intfiction.org

The Interactive Fiction Community Forum
It is currently Sun Nov 18, 2018 2:34 pm

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Tue Dec 19, 2017 9:22 pm 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
So I've got a bit of an odd one I'm having trouble chasing down.

I've got a Glulx Inform game (Inform v6.33 Library v6.12.1 S) that has a mainwin, mapwin and compasswin as well as a sound channel.

Everything seems to work fine except after I replay a command script, even one of only one command. After doing that, if I issue an "undo" command, Git and Glulxe report:
Reference to non-existent Glk object

Lectrote is, as expected more helpful, showing:
Quixe run: glk_get_line_stream: invalid stream

If I take the same command, I can type it in, hit <ENTER> and then type 'undo' and nothing untoward happens.

Now, I've protected, in my code, all references to my windows to make certain the pointers are non-zero before I access them, but I can't chase this down.

Has anyone ever see anything like or care to take a guess as to the cause?

I've got a minimal example (attached) that demonstrates this. Sorry the extension is .txt, but it's really an INF file. Getting around some forum foolishness that blocks INF files.

If it is compiled with -~D in any way, then it crashes when you type undo after inputting a replay file.

If you compile with -D and -S on, undo works fine, but of course I can't release this way as things like "purloin" are still available.

So again, compile this way:
inform6.exe -G -~D -~S +include_path=./,E:/devl/inform/lib,E:/devl/inform/lib/contrib testgame.inf

then "undo" after a replay input is broken.


But compile this way:
inform6.exe -G -D -S +include_path=./,E:/devl/inform/lib,E:/devl/inform/lib/contrib testgame.inf

then "undo" works after replay input.


Attachments:
testgame.txt [1.25 KiB]
Downloaded 45 times
Top
 Profile Send private message  
Reply with quote  
PostPosted: Wed Dec 20, 2017 11:07 am 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 5802
I haven't looked through your code, but you have to take extra care if you undo/restore/restart a move that opened or closed a window. Or even closed and reopened a window. The undo state does not include window identities, so you can be left holding an invalid reference.

(Window references are not memory pointers, although they share the convention that 0 means "none".)

There's a library function which iterates through the currently-open windows and makes sure every global variable refers a valid reference. See http://eblong.com/zarf/glulx/inform-guide.txt on the IdentifyGlkObject() function.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Wed Dec 20, 2017 1:59 pm 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
Thanks, zarf.

I did look through all that because before I created the minimal game showing the problem, I did have lots of windows (well, 3) as well as a sound channel.

I had looked over the guide and Adam's gull/glk pages and my IdentifyGlkObject until my eyes gave out, assuming it was something I was doing.

For the minimal game up above, there's almost nothing left in the code where it could be occurring... no windows are created explicitly by the code, it's some objects and an Initialise routine. I believe, from reading the guide that I'm okay without an IdentifyGlkObject in that case, but this game is still doing it.

It's also possible that it's an issue with the compiler I'm using, as I understand it's not in wide use anymore, versus the Inform7 i6 compiler.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Wed Dec 20, 2017 2:33 pm 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
Okay, in parserm.h in GGRecoverObjects, there's the following:

#Ifdef DEBUG;
gg_commandstr = 0;
gg_command_reading = false;
#Endif; ! DEBUG

So we only wipe gg_commandstr and clear gg_command_reading when it's a debug build (which, unsurprisingly, is when it works properly for me, not crashing). If it's a release build, gg_commandstr is not cleared.

If I remove the ifdef, then I can do a release build, replay my single-command recording and then issue 'undo' properly.

Removing these ifdefs does of course break command recording through a "restart".

I don't propose it as a solution, just trying to understand the issue at the moment. I'll dig a bit into what happens when a replay ends.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Wed Dec 20, 2017 2:36 pm 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
Meant to add...

At a guess, when we type 'undo', all the variables of the previous state are restored, including the values of gg_commandstr and gg_command_reading... so gg_commandstr because a non-zero pointer, but the file it points to is no longer open.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Wed Dec 20, 2017 3:23 pm 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
I think I have a workaround. If I have a react_before that watches for CommandOn and CommandOff, I can have my own global that tracks if command recording is on.

When the library turns off undo, GGRecoverObjects is called, which in turn calls IdentifyGlkObject at phase 0.

So in my IdentifyGlkObject, I can wipe gg_commandstr and set gg_command_command to false (which allows 'undo' to work after a command replay), but only do that if we're not currently recording commands.

End result is I fix 'undo' after a command replay without breaking command recording. And the fix is in-game rather than fiddling with the library in case I'm breaking something else.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Fri Dec 22, 2017 4:02 pm 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 5802
I don't have time to test a complete solution here. However, catching up on the thread:

I don't know why the gg_commandstr lines in GGRecoverObjects() are conditionalized with "#ifdef DEBUG". There's no good reason for that, except maybe the expectation that the RECORD command will only be used on debug builds, which is not a good assumption. You can just remove the "#ifdef" lines there.

(There are two pairs of "#ifdef" lines, one inside the switch statement.)

Quote:
Removing these ifdefs does of course break command recording through a "restart".


It shouldn't. The convention is that open streams, such as the transcript stream (gg_scriptstr), can remain open through a restart.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Sat Dec 23, 2017 9:59 am 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
Okay, cool. I'll try commenting those out again and report back. Thanks for the input once again.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Sat Dec 23, 2017 10:45 am 
Offline

Joined: Mon Dec 11, 2017 8:21 pm
Posts: 25
Okay, commenting out both sets of #Ifdef lines works fine. I had only done the one set before. Thanks!


Top
 Profile Send private message  
Reply with quote  
PostPosted: Wed Sep 12, 2018 3:16 am 
Offline
User avatar

Joined: Mon Dec 12, 2011 7:03 pm
Posts: 557
Location: Washington
I don't know how I missed this thread, but I just now fixed the problem and pushed the result to the Gitlab repo. See https://gitlab.com/DavidGriffith/inform6lib/issues/55

_________________
David Griffith


Top
 Profile Send private message  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 17 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group