Repeat a handler until time limit expires

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
PoLyGLoT
Posts: 105
Joined: Sat Jan 14, 2012 12:37 am

Repeat a handler until time limit expires

Post by PoLyGLoT » Mon Oct 01, 2012 7:21 am

Hi all,

What is the best way to repeatedly summon a specific handler until a given length of time expires? I'm creating a program wherein I want a specific card to remain open for *up to* 8 seconds OR until they click a button to proceed. In other words, the card opens and remains fully open for up to 8 seconds, but if participants want to selectively advance they can press a button.

One of the major problems I'm having is that I need the handler to repeatedly check the elapsed time. If the time has not expired, then I need the exact same handler to run again. In this manner, the handler will once again check the time. If the time has still not expired, then I need the exact same handler to run again, etc. until the time has elapsed. If, during the course of the handler repeatedly running, I need the button which is clicked to tell the handler to STOP running.

The major issue is that repeatedly running a handler gives me a recursion limit reached error.

Here is some code to facilitate discussion:

Code: Select all

on keeptrack6
   global matlist1,testtemp,howlong,whichitem,timeoutRT,session,recall,numtrials,tempanswer,data,stopkeeptrack6,matlist2,matlist3,matlist4,matlist5,matlist6,subID,testtemp,matlist,dropstatus,matlists,stopkeeptrack7,firstkey,writetime,lagcond,checktime
   if stopkeeptrack6 is false then  --K
      put (the ticks - timeoutRT) into checktime
      if session = 1 then --a
         put 480 into howlong
      else
         put 3600 into howlong
      end if  --a
      if checktime > howlong then -- 8 seconds --A
         if firstkey is true then  --b
            put ((the ticks - writetime)/60) & "," after data
            put "no" & "," after data 
         end if  --b
         put cd fld "recall"  & "," after data
         put cd fld "recall"  into tempanswer
         put empty into cd fld "recall" 
         show cd fld "hide recall" 
         hide cd fld "hide definition" 
         hide cd fld "recall instructions"  
         hide cd fld "study instructions" 
         put item 2 of line 1 of testtemp into whichitem # item num
         if (char 1 to 4 of item 1 of line 1 of tempanswer) = (char 1 to 4 of item 4 of line 1 of testtemp) then --Y  ---> Answer Correct
            add 1 to line whichitem of cd fld "dropstatus" of cd "main task materials"
            if line whichitem of cd fld "dropstatus" of cd "main task materials" < item 5 of line 1 of testtemp then  --X  --> Answer correct, not reached criterion yet
               put return & line 1 of testtemp after matlist1
               opencard
            else  --X   --> Answer correct and reached criterion
               go to cd "confidence"
            end if --X
         else  --if answer is incorrect Y
            put return & line 1 of testtemp after matlist1
            show cd fld "hide recall" 
            hide cd fld "hide definition" 
            hide cd fld "recall instructions" 
            hide cd fld "study instructions" 
            hide button "done with recall" 
            hide cd fld "recall instructions2" 
            wait 30 ticks
            opencard
         end if  --Y
      else #time limit not reached on test trial  --A
         keeptrack6
      end if  --A
   end if  --K
end keeptrack6
I very much hope you can help me!

Thanks in advance.

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: Repeat a handler until time limit expires

Post by Mark » Mon Oct 01, 2012 10:02 am

Hi,

Here's a simple example:

Code: Select all

constant kMilliSecs = 20000 // 20 seconds
constant kDelay = 200 // millisecs
local lAbsTimeLimit

on doUntilTimeLimit
  if lAbsTimeLimit is empty then put the millisecs + kMilliSecs into lAbsTimeLimit
  if the millisecs > lAbsTimeLimit then
    beep
    answer "Finished!"
  else
    put (lAbsTimeLimit - the millisecs)/1000 && "seconds to go" // into msg box
    send "doUntilTimeLimit" to me in kDelay millisecs
  end if
