PDA

View Full Version : Getting more lines to use in ZScript



Nimono
12-03-2006, 06:41 PM
Sigh.... I can't figure this out. I want to make my own script, but the problem is, whenever I try to get a new line to use, nothing works. Pressing enter simply crashes ZQuest, the numberpad enter does nothing, insert does nothing, and of course no character keys will work. I need serious help here.

ShadowTiger
12-03-2006, 06:44 PM
What about writing your own scripts in notepad, then copying/pasting them into the Compiler? :shrug: Tried that? o.o (... because I haven't. :sweat: Then again, I haven't actually tried to compile a script yet.)

Nimono
12-03-2006, 07:02 PM
O_o; I never thought about that. I guess that'd make it a lot easier. Though, do I HAVE to save it as a .z file?

ShadowTiger
12-03-2006, 07:19 PM
For Zasm, I think, since it probably won't read a .txt file anyway. EDIT: Check Saffith's post below. I haven't actually tried this in terms of ZScript, but I'd assume that you'd just use the method I described anyway if you'll be writing the code. If someone gave you some code that you'd be importing into ZQuest, you'd also have to assume that it'd be in usable form already, as the person knows what they're doing, and knows that it'd be the right format to be used in.

Saffith
12-03-2006, 08:52 PM
Pressing enter simply crashes ZQuest, the numberpad enter does nothing, insert does nothing, and of course no character keys will work.It's a known bug. Until it's fixed you'll have to use an external text editor. Save as a .z file for ZScript, and .txt for ZASM.


O_o; I never thought about that. I guess that'd make it a lot easier. Though, do I HAVE to save it as a .z file?Well, if you want to import it. You could also just copy and paste the script into the internal editor.

DarkDragon
12-04-2006, 08:05 AM
It's a known bug. Until it's fixed you'll have to use an external text editor. Save as a .z file for ZScript, and .txt for ZASM.
Is this new in b15 or has it always crashed for you? Is everyone experiencing this problem?
I could write scripts without problem in b14.

Saffith
12-04-2006, 02:54 PM
It's been doing it for as long as the editor has been there. Apparently it's not a problem for everyone. Koopa and I are both seeing it, but it doesn't seem to affect _L_.

Oh, it gave me this once:

Assertion failed!

Program: D:\ZC 2.11b14\zquest-w.exe
File: EditboxView.cpp
Line: 21

Expression: model

DarkDragon
12-05-2006, 10:12 AM
Oh, I see, that should be an easy fix. Could you paste the method containing that line here please?

Saffith
12-05-2006, 10:40 AM
I can, but there's not too much there.

void EditboxView::update()
{
assert(model);
layoutPage();
}
I would expect it's being called from here:

void EditboxCursor::insertChar(int c)
{
if(host.isReadonly())
return;

Unicode::insertAtIndex(host.getBuffer(),c,index);
CursorPos cp = host.findCursor();
Unicode::insertAtIndex(cp.it->line, c, cp.index);
cp.it->numchars++;
host.markAsDirty(cp.it);
host.getView()->update();
(*this)++;
}
To clarify a bit, this is only a problem on the last line. Any line before the last, everything works fine. Also, it only happens when you're typing; pasting doesn't cause problems.

DarkDragon
12-05-2006, 11:04 AM
Fuck, I wrote this code long enough ago I don't remember it in detail. Where does model get initialized? It gets passed into the EditboxView constructor right?

Saffith
12-05-2006, 11:14 AM
Passed to the initialize method. The constructor just makes it null.

DarkDragon
12-05-2006, 11:20 AM
OK, so as you've probably deduced the next step is determining when, if ever, initialize is called ;)

Saffith
12-05-2006, 11:54 AM
It's called from here:

int d_editbox_proc(int msg, DIALOG *d, int c)
{
EditboxModel *model= (EditboxModel *)d->dp;
int ret = D_O_K;

static clock_t ticks;
bool dontredraw=false;
switch(msg)
{
case MSG_START:
{
model->getSelection().clearSelection();
model->getView()->initialize(model);
break;
}
// More cases...
}
if(ret == D_USED_CHAR && !dontredraw)
{
//redraw
if(!model->getCursor().isVisible())
model->getCursor().invertVisibility();
ticks=clock()+(CLOCKS_PER_SEC/2);
model->getView()->ensureCursorOnScreen();
d->flags |= D_DIRTY;
}
return ret;
}
It's definitely being called somewhere, but it starts getting messy at that point.

DarkDragon
12-06-2006, 12:09 PM
Hrm, thanks. I'm 95% sure that the problem is that a MSG_START is not being passed to the dialog when the dialog is first opened, but I'm not familiar enough with the Allegro jwin system to know why. Feel free to keep investigating this bug; worst-case I'll look into it and fix it when I get back :/

Saffith
12-06-2006, 05:25 PM
I've almost got it... I believe I found where the problem is, but I'm not quite sure of the best way to fix it.
You know the code better than I do. What do you think?


