-- $LastChangedDate: 2010-04-12 23:22:52 -0500 (Mon, 12 Apr 2010) $
-- Registry of timer-tick callbacks.

Timer = {
    callbacks = {},
    zombies = {},
}

-- NOTE: Name of callback must be "Tick()".
-- Register callback.
-- "object" means either a class object or instance object.
-- Frequency is in milliseconds.  If omitted, frequency is every frame.
function Timer:Register( object, freq )
    --assert( object.Tick )  -- too soon, Tick() may be defined after ctor calls Register()
    self.callbacks[object] = { freq = freq or 0, lastTime = 0 }
end

-- Unregister callback.
function Timer:Unregister( object )
    -- Do not modify self.callbacks to avoid disrupting iteration.
    self.zombies[object] = true
end

-- Register a timer-tick callback.
-- Can cope with callbacks that call Unregister().
function Timer:Tick( callback )
    -- First, destroy unregistered callbacks.
    for zombie in KEYS(self.zombies) do
        self.callbacks[zombie] = nil
    end
    self.zombies = {}

    -- Invoke all callbacks.
    local now = sim.Base:GetElapsedTime()  -- milliseconds
    for object,timeInfo in KEYS_VALS(self.callbacks) do
        -- Time to invoke callback?
        if ( now - timeInfo.lastTime > timeInfo.freq ) then
            -- Remember time it was called.
            timeInfo.lastTime = now

            -- Invoke callback.
            object.Tick( object )
        end
    end
end