end doUntilTimeLimit
You can change the constants to keep the script running for a longer time or to abort it earlier and to run it less or more frequently during the given time.

Kind regards,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

PoLyGLoT
Posts: 105
Joined: Sat Jan 14, 2012 12:37 am

Re: Repeat a handler until time limit expires

Post by PoLyGLoT » Mon Oct 01, 2012 7:33 pm

Thanks for the advice. I have an additional question: Let's say I'm on handler A. The last bit of code executes handler B. Handler B will keep repeating itself until 8 seconds has elapsed. However, handler C can be activated via a mouse click. I want to make it so that handler C *automatically terminates* the running of handler B.

Functionally, handler C = handler B. They both do similar things. The kicker is that I only need the script in both handlers to execute 1 time (either handler B or handler C; but not both).

Is there a command which will automatically stop handler B once handler C is activated?

Thanks,

PoLy

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10356
Joined: Wed May 06, 2009 2:28 pm

Re: Repeat a handler until time limit expires

Post by dunbarx » Tue Oct 02, 2012 2:47 am

Hi.

I made a button named "doStuff", and another named "terminate". I put this in the "dostuff" script:

Code: Select all

on mouseUp
--doYourStuff
   put the seconds + 8 into tSecs
   set the doRun of this card to "run"
   callHandlerB tSecs
end mouseUp
This in the "terminate" script:

Code: Select all

on mouseUp
  set the doRun of this card to ""
end mouseUp
in the card acript:

Code: Select all

on callHandlerB tSecs
   put random(99)
   if the doRun of me <> "run" then  exit to top
   if tSecs > the seconds then send "callHandlerB" && tSecs to me in 0 millisecs
end callHandlerB
Interestingly, I tried to do this purely by passing parameters instead of setting a custom property. I am having trouble with that. The code works fine if I step through it,but will not work if I just run it. Watch this space.

Craig Newman

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: Repeat a handler until time limit expires

Post by Mark » Tue Oct 02, 2012 2:26 pm

Hi Poly,

Here's an example, which does what you ask. Create a new button and enter the script below.

Code: Select all

constant kDelay = 200
local lStartStopFlag

on mouseUp
     handlerA
end mouseUp

on handlerA
     if the optionKey is down then
          // full stop
          put the pendingMessages into myMessages
          if "handlerB" is in myMessages  or "handlerC" is in myMessages then
               repeat for each line myMsg in myMessages
                    if myMsg contains "handlerB" or myMsg contains "handlerC" then cancel item 1 of myMsg
               end repeat
               put empty into lStartStopFlag
               put empty
          end if
     else
          if lStartStopFlag is not false then
               put false into lStartStopFlag
               handlerB
          else
               put true into lStartStopFlag
               handlerC
          end if
     end if
end handlerA

on handlerB
     // stop handlerC after the user clicks on this button
     put the pendingMessages into myMessages
     if "handlerC" is in myMessages then
          repeat for each line myMsg in myMessages
               if myMsg contains "handlerC" then cancel item 1 of myMsg
          end repeat
     end if
     if lStartStopFlag is false then
          // do something here, e.g. put the seconds
          put the seconds & cr & lStartStopFlag & cr & "HandlerB"
          send "handlerB" to me in kDelay millisecs
     end if
end handlerB

on handlerC
     // stop handlerB
     // stop handlerB after the user clicks on this button
     put the pendingMessages into myMessages
     if "handlerB" is in myMessages then
          repeat for each line myMsg in myMessages
               if myMsg contains "handlerB" then cancel item 1 of myMsg
          end repeat
     end if
     if lStartStopFlag is true then
          // do something here, e.g. put the seconds
          put the seconds & cr & lStartStopFlag & cr & "HandlerC"
          send "handlerC" to me in kDelay millisecs
     end if
end handlerC
Kind regards,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

Post Reply