void EditboxCursor::insertNewline()
{
if(host.isReadonly())
return;
int c = Unicode::getCharAtOffset(uconvert_ascii("\n",NULL),0);
Unicode::insertAtIndex(host.getBuffer(),c,index);
CursorPos cp = host.findCursor();
//split off the next line
int offset = Unicode::indexToOffset(cp.it->line, cp.index);
string newline = cp.it->line.substr(offset, cp.it->line.size()-offset);
LineData newld = {newline, cp.it->numchars-cp.index, cp.it->newlineterminated,true,NULL};
cp.it->line = cp.it->line.substr(0,offset);
Unicode::insertAtIndex(cp.it->line, c, cp.index);
cp.it->numchars = cp.index+1;
cp.it->newlineterminated = true;
cp.it->dirtyflag = true;
list<LineData>::iterator next = cp.it;
next++;
host.getLines().insert(next,newld);
host.markAsDirty(next); // <---------This call
host.markAsDirty(cp.it);
host.getView()->update();
(*this)++;
}

void EditboxModel::markAsDirty(list<LineData>::iterator line)
{
//coalesce lines that are NOT newline-terminated
list<LineData>::reverse_iterator rit = list<LineData>::reverse_iterator(line);
//find start of line
while(rit != lines.rend() && !rit->newlineterminated)
{
rit++;
}
line = rit.base();

// This loop in particular seems to be what causes it to crash.
while(!line->newlineterminated)
{
list<LineData>::iterator next = line;
next++;
assert(next != lines.end());
line->numchars += next->numchars; // This line, of all places, is where the model pointer gets screwed up
destroy_bitmap(next->strip);
line->line += next->line;
line->newlineterminated = next->newlineterminated;
lines.erase(next);
}
line->dirtyflag=true;
}When markAsDirty() is called, next is pointing just past the text, apparently to the same area where the EditboxView is stored. It can be kept from getting messed with by preventing that call with if(next!=host.getLines().end()) or simply removing that while loop (this one case is the only time it ever executes, anyway). Neither of those causes problems, as far as I've seen, but they would seem to be just quick fixes.

DarkDragon
12-07-2006, 07:35 AM
No, that loop is necessary. Not for the ZScript editor (since the code doesn't wrap) but for the other wrapping text boxes such as the help.
What that while loop does is re-layout a paragraph containing multiple lines when an earlier line in the paragraph has been modified.

Here is what SHOULD happen during these calls:
1. An empty buffer contains only a single newline character. Thus the first (and only) line is newline-terminated.
2. Enter is pressed.
3. A new line structure is created, as per the code you pasted. This new line is newline-terminated (since the old one was), and is appended after the old line.
4. The newly appended line is marked as dirty:
4a. A reverse-iterator is created pointing to the new line. Since this new line is newline-terminated, the first while loop is skipped.
4b. The reverse-iterator is converted back into a normal iterator, still pointing to the new line.
4c. Since the new line is newline-terminated, the second while loop is skipped.

So something went wrong in this sequence of events. The code you pasted looks OK at a glance, so I'd guess there might be a problem as early as steps 1 or 3.

Saffith
12-07-2006, 10:13 PM
I think it's a problem with the iterators. I haven't worked out why, exactly, but that's what it seems to be. For some reason, next is pointing past where it should be.

If I have this text:

123456
abcdef... then if I insert a line between 123 and 456, cp.it points to 123\n, and next (after it's incremented) points to abcdef\n.

I tried putting next--; after newld is inserted, and everything seems to work fine...

I don't see why that fixes it. It gets initialized to the same position as cp->it, as it should, then the increment goes a line too far, the line's inserted in the right place, and the decrement puts it back where it should be. If you see why it's doing that, I'd sure like to know.

DarkDragon
12-08-2006, 08:56 AM
Oh fuck! Yes, yes you're right. After the call to list<>::insert, next STILL points to the element that used to be after cp.it, NOT to the newly inserted line. And of course that's trouble when cp.it was the last line of the buffer, and next is lines.end.
So your fix is absolutely correct. Keep it and commit :)

Saffith
12-08-2006, 09:11 AM
Gah, of course. I almost feel stupid for missing it...


Keep it and commit :)Done. Except it had some bizarre error and didn't prompt me for a message. So now the newest revision has no comment, and I can't edit it.
Well, in case anyone's wondering what exactly was changed, this was it...

Geez, I'm just having a great couple of days here. :p Eh, well, it's fixed. I suppose that's the important thing.
That emoticon looks too happy, though. I'm trying to whine here.

DarkDragon
12-08-2006, 09:17 AM
The repository gave you an error? But you're sure the commit went through?

Saffith
12-08-2006, 09:19 AM
It wasn't the repository, it was the software. At least, it seems to have been. In any case, yeah, it went through just fine.