Page 1 of 1
Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 6:26 pm
by grimaldiface
Hi all,
I've got a major problem that started happening after upgrading from 4.0 to 5.5, and I desperately need help.
I make a lot of "quizzing" type programs that basically present a user a question, they type an answer, click a button submit it and move on. The code I have used to do this for the longest time is like this:
Code: Select all
--present question
put "How old are you?" into fld "question" of card "question"
select the text of fld "response" of card "question"
--wait for response
put false into gButtonClicked
wait until gButtonClicked is true with messages
--record answer
put fld "response" of card "question" into tResponse
The user clicks a button that sets "gButtonClicked" to true when they are done answering the question, thus exiting the wait command and moving the script on. This is the basic way I've done this for years. However, since upgrading to 5.5 it no longer works. While the wait command is "waiting", anything the user types into the field is not visible. If they click off of the field, the text will then appear. In some of my programs that use the wait command in conjunction with a text entry field, the application will suddenly and completely disable all messages coming from the user.This is obviously problematic, considering the wait command will wait until the user can set "gButtonClicked" to true. This is completely bizarre--I have run 15 people through the exact program at it will freeze up for 5 people and work fine for everyone else. None have reported doing anything strange, they just started typing and then all of the sudden keypresses and mouse clicks do nothing.
Interestingly, the problem sort of goes away if I nest the wait command into a repeat loop, like this:
Code: Select all
repeat until gButtonClicked is true
wait 5 milliseconds with messages
end repeat
However, I still get intermittent problems with this method.
The most frustrating part is that these problems almost exclusively occur when the program is run as a standalone, and the program typically works fine when run in LiveCode Studio. Debugging is so much fun when the problem is intermittent and you have to generate a standalone each time you want to see if something made a difference!
Anyways, I'm majorly pissed about all of this. I was really excited about updating, and this has completely screwed me up. I use the wait command in conjunction with text entry fields so much, they are critical to everything I do. It seems to me that it has something to do with how LiveCode compiles the standalones now. I can save the same exact stack file as a standalone using 4.0 and it works fine, but is completely screwy when generated from 5.5.
Does anyone have any insight into this problem? Has anyone else experienced it? Any good timing alternatives? If it matters I'm running OS X 10.8, and using 5.5.1. Colleagues running 10.7 and using 5.5.2 have reported the same problems to me.
Re: Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 7:23 pm
by dunbarx
I have no answers, except that I have stayed with 5.5, experiencing oddities with anything more recent.
But it is always the best practice to use neither the "wait" command, nor your slightly more robust "repeat/wait with messages".
The right way is always send a message in time. I am an old HC guy, and still have to try to remember to do it this way. But it fixes many ills. You probably have done this sort of thing. With two buttons, and this in the script of the first:
Code: Select all
on mouseUp
setUpEventThingie
end mouseUp
on setUpEventThingie
if the mouseLoc is within the rect of btn 2 then
answer random(99)
exit setUpEventThingie
end if
send "setUpEventThingie" to me in 1 millisec
end setUpEventThingie
Try rewriting your code this way. I bet it works. I never have an issue with solving a problem even though I never fixed it, nor understood it.
Craig Newman
Re: Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 8:01 pm
by jmburnod
Hi Craig,
I think it is necessary to add a "stopPending" before the exit:
Code: Select all
on setUpEventThingie
if the mouseLoc is within the rect of btn 2 then
answer random(99)
stopPending setUpEventThingie
exit setUpEventThingie
end if
send "setUpEventThingie" to me in 1 millisec
end setUpEventThingie
on stopPending pPending
repeat for each line aLine in the pendingmessages
if aLine contains pPending then
cancel item 1 of aLine
end if
end repeat
end stopPending
Jean-Marc
Re: Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 8:39 pm
by grimaldiface
dunbarx wrote:
But it is always the best practice to use neither the "wait" command, nor your slightly more robust "repeat/wait with messages".
The right way is always send a message in time. I am an old HC guy, and still have to try to remember to do it this way. But it fixes many ills. You probably have done this sort of thing. With two buttons, and this in the script of the first:
Thanks for your reply! So you've had strange problems with 5.5.1, but not 5.5.0?
I used to do timing the way you mentioned, until I found using the "wait" command to be easier to manage and more parsimonious. How is using the wait command not good practice? Is that not that what it is for? It seems the "send in time" method forces me to split up an otherwise straightforward handler....not saying it wouldn't work but it's a pain compared to using "wait". I'll give it a shot, but I'm still open to other suggestions.
Re: Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 9:28 pm
by grimaldiface
Alright I tried Craig's suggested method:
Code: Select all
global gButtonClicked
On QuestionProcedure
put "How old are you?" into fld "question" of card "question"
select the text of fld "response" of card "question"
put false into gButtonClicked
eventTimer
put fld "response" of card "question" into tResponse
answer "You are" && tResponse && "years old."
end QuestionProcedure
on eventTimer
if gButtonClicked is true then
exit eventTimer
end if
send "eventTimer" to me in 1 millisecond
end eventTimer
So this didn't work. The problem here is that "eventTimer" is called within the running QuestionProcedure handler, so when the script gets to "send eventtimer to me in 1 millisecond", it continues on to the next line in the QuestionProcedure handler. I need eventTimer to sort of stall the QuestionProcedure handler, but it just sort of keeps going.
Re: Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 10:43 pm
by dunbarx
Jean-Marc.
I see no backlog of pending messages when I run a handler of this sort. Are you thinking they will build up and languish in the ether?
Craig
Re: Problem with "wait" command in standalone only.
Posted: Thu Sep 20, 2012 11:59 pm
by dunbarx
Grimaldiface.
The devil is in the structure. I made two buttons. I assume you have the fields. Try this in the script of button 1:
Code: Select all
global gButtonClicked
on mouseup
put "How old are you?" into fld "question"
select the text of fld "response"
put false into gButtonClicked
eventTimer
end mouseup
on eventTimer
if gButtonClicked is true then
put fld "response" into tResponse
answer "You are" && tResponse && "years old."
exit eventTimer
end if
send "eventTimer" to me in 1 millisecond
end eventTimer
And in the other button:
Code: Select all
global gButtonClicked
on mouseUp
put "true" into gButtonClicked
end mouseUp
Write back. It is always a bit of juggling when these interleaved processes are started.
Craig Newman
Re: Problem with "wait" command in standalone only.
Posted: Fri Sep 21, 2012 7:18 am
by jmburnod
Craig,
Are you thinking they will build up and languish in the ether?
Yes. That is a pending message and i don't like having a loop for nothing
Jean-Marc
Re: Problem with "wait" command in standalone only.
Posted: Fri Sep 21, 2012 3:36 pm
by FourthWorld
Timers are tricky things. In almost all other respects LiveCode is free of race conditions, but timers open up the possibility for introducing them, and it can indeed be difficult to track down issues related to them.
I've briefly reviewed the Release Notes for the current build to look for any changes in the engine which might account for this, but came up empty. Given the many releases between v4.0 and 5.5 it's hard to say what could account for the behavioral change.
But as I look at the code, I find myself wondering if a timer is needed here.
It seems that the buttons already have a handler which allows them to set the gButtonClicked global. If instead the original handler was merely broken into two handlers, and the button scripts modified to call the handler that performs the post-click action, you'd have a reliable with-the-grain solution:
Code: Select all
-- Card or stack script:
on AskQuestion
--present question
put "How old are you?" into fld "question" of card "question"
select the text of fld "response" of card "question"
end AskQuestion
on HandleAnswer
--record answer
put fld "response" of card "question" into tResponse
DoWhateverNeedsToBeDoneWith tResponse
end HandleAnswer
-- Button script:
on mouseUp
HandleAnswer
end mouseUp
Is there some benefit to using a timer here that I've overlooked?
Re: Problem with "wait" command in standalone only.
Posted: Fri Sep 21, 2012 3:41 pm
by grimaldiface
Craig,
I see why your structure works and mine doesn't. The problem I face however is that all of my existing stacks are structured in a completely different manner. The code I've posted above is a boiled down, oversimplification of just the wait problem(obviously). I am almost always presenting more than one question to the user, having them study things, present more questions, etc. The structure I use is something like this:
Code: Select all
on godHandler
repeat 2 times
studyproc
questionproc
end repeat
end godHandler
on questionproc
repeat with x = 1 to the number of lines in gQuestionList
put false into gButtonClicked
put empty into field "response"
put line x of gQuestionList into field "question"
wait until gButtonClicked is true with messages
put field "response" and return after gData
end repeat
end questionproc
(The above is pretty much pseudocode for explanatory purposes). In my structure, everything is controlled by handlers in the stack script. Rather than the user calling handlers, the script does everything and simply waits for user to make a response. As far as I can tell, your "eventTimer" handler can't be used while another handler or repeat loop is running.
Re: Problem with "wait" command in standalone only.
Posted: Fri Sep 21, 2012 3:47 pm
by grimaldiface
FourthWorld wrote:
Is there some benefit to using a timer here that I've overlooked?
FourthWorld,
You posted right before I typed the above reply. That reply should answer part of your question. The other part is that the timing varies across my programs (which are psychology experiments, fyi). Sometimes I wait for the user to make a response. Sometimes I wait a certain amount of time. Sometimes I wait for a response or a certain amount of time. Using "wait until some condition is met" allows me to easily change the requirements at will.
Re: Problem with "wait" command in standalone only.
Posted: Fri Sep 21, 2012 3:50 pm
by grimaldiface
I was just contacted by runrev, and this is indeed a bug. I was told it will be fixed in the next release.
Craig, you mentioned that using "wait" should be avoided for timing. What is your reasoning? I don't see anything in the docs that suggest this.
Re: Problem with "wait" command in standalone only.
Posted: Fri Sep 21, 2012 8:28 pm
by dunbarx
It is just that "wait" is blocking. Sometimes this does not matter. "Wait with messages" is more robust, and this is what you used.
In general, the "send in time" is cleaner, a separate timing construct managed by the engine taking the place of any preset loop or wait. Control is returned to the user completely, and it is as if a gremlin inside the machine repeatedly shoots the "send" command behind the scenes, apart from anything the user does.
Craig Newman