mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Fixed that schedulers, which are not attached to an object, after garbage collect were removed also from the scheduler dispatcher. The scheduler dispatcher now attaches the schedulers to 2 different tables. - A weak table ObjectSchedulers, which contains scheduler attached to objects. When the object is removed, the scheduler is removed also. - A weak table with PersistentSchedulers, which contains schedulers not attached to objects. These schedulers are persistent, even after garbage collection. I hope this now makes the circle round...
173 lines
5.3 KiB
Lua
173 lines
5.3 KiB
Lua
--- This module contains the TIMER class.
|
|
--
|
|
-- ===
|
|
--
|
|
-- Takes care of scheduled function dispatching for defined in MOOSE classes.
|
|
--
|
|
-- This function is complicated.
|
|
--
|
|
-- ===
|
|
--
|
|
-- ===
|
|
--
|
|
-- ### Contributions: -
|
|
-- ### Authors: FlightControl : Design & Programming
|
|
--
|
|
-- @module Timer
|
|
|
|
--- The TIMER structure
|
|
-- @type TIMER
|
|
TIMER = {
|
|
ClassName = "TIMER",
|
|
CallID = 0,
|
|
}
|
|
|
|
function TIMER:New()
|
|
local self = BASE:Inherit( self, BASE:New() )
|
|
self:F3()
|
|
return self
|
|
end
|
|
|
|
--- Add a Schedule to the ScheduleDispatcher.
|
|
-- The development of this method was really tidy.
|
|
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is nillified.
|
|
-- Nothing of this code should be modified without testing it thoroughly.
|
|
-- @param #TIMER self
|
|
-- @param Core.Scheduler#SCHEDULER Scheduler
|
|
function TIMER:AddSchedule( Scheduler, ScheduleFunction, ScheduleArguments, Start, Repeat, Randomize, Stop )
|
|
self:F( { Scheduler, ScheduleFunction, ScheduleArguments, Start, Repeat, Randomize, Stop } )
|
|
|
|
self.CallID = self.CallID + 1
|
|
|
|
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
|
|
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
|
|
self.PersistentSchedulers = self.PersistentSchedulers or {}
|
|
|
|
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
|
|
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
|
|
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } )
|
|
|
|
if Scheduler.TimeEventObject then
|
|
self.ObjectSchedulers[self.CallID] = Scheduler
|
|
self:T3( { self.CallID, self.ObjectSchedulers[self.CallID] } )
|
|
else
|
|
self.PersistentSchedulers[self.CallID] = Scheduler
|
|
self:T3( { self.CallID, self.PersistentSchedulers[self.CallID] } )
|
|
end
|
|
|
|
self.Schedule = self.Schedule or setmetatable( {}, { __mode = "k" } )
|
|
self.Schedule[Scheduler] = {}
|
|
self.Schedule[Scheduler][self.CallID] = {}
|
|
self.Schedule[Scheduler][self.CallID].Function = ScheduleFunction
|
|
self.Schedule[Scheduler][self.CallID].Arguments = ScheduleArguments
|
|
self.Schedule[Scheduler][self.CallID].StartTime = timer.getTime() + ( Start or 0 )
|
|
self.Schedule[Scheduler][self.CallID].Start = Start + .001
|
|
self.Schedule[Scheduler][self.CallID].Repeat = Repeat
|
|
self.Schedule[Scheduler][self.CallID].Randomize = Randomize
|
|
self.Schedule[Scheduler][self.CallID].Stop = Stop
|
|
|
|
self:T3( self.Schedule[Scheduler][self.CallID] )
|
|
|
|
self.Schedule[Scheduler][self.CallID].CallHandler = function( CallID )
|
|
self:F3( CallID )
|
|
|
|
local ErrorHandler = function( errmsg )
|
|
env.info( "Error in timer function: " .. errmsg )
|
|
if debug ~= nil then
|
|
env.info( debug.traceback() )
|
|
end
|
|
return errmsg
|
|
end
|
|
|
|
local Scheduler = self.ObjectSchedulers[CallID]
|
|
if not Scheduler then
|
|
Scheduler = self.PersistentSchedulers[CallID]
|
|
end
|
|
|
|
self:T3( { Scheduler = Scheduler } )
|
|
|
|
if Scheduler then
|
|
|
|
local Schedule = self.Schedule[Scheduler][CallID]
|
|
|
|
self:T3( { Schedule = Schedule } )
|
|
|
|
local ScheduleObject = Scheduler.TimeEventObject
|
|
local ScheduleFunction = Schedule.Function
|
|
local ScheduleArguments = Schedule.Arguments
|
|
local Start = Schedule.Start
|
|
local Repeat = Schedule.Repeat or 0
|
|
local Randomize = Schedule.Randomize or 0
|
|
local Stop = Schedule.Stop or 0
|
|
local ScheduleID = Schedule.ScheduleID
|
|
|
|
local Status, Result
|
|
if ScheduleObject then
|
|
local function Timer()
|
|
return ScheduleFunction( ScheduleObject, unpack( ScheduleArguments ) )
|
|
end
|
|
Status, Result = xpcall( Timer, ErrorHandler )
|
|
else
|
|
local function Timer()
|
|
return ScheduleFunction( unpack( ScheduleArguments ) )
|
|
end
|
|
Status, Result = xpcall( Timer, ErrorHandler )
|
|
end
|
|
|
|
local CurrentTime = timer.getTime()
|
|
local StartTime = CurrentTime + Start
|
|
|
|
if Status and (( Result == nil ) or ( Result and Result ~= false ) ) then
|
|
if Repeat ~= 0 and ( Stop == 0 ) or ( Stop ~= 0 and CurrentTime <= StartTime + Stop ) then
|
|
local ScheduleTime =
|
|
CurrentTime +
|
|
Repeat +
|
|
math.random(
|
|
- ( Randomize * Repeat / 2 ),
|
|
( Randomize * Repeat / 2 )
|
|
) +
|
|
0.01
|
|
self:T( { ScheduleArguments, "Repeat:", CurrentTime, ScheduleTime } )
|
|
return ScheduleTime -- returns the next time the function needs to be called.
|
|
else
|
|
timer.removeFunction( ScheduleID )
|
|
ScheduleID = nil
|
|
end
|
|
else
|
|
timer.removeFunction( ScheduleID )
|
|
ScheduleID = nil
|
|
end
|
|
else
|
|
self:E( "Scheduled obscolete call ..." )
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
|
|
self.Schedule[Scheduler][self.CallID].ScheduleID = timer.scheduleFunction(
|
|
self.Schedule[Scheduler][self.CallID].CallHandler,
|
|
self.CallID,
|
|
timer.getTime() + self.Schedule[Scheduler][self.CallID].Start
|
|
)
|
|
|
|
return self.CallID
|
|
end
|
|
|
|
function TIMER:RemoveSchedule( CallID )
|
|
self:F( CallID )
|
|
|
|
local Schedule = self.ObjectSchedulers[CallID]
|
|
|
|
if Schedule then
|
|
local ScheduleID = Schedule.ScheduleID
|
|
timer.removeFunction( ScheduleID )
|
|
ScheduleID = nil
|
|
Schedule = nil
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|