Extended Timeout

Some time ago, while work­ing on a game, I had to use a mul­ti­tude of #time­out objects (over 250) with dif­fer­ent dura­tions. In the course of the work it was get­ting more and more dif­fi­cult for me to man­age them. Unfor­tu­nate­ly, I ful­ly real­ized that I was going in the wrong direc­tion just when I had to imple­ment the pause game/resume game func­tion­al­i­ty. At that moment I thought that it would have been bet­ter if the #time­out object had have meth­ods as pause(), resume() and restart(). The script below adds this func­tion­al­i­ty. Its usage is a lit­tle bit dif­fer­ent from the stan­dard. Instead of

myTime­out = timeout().new( “myTime­out”, 1000, #yourHan­dler­Name, me )

We use:

myTime­out = script( “Time­out” ).new( 1000, ‑1 )
myTimeout.addEventListener( #TIMER, #yourHan­dler­Name, me )
myTimeout.start()

It def­i­nite­ly requires more lines of code, but in return we can do things as:

myTimeout.pause()
trace( myTimeout.percentDone())
myTimeout.resume()

Time­out script inher­its from Event­Dis­patch­er ( see Event­Dis­patch­er ), so we can add or remove lis­ten­ers at any time:

myTimeout.addEventListener( #TIMER, #dis­play­Time­Code, _movie )
myTimeout.addEventListener( #TIMER_COMPLETE, #dis­playEndTi­tles, _movie )

When the work is done, we call dis­pose(), to remove the ref­er­ences to the lis­ten­ers hold by myTimeout:

myTimeout.dispose()
myTime­out = VOID

Here fol­lows Time­out script, as well as a small demonstration:

Show code

————————————————-
— “Time­out” par­ent script
————————————————-
prop­er­ty ancestor
prop­er­ty _timeout — #time­out; The time­out object, which this script real­ly uses.
prop­er­ty _name — #string; The time­out name.
prop­er­ty _period — #inte­ger; The time­out period.
prop­er­ty _remMs — #inte­ger; Remain­ing mil­lisec­onds until the next excution.
prop­er­ty _afterResume — #boolean; Indi­cates the cycle after “resum­ing” the timeout.
prop­er­ty _percentDone — #float; Stores the per­cent done in the moment of pausing.
————————————————-
PUBLIC PROPERTIES
————————————————-
on ___________________________PUBLIC_PROPERTIES
end

prop­er­ty _state
on state( me )
return _state
end state

prop­er­ty _count
on cur­rent­Count( me )
return _count
end currentCount

prop­er­ty _number
on repeat­Count( me, avalue )
if voidP( aval­ue ) then return _number
_number = max( aval­ue, _count )
end repeatCount

on peri­od( me, avalue )
if( voidP( aval­ue ) ) then return me._getPeriod()
_timeout.period = avalue
end period

on remain­ing­Time( me )
if( ilk( _timeout ) = #time­out ) then
return( _timeout.time — _system.milliseconds )
else
return 0.000001
end if
end remainingTime

on time( me )
if( ilk( _timeout ) = #time­out ) then return VOID
return _timeout.time
end time

on per­cent­Done( me )
if( _state = #stopped ) then
return 0.0
else if( _state = #runned ) then
if( _afterResume ) then
return 1 — ( me.remainingTime() / me.period() ) * _percentDone
else
return 1 — ( me.remainingTime() / me.period() )
end if
else if( _state = #paused ) then
return 1 — ( _remMs / float( _period ) )
end if
end percentDone

————————————————-
CONSTRUCTOR
————————————————-
on ___________________________CONSTRUCTOR
end

on new( me, aPe­ri­od, aNumber )
if( not ilk( aPe­ri­od ) = #inte­ger ) then me._exception( #new, #peri­od )
if( not ilk( aNum­ber ) = #inte­ger ) then me._exception( #new, #cycles )
ances­tor = script( “Event­Dis­patch­er” ).rawNew()
callAnces­tor( #new, me )
_name = string( me )
_period = aPeriod
_number = aNumber
_count = 0
_remMs = 0
_state = #stopped
_afterResume = false
_percentDone = 0
return me
end new

————————————————-
PUBLIC METHODS
————————————————-
on ___________________________PUBLIC_METHODS
end

on start( me )
if( _number = 0 ) then return
_timeout = timeout().new( _name, _period, #_execute, me )
_state = #runned
end start

on stop( me )
if ( ilk( _timeout ) = #time­out ) then
_timeout.forget()
_timeout = VOID
_remMs = 0
_afterResume = false
_percentDone = 0.0
end if
_state = #stopped
end stop

on pause( me )
if( _state = #runned ) then return
_remMs = me.remainingTime()
_percentDone = ( _remMs / float( _period ) )
if ( ilk( _timeout ) = #time­out ) then
_timeout.forget()
_timeout = VOID
end if
_state = #paused
end pause

on resume( me )
if( _state = #stopped ) then return
_timeout = timeout().new( _name, _remMs, #_execute, me )
_state = #runned
_afterResume = true
nothing
end resume

on scale( me, avalue )
if( ilk( _timeout ) = #time­out ) then return
p = inte­ger( _timeout.period * avalue )
_timeout.period = p
end scale

on dis­pose( me )
if not voidP( ances­tor ) then callAnces­tor( #dis­pose, me )
if ilk( _timeout ) = #time­out then
_timeout.forget()
end if
_timeout = VOID
_name = VOID
_period = VOID
_number = VOID
_count = VOID
_remMs = VOID
_state = VOID
_afterResume = VOID
_percentDone = VOID
end dispose

————————————————-
PRIVATE METHODS
————————————————-
on ___________________________PRIVATE_METHODS
end

on _getPeriod( me )
if( ilk( _timeout ) = #time­out ) then
return float( _timeout.period )
else
return 0.000001
end if
end _getPeriod

on _execute( me )
_count = _count + 1
me.dispatchEvent( #TIMER, me, [ #currentCount:_count, #repeatCount:_number, #totalPercentDone:max( 0, _count / float( _number ) ) ] )
if( _afterResume ) then
_timeout.period = _period
_afterResume = false
end if
if ( _number = ‑1 ) then
nothing
else
if ( _count >= _number ) then
me.stop()
me.dispatchEvent( #TIMER_COMPLETE, me, [ #repeatCount:_number, #totalPercentDone:max( 0,_count / float( _number ) ) ] )
end if
end if
end _execute

on _exception( me, ahan­dler, ames­sage, avalue )
exl = propList()
exl.addProp( #peri­od, “Bad para­me­ter — Time­out peri­od (mil­lisec­onds): #inte­ger” )
exl.addProp( #cycles, “Bad para­me­ter — Num­ber of cycles: #inte­ger” )
_player.alert( string( exl[ ames­sage ] ) & RETURN & \
“script:” && me.script & RETURN & \
“han­dler:” && “#” & ahandler )
_movie.halt()
end _exception

Extend­ed Time­out demo

To visu­al­ize the time past, we use:

on enter­Frame( me )
p = myTimeout.percentDone()
sprite( “PROGRESS” ).set­Progress( p )
end enterFrame

Extend­ed Time­out (7530 downloads) 
 
Comments

This is great and use­ful code. Thanks for posting!