Starting to harmonize the new TASK logic with the old DETECTION_DISPATCHER

This commit is contained in:
FlightControl 2016-11-23 18:37:12 +01:00
parent 20dca5088a
commit 35ac87109b
12 changed files with 98 additions and 197 deletions

View File

@ -127,6 +127,24 @@ function BASE:_Destructor()
self:EventRemoveAll()
end
function BASE:_SetDestructor()
local proxy = newproxy(true)
local proxyMeta = getmetatable(proxy)
proxyMeta.__gc = function ()
-- env.info("In __gc for " .. Child:GetClassNameAndID() )
if self._Destructor then
self:_Destructor()
end
end
-- keep the userdata from newproxy reachable until the object
-- table is about to be garbage-collected - then the __gc hook
-- will be invoked and the destructor called
rawset( self, '__proxy', proxy )
end
--- This is the worker method to inherit from a parent class.
-- @param #BASE self
@ -141,21 +159,7 @@ function BASE:Inherit( Child, Parent )
setmetatable( Child, Parent )
Child.__index = Child
local proxy = newproxy(true)
local proxyMeta = getmetatable(proxy)
proxyMeta.__gc = function ()
-- env.info("In __gc for " .. Child:GetClassNameAndID() )
if Child._Destructor then
Child:_Destructor()
end
end
-- keep the userdata from newproxy reachable until the object
-- table is about to be garbage-collected - then the __gc hook
-- will be invoked and the destructor called
rawset(Child, '__proxy', proxy)
Child:_SetDestructor()
end
--self:T( 'Inherited from ' .. Parent.ClassName )
return Child

View File

@ -98,6 +98,8 @@ function STATEMACHINE:AddProcess( From, Event, Process, ReturnEvents )
sub.event = "Start"
sub.ReturnEvents = ReturnEvents
-- Make the reference table weak.
setmetatable( self.options.subs, { __mode = "v" } )
self.options.subs[Event] = sub
self:_submap( self.subs, sub, nil )
@ -137,13 +139,16 @@ function STATEMACHINE:_submap( subs, sub, name )
self:E( { sub = sub, name = name } )
subs[sub.FromParent] = subs[sub.FromParent] or {}
subs[sub.FromParent][sub.EventParent] = subs[sub.FromParent][sub.EventParent] or {}
local Index = #subs[sub.FromParent][sub.EventParent] + 1
subs[sub.FromParent][sub.EventParent][Index] = {}
subs[sub.FromParent][sub.EventParent][Index].fsm = sub.fsm
subs[sub.FromParent][sub.EventParent][Index].event = sub.event
subs[sub.FromParent][sub.EventParent][Index].ReturnEvents = sub.ReturnEvents or {} -- these events need to be given to find the correct continue event ... if none given, the processing will stop.
subs[sub.FromParent][sub.EventParent][Index].name = name
subs[sub.FromParent][sub.EventParent][Index].fsmparent = self
-- Make the reference table weak.
setmetatable( subs[sub.FromParent][sub.EventParent], { __mode = "k" } )
subs[sub.FromParent][sub.EventParent][sub] = {}
subs[sub.FromParent][sub.EventParent][sub].fsm = sub.fsm
subs[sub.FromParent][sub.EventParent][sub].event = sub.event
subs[sub.FromParent][sub.EventParent][sub].ReturnEvents = sub.ReturnEvents or {} -- these events need to be given to find the correct continue event ... if none given, the processing will stop.
subs[sub.FromParent][sub.EventParent][sub].name = name
subs[sub.FromParent][sub.EventParent][sub].fsmparent = self
end

View File

@ -201,7 +201,7 @@ do -- PROCESS_ACCOUNT_DEADS
function PROCESS_ACCOUNT_DEADS:_Destructor()
self:E("_Destructor")
self:RemoveEventsAll()
self:EventRemoveAll()
end

View File

@ -144,12 +144,12 @@ do -- PROCESS_SMOKE_TARGETS_ZONE
ClassName = "PROCESS_SMOKE_TARGETS_ZONE",
}
function PROCESS_SMOKE_TARGETS_ZONE:_Destructor()
self:E("_Destructor")
self.Menu:Remove()
self:EventRemoveAll()
end
-- function PROCESS_SMOKE_TARGETS_ZONE:_Destructor()
-- self:E("_Destructor")
--
-- self.Menu:Remove()
-- self:EventRemoveAll()
-- end
--- Creates a new target smoking state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
-- @param #PROCESS_SMOKE_TARGETS_ZONE self

View File

@ -170,6 +170,11 @@ function TASK_BASE:AssignToUnit( TaskUnit )
for FsmSubID, FsmSub in pairs( FsmUnit:GetSubs() ) do
self:E( { "Sub ID", FsmSub.fsm:GetClassNameAndID(), FsmSubID } )
FsmSub.fsm:Assign( self, TaskUnit )
--FsmSub.fsm:_SetDestructor()
--FsmSub.fsm = nil
--collectgarbage()
end
@ -190,6 +195,8 @@ function TASK_BASE:AssignToUnit( TaskUnit )
FsmUnit:SetInitialState( "Planned" )
FsmUnit:Accept() -- Each Task needs to start with an Accept event to start the flow.
return self
end

