Page 1 of 1

Finally found one

Posted: Tue Oct 02, 2012 3:21 am
by dunbarx
Finally found reproducible scripts that work as advertised when stepping through in the deBugger, but do not when simply run. This gremlin has been sighted, like the Yeti, by nominally sane people, but never caught.

Make two buttons. Name one "start". Name the other "stop".

in btn "start":

Code: Select all

on mouseUp
   put the seconds + 8 into tSecs
   showrandoms tSecs
end mouseUp
In btn "stop":

Code: Select all

on mouseup
   send "showRandoms" && 0 to this card
end mouseup
In the card script:

Code: Select all

on showRandoms tSecs
   put random(99)
   if tSecs = 0 then 
      exit to top
   end if
   if tSecs > the seconds then send "showRandoms" && tSecs to me in 0 millisecs
end showRandoms
Try it. If you press the "start" button, you get random numbers in msg for eight seconds. If you press the "stop" button while this is going on, nothing happens.

If you place a breakpoint at the "exit to top" line in the card script. the handler is caught there, and if you then step through, you exit. The "stop" button was intended to reset the variable "tSecs" to a value that will force the showRandoms to end. And it does, but only if you step through, not if you run it. The variable watcher shows a "0" as the value of tSecs, as it should, and the conditional tosses you out of the handler. As it should.

But not in a normal run, only in the debugger.

I have been chasing this since 1987. I am not crazy. I have pictures. I will start a support group.

Craig Newman

Re: Finally found one

Posted: Tue Oct 02, 2012 12:19 pm
by bn
Hi Craig,

confirmed here. Neither adding wait with messages nor any other trick changed the behavior you described.

I put in a field to show the parameter tSecs and 0 is passed alright but does not trigger exit. In the next round it is replaced by the seconds again.
I had increased the messaging to 1000 milliseconds in showRandoms to better see what is going on.
if tSecs > the seconds then send "showRandoms" && tSecs to me in 1000 millisecs

Nice find.

Kind regards
Bernd

Re: Finally found one

Posted: Tue Oct 02, 2012 6:35 pm
by dunbarx
Bernd.

I also posted this to the use group. The "wait with messages" does work, as it should, though if you only specify 0 milliseconds, it will fail now and then. I am more interested in understanding why "send in time" also does not return control to the user for an external event, like clicking the mouse.

-------------------------

Mark.

I thought of that, but believed that the "send in time", where I even increased the time value to, say, 100 ticks, would be more than enough to allow the engine to "rest".

So I am misunderstanding the two paths. I see clearly what "wait with messages" does. But I am trying to avoid "wait" in general. This from an old HC user.

But I thought that "send in time" also placed control back in the hands of the engine (the message pending) for the specified interval. What else is going on during that time? There is no loop. The handler ends, the message is queued, and I would have thought that I can invoke a new instance of that handler from another source, like clicking a button.

This was derived from a post I made on the forum. I tried something like this, and failed, eventually setting a custom property and checking its value to allow the poster to do just what I mentioned.

Thanks,

Craig


-----Original Message-----
...
Subject: Re: Finally found one.

Craig-

Monday, October 1, 2012, 7:25:49 PM, you wrote:

[bunch of stuff deleted]

> Try it. If you press the "start" button, you get random numbers
> in msg for eight seconds. If you press the "stop" not while this is
> going on, nothing happens.

You need to give the engine some room to breathe. Insert the line

wait 0 milliseconds with messages

at the start of your showRandoms function. The "with messages" part
will allow the engine a chance to look around and see if any events
have occurred (as for instance someone pressing the Stop button).
Otherwise you've coded up a loop that's so tight the engine will never
see the mouseUp (or any other) message.

When you're running this in the debugger there are a lot of engine
events happening - your actual code is only a small fraction of that,
and the engine is paying attention to everything in the environment.
That's why your mouseclicks get registered.

--
-Mark Wieder

Re: Finally found one

Posted: Tue Oct 02, 2012 11:15 pm
by sturgis
Seems to me this is a logic error.
The start button starts a loop. THe loop is passing the value tsecs to itself every time.

The button stop starts another loop with tsecs 0 so THAT loop does nothing.

