Hi, just for fun and while studying metatables and OOP just made the first version of a custom timer, like the timer.performWithDelay with some differences.
What can this timer do?
It can autostart (like timer.performWithDelay);
It can have more than 1 interaction (like timer.performWithDelay)
It can call a function for each interaction (like timer.performWithDelay)
It can also be declared on the beginning of a scene and called later, and reused anytime you want. (less code to call when is called to run, faster start) - autostart=false. use variable.start() to start it.
By default when it ends it will delete itself. If you want to use it more than 1 time you need to use autoRemove=false.
It has pause, resume, remove, cancel and start methods.
it stores a special variable. It’s a counter while the timer is active. This can be used to use in counter. - variable.elapsedTime returns the time passed by the timer. it’s updated every frame.
This is my version:
local newTimer={} newTimer.prototype = {delay=1000, listener =function() end, interactions=1, autoRemove=true, autoStart=true, elapsedTime=0} newTimer.mt = {\_\_index = newTimer.prototype } function newTimer.new(oIn) local o=oIn or {} setmetatable(o, newTimer.mt) local counter\_interaction=1 local startTime local autoRemove=o.autoRemove local autoStart=o.autoStart local pausedTime=0 local function updateTime() local time = system.getTimer() if startTime and counter\_interaction and time+pausedTime \>= startTime+counter\_interaction\*o.delay then counter\_interaction=counter\_interaction+1 o.listener() if counter\_interaction\>o.interactions and o.interactions~=0 then if autoRemove then o.remove() else o.cancel() end end end if startTime then o.elapsedTime=(time+pausedTime-startTime) end end local function addListner() if updateTime then Runtime:addEventListener("enterFrame", updateTime) end end local function removeListner() if updateTime then Runtime:removeEventListener("enterFrame", updateTime) end end function o.start() counter\_interaction=1 autoRemove=o.autoRemove autoStart=o.autoStart pausedTime=0 o.resume() end function o.pause() pausedTime=system.getTimer() removeListner() end function o.resume() startTime=system.getTimer() addListner() end function o.cancel() removeListner() startTime=nil counter\_interaction=1 o.elapsedTime=0 pausedTime=0 end function o.remove() removeListner() for n,m in pairs (o) do o[m]=nil o[n]=nil end startTime=nil counter\_interaction=nil updateTime=nil addListner=nil removeListner=nil pausedTime=nil end if autoStart then o.start() end return o end
to use it, here are some examples:
local timer1 local timer2 local timer3 local delay=2000 local interactions=4 local counter=0 local function printTime() print (timer1.elapsedTime) end local function showTime() print("DO SOMETHING") counter=counter+1 if counter\>=interactions then Runtime:removeEventListener( "enterFrame", printTime ) end end timer1=newTimer.new({delay=delay, listener=showTime, interactions=interactions}) local function startTimer1() print ("pause timer1") timer1.pause() end local function resumeTimer1() print ("resume timer1") timer1.resume() end timer2=newTimer.new({delay=1500, listener=startTimer1}) timer3=newTimer.new({delay=5000, listener=resumeTimer1}) Runtime:addEventListener("enterFrame", printTime)
Can you make a version of a timer, so we can share different approaches? if you can not, can you at least point some other directions of the code? And justify your reasons please so we can all learn from it.
I used metatables to initiate variables, created some local functions that I didn’t want to be called outside the scope, created others that could. Just started to learn meta yesterday so bare with me. Never needed them, but I can see the potential using them. I was thinking to pass all methods outside the .new() function but other variables will be exposed and I don’t want that, for the sake of the experience.
Regards,
Carlos.