View File

@ -44,114 +44,41 @@ do -- TASK_A2G
self.TargetSetUnit = TargetSetUnit
self.TargetZone = TargetZone
self.FACUnit = FACUnit
self:SetProcessTemplate( "PROCESS_ASSIGN", PROCESS_ASSIGN_ACCEPT:New( self.TaskBriefing ) )
self:SetProcessTemplate( "PROCESS_ROUTE", PROCESS_ROUTE_ZONE:New( self.TargetZone ) )
self:SetProcessTemplate( "PROCESS_ACCOUNT", PROCESS_ACCOUNT_DEADS:New( self.TargetSetUnit, "A2G" ) )
local ProcessSmoke = self:AddProcess( TaskUnit, PROCESS_SMOKE_TARGETS_ZONE:New( self, TaskUnit, self.TargetSetUnit, self.TargetZone ) )
local ProcessJTAC = self:AddProcess( TaskUnit, PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
local Fsm = self:GetFsmTemplate()
_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
_EVENTDISPATCHER:OnDead( self._EventDead, self )
_EVENTDISPATCHER:OnCrash( self._EventDead, self )
_EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
Fsm:AddProcess( "Planned", "Accept", PROCESS_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
Fsm:AddProcess( "Assigned", "Route", PROCESS_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
Fsm:AddAction ( "Arrived", "Update", "Updated" )
Fsm:AddProcess( "Updated", "Account", PROCESS_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
Fsm:AddProcess( "Updated", "Smoke", PROCESS_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
--Fsm:AddProcess( "Updated", "JTAC", PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
Fsm:AddAction ( "Accounted", "Success", "Success" )
Fsm:AddAction ( "Failed", "Fail", "Failed" )
function Fsm:onenterUpdated( TaskUnit )
self:E( { self } )
self:Account()
self:Smoke()
end
--_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
--_EVENTDISPATCHER:OnDead( self._EventDead, self )
--_EVENTDISPATCHER:OnCrash( self._EventDead, self )
--_EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
return self
end
--- Removes a TASK_A2G.
-- @param #TASK_A2G self
-- @return #nil
function TASK_A2G:CleanUp()
self:GetParent( self ):CleanUp()
return nil
end
--- Assign the @{Task} to a @{Unit}.
-- @param #TASK_A2G self
-- @param Unit#UNIT TaskUnit
-- @return #TASK_A2G self
function TASK_A2G:AssignToUnit( TaskUnit )
self:F( TaskUnit:GetName() )
local ProcessAssign = self:AssignProcess( TaskUnit, "PROCESS_ASSIGN" )
local ProcessRoute = self:AssignProcess( TaskUnit, "PROCESS_ROUTE" )
local ProcessDestroy = self:AssignProcess( TaskUnit, "PROCESS_ACCOUNT" )
--local ProcessSmoke = self:AddProcess( TaskUnit, PROCESS_SMOKE_TARGETS_ZONE:New( self, TaskUnit, self.TargetSetUnit, self.TargetZone ) )
--local ProcessJTAC = self:AddProcess( TaskUnit, PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
local Process = self:AddStateMachine( TaskUnit, STATEMACHINE_TASK:New( self, TaskUnit, {
initial = 'None',
events = {
{ name = 'Next', from = 'None', to = 'Planned' },
{ name = 'Next', from = 'Planned', to = 'Assigned' },
{ name = 'Reject', from = 'Planned', to = 'Rejected' },
{ name = 'Next', from = 'Assigned', to = 'Success' },
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
{ name = 'Fail', from = 'Arrived', to = 'Failed' }
},
callbacks = {
onNext = self.OnNext,
onRemove = self.OnRemove,
},
subs = {
Assign = { onstateparent = 'Planned', oneventparent = 'Next', fsm = ProcessAssign.Fsm, event = 'Start', returnevents = { 'Next', 'Reject' } },
Route = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessRoute.Fsm, event = 'Start' },
Destroy = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessDestroy.Fsm, event = 'Start', returnevents = { 'Next' } },
Smoke = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessSmoke.Fsm, event = 'Start', },
JTAC = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessJTAC.Fsm, event = 'Start', },
}
} ) )
ProcessRoute:AddScore( "Failed", "failed to destroy a ground unit", -100 )
ProcessDestroy:AddScore( "Destroy", "destroyed a ground unit", 25 )
ProcessDestroy:AddScore( "Failed", "failed to destroy a ground unit", -100 )
Process:Next()
return self
end
--- StateMachine callback function for a TASK
-- @param #TASK_A2G self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Event#EVENTDATA Event
function TASK_A2G:OnNext( Fsm, Event, From, To, Event )
self:SetState( self, "State", To )
end
--- @param #TASK_A2G self
function TASK_A2G:GetPlannedMenuText()
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
end
--- @param #TASK_A2G self
function TASK_A2G:_Schedule()
self:F2()
self.TaskScheduler = SCHEDULER:New( self, _Scheduler, {}, 15, 15 )
return self
end
--- @param #TASK_A2G self
function TASK_A2G._Scheduler()
self:F2()
return true
end
end

View File

@ -45,80 +45,31 @@ do -- TASK_SEAD
self.TargetSetUnit = TargetSetUnit
self.TargetZone = TargetZone
self:SetProcessTemplate( "ASSIGN", PROCESS_ASSIGN_ACCEPT:New( self.TaskBriefing ) )
self:SetProcessTemplate( "ROUTE", PROCESS_ROUTE_ZONE:New( self.TargetZone ) )
self:SetProcessTemplate( "ACCOUNT", PROCESS_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ) )
self:SetProcessTemplate( "SMOKE", PROCESS_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
local Fsm = self:GetFsmTemplate()
Fsm:AddProcess( "Planned", "Accept", "Planned", PROCESS_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Eject" } )
Fsm:AddProcess( "Assigned", "Route", PROCESS_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
Fsm:AddAction ( "Arrived", "Update", "Updated" )
Fsm:AddProcess( "Updated", "Account", PROCESS_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
Fsm:AddProcess( "Updated", "Smoke", PROCESS_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
Fsm:AddAction ( "Accounted", "Success", "Success" )
Fsm:AddAction ( "Failed", "Fail", "Failed" )
_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
_EVENTDISPATCHER:OnDead( self._EventDead, self )
_EVENTDISPATCHER:OnCrash( self._EventDead, self )
_EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
function Fsm:onenterUpdated( TaskUnit )
self:E( { self } )
self:Account()
self:Smoke()
end
-- _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
-- _EVENTDISPATCHER:OnDead( self._EventDead, self )
-- _EVENTDISPATCHER:OnCrash( self._EventDead, self )
-- _EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
return self
end
--- Removes a TASK_SEAD.
-- @param #TASK_SEAD self
-- @return #nil
function TASK_SEAD:CleanUp()
self:GetParent(self):CleanUp()
return nil
end
--- Assign the @{Task} to a @{Unit}.
-- @param #TASK_SEAD self
-- @param Unit#UNIT TaskUnit
-- @return #TASK_SEAD self
function TASK_SEAD:AssignToUnit( TaskUnit )
self:F( TaskUnit:GetName() )
local ProcessAssign = self:AssignProcess( TaskUnit, "ASSIGN" )
local ProcessRoute = self:AssignProcess( TaskUnit, "ROUTE" )
local ProcessAccount = self:AssignProcess( TaskUnit, "ACCOUNT" )
local ProcessSmoke = self:AssignProcess( TaskUnit, "SMOKE" )
local FSMT = {
initial = 'None',
events = {
{ name = 'Start', from = 'None', to = 'Planned' },
{ name = 'Next', from = 'Planned', to = 'Assigned' },
{ name = 'Reject', from = 'Planned', to = 'Rejected' },
{ name = 'Next', from = 'Assigned', to = 'Success' },
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
{ name = 'Fail', from = 'Arrived', to = 'Failed' }
},
subs = {
Assign = { onstateparent = 'Planned', oneventparent = 'Next', fsm = ProcessAssign, event = 'Start', returnevents = { 'Next', 'Reject' } },
Route = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessRoute, event = 'Start' },
Sead = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessAccount, event = 'Start', returnevents = { 'Next' } },
Smoke = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessSmoke, event = 'Start', }
}
}
local Process = self:AddStateMachine( TaskUnit, STATEMACHINE_TASK:New( FSMT, self, TaskUnit ) )
Process:Next()
return self
end
--- StateMachine callback function for a TASK
-- @param #TASK_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Event#EVENTDATA Event
function TASK_SEAD:onafterNext( Fsm, Event, From, To )
self:SetState( self, "State", To )
end
--- @param #TASK_SEAD self
function TASK_SEAD:GetPlannedMenuText()
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"

View File

@ -1,5 +1,5 @@
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
env.info( 'Moose Generation Timestamp: 20161102_0903' )
env.info( 'Moose Generation Timestamp: 20161123_1801' )
local base = _G

View File

@ -1,5 +1,5 @@
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
env.info( 'Moose Generation Timestamp: 20161102_0903' )
env.info( 'Moose Generation Timestamp: 20161123_1801' )
local base = _G

View File

@ -1,6 +1,13 @@
env.info( "Lua Version = " .. _VERSION )
-- Test Garbage control of one declared PROCESS.
do
local Process = PROCESS_ASSIGN_ACCEPT:New( "SEAD the Area" )
end
collectgarbage()
local Mission = MISSION:New( 'SEAD Targets', "Strategic", "SEAD the enemy", coalition.side.RED )
local Scoring = SCORING:New( "SEAD" )