The first loop should continue until complete. The only way this would work (if I understand correctly) is if tsec was external and not passed. In this case my guess is since tsec is a parameter its scope is local to the execution context. So, since the first (start) loop itself is passing tsec to itself, what stop does should have zero affect on the other messages being looped. (Think this was said in the email thread somewhere) So there is a message sitting there with a value already set, and then clicking the stop button queues another message with a different value.

Think to get around this you could use @tsec instead? Or don't take a parameter just set the value of a variable, then if you override the value, next loop through it stops. (Yes I know you know all this but i'm thinking it through in text so that _I_ know all this)
dunbarx wrote:Finally found reproducible scripts that work as advertised when stepping through in the deBugger, but do not when simply run. This gremlin has been sighted, like the Yeti, by nominally sane people, but never caught.

Make two buttons. Name one "start". Name the other "stop".

in btn "start":

Code: Select all

on mouseUp
   put the seconds + 8 into tSecs
   showrandoms tSecs
end mouseUp
In btn "stop":

Code: Select all

on mouseup
   send "showRandoms" && 0 to this card
end mouseup
In the card script:

Code: Select all

on showRandoms tSecs
   put random(99)
   if tSecs = 0 then 
      exit to top
   end if
   if tSecs > the seconds then send "showRandoms" && tSecs to me in 0 millisecs
end showRandoms
Try it. If you press the "start" button, you get random numbers in msg for eight seconds. If you press the "stop" button while this is going on, nothing happens.

If you place a breakpoint at the "exit to top" line in the card script. the handler is caught there, and if you then step through, you exit. The "stop" button was intended to reset the variable "tSecs" to a value that will force the showRandoms to end. And it does, but only if you step through, not if you run it. The variable watcher shows a "0" as the value of tSecs, as it should, and the conditional tosses you out of the handler. As it should.

But not in a normal run, only in the debugger.

I have been chasing this since 1987. I am not crazy. I have pictures. I will start a support group.

Craig Newman

Re: Finally found one

Posted: Tue Oct 02, 2012 11:43 pm
by bn
OK,

I think what is going on after reading John Craig's solution on the use-List:

Craig Dunbark's code works alright except that there is still one/multiple showRandoms messages with the seconds in tSecs in the pendingMessages. The message from the stop button is sent alright and the conditional is executed but exit to top does not seem to cancel pendingMessages.

Which begs the question what "exit to top" does.

from the dictionary:
Use the exit to top control structure to stop executing the current handler and suppress pending messages.
I use this code in the card script after adding two fields to the card:

Code: Select all

on showRandoms tSecs
   put random(99) into field 1
   put tSecs into field 2
   if tSecs = 0 then 
      put return & "inside conditional " & the milliseconds after field 2
      exit to top 
   end if
   if tSecs > the seconds then send "showRandoms"  && tSecs to me in 1000 millisecs
end showRandoms
by setting the send in time interval to 1000 milliseconds there is enough time to watch what is going on.

For me this is still not clear. Why does exit to top does not terminate the handler.

Kind regards

Bernd

Re: Finally found one

Posted: Wed Oct 03, 2012 2:05 am
by dunbarx
To simplify, two buttons. In the first:

on mouseUp
showRandoms 3
end mouseUp

In the second:

on mouseUp
showRandoms 0
end mouseUp

in the card script:

on showRandoms var
put random(99)
if var = 0 then
repeat for each line tLine in the pendingMessages
cancel item 1 of tLine
end repeat
exit to top
end if
send "showRandoms" && 3 to this card in 60
end showRandoms

The exit works if the code runs as shown. It fails if the repeat construct is commented out. Does the existence of a pending message block a new call to that very same handler from another source? That is what I am trying to understand.

You can do anything you want while the card script is running. You can fool around with the msg box, write to a field, change a script in another object handler, take a nap. The running handler truly returns control to the user. So why cannot I send a message with a parameter that would direct a conditional to terminate that handler? As Bernd noted, the "0" parameter is sent and trapped when the second button does its thing. It just is not paid any attention. The waiting pending message trumps it.

Craig

Re: Finally found one

Posted: Wed Oct 03, 2012 2:32 am
by mwieder
As to why it works in the debugger, if you examine the debugger code you'll see "with messages" calls sprinkled throughout. The debugger needs to be catching messages from all over, and so your stop button will register its interruption.

I remain skeptical that "exit to top" really cancels pending messages.