Code: Select all
;-===MODULE DESCRIPTION===
;Tiny module to create periodic tickers
;Created with PB 6.20 Beta 1
;Author: :miso
;Creation date:2025.01.31
;Purpose :for periodic tasks like sending a keepalive packet to push through nat or change frame of an animation, etc
;Scope :all platforms, but tested only on Windows 7 64 bit
;Permissions :777, do what you want, (author takes no responsibilities nor any claims)
EnableExplicit
;-===MODULE DECLARATION===
DeclareModule ticker
;-===CONSTANTS===
#TICKS_FOREVER = -10
#MAXIMUM_ALLOWED_TICKERS = 255
;-===STRUCTURES===
Structure tickerstructure
timeout.i
lasttick.i
current_tick_count.i
target_tick_count.i
alive.i
EndStructure
;-===PUBLIC PROCEDURE DECLARATIONS===
Declare.i create(ID.i,ticktime_ms.i,number_of_ticks.i=#TICKS_FOREVER)
Declare.i triggered(ID.i)
Declare.i kill(ID.i)
EndDeclareModule
;-===MODULE===
Module ticker
;-===PRIVATE GLOBALS===
Global Dim tickers.tickerstructure(#MAXIMUM_ALLOWED_TICKERS)
;-===PUBLIC PROCEDURES===
;***************************************
;Create a new ticker
;***************************************
Procedure.i create(ID.i,ticktime_ms.i,number_of_ticks.i=#TICKS_FOREVER)
If ID.i>=0 And ID.i<=#MAXIMUM_ALLOWED_TICKERS
With tickers(ID.i)
\lasttick.i = ElapsedMilliseconds()
\timeout.i = ticktime_ms.i
\current_tick_count.i = 0
\alive.i = #True
\target_tick_count = number_of_ticks.i
EndWith
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
;***************************************
;Returns the triggered status of a ticker
;***************************************
Procedure.i triggered(ID.i)
If ID.i<0 Or ID.i>#MAXIMUM_ALLOWED_TICKERS
Debug Str(ID.i) + " not exists, cant be checked"
ProcedureReturn #False
EndIf
If tickers(ID.i)\alive <> #True
ProcedureReturn #False
EndIf
If ElapsedMilliseconds()-tickers(ID.i)\lasttick<tickers(ID.i)\timeout
ProcedureReturn #False
EndIf
tickers(ID.i)\current_tick_count + 1
tickers(ID.i)\lasttick = ElapsedMilliseconds()
If tickers(ID.i)\current_tick_count = tickers(ID.i)\target_tick_count
tickers(ID.i)\alive = #False
EndIf
ProcedureReturn #True
EndProcedure
;***************************************
;Sets a ticker to be dead
;***************************************
Procedure.i Kill(ID.i)
If ID.i<0 Or ID.i>#MAXIMUM_ALLOWED_TICKERS
ProcedureReturn #False
EndIf
tickers(ID.i)\alive = #False
ProcedureReturn #True
EndProcedure
EndModule
;-===EXAMPLE USAGE===
OpenConsole("Periodic Tickers")
ticker::create(0,5000) ;this ticker can proc any number of times with 5000 ms delay
ticker::create(1,1000,2) ;This can proc only twice, then stops
ticker::create(2,200) ;this ticker can proc any number of times with 200 ms delay
Repeat
If ticker::triggered(1) : PrintN("Tiktak") : EndIf
If ticker::triggered(2) : PrintN("Tak") : EndIf
Until ticker::triggered(0)
ticker::kill(0) ;not needed, just showcase for example
End