From 2f4eb39156fe25ff93e8092e351695719e474bd0 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Tue, 22 Nov 2016 08:45:38 +0100 Subject: [PATCH] Jippie! Finally got the Sub Statemachine declaration understandable for end-users. Reworked the hierarchical state machine processing in terms of sub processing. Now, the declaration and usage of subs is completely understandable and easy to implement. I am excited to see how end-users will see the possibilities. --- Moose Development/Moose/Core/Base.lua | 25 +++ Moose Development/Moose/Core/Event.lua | 9 +- Moose Development/Moose/Core/StateMachine.lua | 140 +++++++++----- Moose Development/Moose/Fsm/Process.lua | 14 +- Moose Development/Moose/Process/Account.lua | 21 ++- Moose Development/Moose/Process/Assign.lua | 8 + Moose Development/Moose/Process/Route.lua | 29 ++- Moose Development/Moose/Process/Smoke.lua | 13 +- Moose Development/Moose/Tasking/Task.lua | 175 ++++++++---------- Moose Development/Moose/Tasking/Task_SEAD.lua | 5 +- .../Moose_Test_Task_SEAD.lua | 36 ++-- .../Moose_Test_Task_SEAD.miz | Bin 26262 -> 25960 bytes .../DCS World - MOOSE - Tasking - SEAD.pptx | Bin 2757198 -> 2757094 bytes 13 files changed, 296 insertions(+), 179 deletions(-) diff --git a/Moose Development/Moose/Core/Base.lua b/Moose Development/Moose/Core/Base.lua index 9db404093..9ceb850bb 100644 --- a/Moose Development/Moose/Core/Base.lua +++ b/Moose Development/Moose/Core/Base.lua @@ -116,9 +116,18 @@ function BASE:New() self.__index = self _ClassID = _ClassID + 1 self.ClassID = _ClassID + + return self end +function BASE:_Destructor() + --self:E("_Destructor") + + self:EventRemoveAll() +end + + --- This is the worker method to inherit from a parent class. -- @param #BASE self -- @param Child is the Child class that inherits. @@ -131,6 +140,22 @@ function BASE:Inherit( Child, Parent ) if Child ~= nil then 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) + end --self:T( 'Inherited from ' .. Parent.ClassName ) return Child diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index e752a7d3e..3c78e6bb9 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -85,9 +85,16 @@ end -- @return #EVENT.Events function EVENT:Init( EventID, EventClass ) self:F3( { _EVENTCODES[EventID], EventClass } ) - if not self.Events[EventID] then + + if not self.Events[EventID] then self.Events[EventID] = {} + + -- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned. + local Meta = {} + setmetatable( self.Events[EventID], Meta ) + Meta.__mode = "k" end + if not self.Events[EventID][EventClass] then self.Events[EventID][EventClass] = {} end diff --git a/Moose Development/Moose/Core/StateMachine.lua b/Moose Development/Moose/Core/StateMachine.lua index fd353d464..3257e8280 100644 --- a/Moose Development/Moose/Core/StateMachine.lua +++ b/Moose Development/Moose/Core/StateMachine.lua @@ -18,7 +18,7 @@ --- STATEMACHINE class -- @type STATEMACHINE --- @extends Base#BASE +-- @extends Core.Base#BASE STATEMACHINE = { ClassName = "STATEMACHINE", } @@ -34,7 +34,7 @@ function STATEMACHINE:New( options ) --local self = routines.utils.deepCopy( self ) -- Create a new self instance - assert(options.events) + --assert(options.events) --local MT = {} --setmetatable( self, MT ) @@ -46,31 +46,70 @@ function STATEMACHINE:New( options ) self.subs = {} self.endstates = {} - for _, event in ipairs(options.events or {}) do - local name = event.name - local __name = "__" .. event.name - self[name] = self[name] or self:_create_transition(name) - self[__name] = self[__name] or self:_delayed_transition(name) - self:T( "Added methods: " .. name .. ", " .. __name ) - self.events[name] = self.events[name] or { map = {} } - self:_add_to_map(self.events[name].map, event) + for _, event in pairs(options.events or {}) do + self:E({ "events", event }) + self:_eventmap( self.events, event ) end for name, callback in pairs(options.callbacks or {}) do + self:E("callbacks") self[name] = callback end for name, sub in pairs( options.subs or {} ) do + self:E("sub") self:_submap( self.subs, sub, name ) end for name, endstate in pairs( options.endstates or {} ) do + self:E("endstate") self.endstates[endstate] = endstate end return self end +function STATEMACHINE:SetInitialState( State ) + self.current = State +end + +function STATEMACHINE:AddAction( From, Event, To ) + + local event = {} + event.from = From + event.name = Event + event.to = To + + self:E( event ) + + self:_eventmap( self.events, event ) +end + + +--- Set the default @{Process} template with key ProcessName providing the ProcessClass and the process object when it is assigned to a @{Controllable} by the task. +-- @return Process#PROCESS +function STATEMACHINE:AddProcess( From, Event, Process, ReturnEvents ) + + local sub = {} + sub.FromParent = From + sub.EventParent = Event + sub.fsm = Process + sub.event = "Start" + sub.ReturnEvents = ReturnEvents + + self:_submap( self.subs, sub, nil ) + + self:AddAction( From, Event, "*" ) + + return Process +end + +function STATEMACHINE:GetSubs() + + return self.options.subs +end + + function STATEMACHINE:LoadCallBacks( CallBackTable ) for name, callback in pairs( CallBackTable or {} ) do @@ -79,17 +118,29 @@ function STATEMACHINE:LoadCallBacks( CallBackTable ) end +function STATEMACHINE:_eventmap( events, event ) + + local name = event.name + local __name = "__" .. event.name + self[name] = self[name] or self:_create_transition(name) + self[__name] = self[__name] or self:_delayed_transition(name) + self:T( "Added methods: " .. name .. ", " .. __name ) + events[name] = self.events[name] or { map = {} } + self:_add_to_map( events[name].map, event ) + +end + function STATEMACHINE:_submap( subs, sub, name ) self:E( { sub = sub, name = name } ) - subs[sub.onstateparent] = subs[sub.onstateparent] or {} - subs[sub.onstateparent][sub.oneventparent] = subs[sub.onstateparent][sub.oneventparent] or {} - local Index = #subs[sub.onstateparent][sub.oneventparent] + 1 - subs[sub.onstateparent][sub.oneventparent][Index] = {} - subs[sub.onstateparent][sub.oneventparent][Index].fsm = sub.fsm - subs[sub.onstateparent][sub.oneventparent][Index].event = sub.event - subs[sub.onstateparent][sub.oneventparent][Index].returnevents = sub.returnevents -- these events need to be given to find the correct continue event ... if none given, the processing will stop. - subs[sub.onstateparent][sub.oneventparent][Index].name = name - subs[sub.onstateparent][sub.oneventparent][Index].fsmparent = self + 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 end @@ -121,11 +172,15 @@ function STATEMACHINE._handler( self, EventName, ... ) local execute = true - local subtable = self:_gosub( to, EventName ) + local subtable = self:_gosub( from, EventName ) for _, sub in pairs( subtable ) do + --if sub.nextevent then + -- self:F2( "nextevent = " .. sub.nextevent ) + -- self[sub.nextevent]( self ) + --end self:F2( "calling sub: " .. sub.event ) sub.fsm.fsmparent = self - sub.fsm.returnevents = sub.returnevents + sub.fsm.ReturnEvents = sub.ReturnEvents sub.fsm[sub.event]( sub.fsm ) execute = true end @@ -176,32 +231,30 @@ function STATEMACHINE:_create_transition( EventName ) return function( self, ... ) return self._handler( self, EventName , ... ) end end -function STATEMACHINE:_gosub( parentstate, parentevent ) +function STATEMACHINE:_gosub( ParentFrom, ParentEvent ) local fsmtable = {} - if self.subs[parentstate] and self.subs[parentstate][parentevent] then - return self.subs[parentstate][parentevent] + self:E( { ParentFrom, ParentEvent, self.subs[ParentFrom] } ) + if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then + return self.subs[ParentFrom][ParentEvent] else return {} end end -function STATEMACHINE:_isendstate( state ) - local fsmparent = self.fsmparent - if fsmparent and self.endstates[state] then - self:E( { state = state, endstates = self.endstates, endstate = self.endstates[state] } ) - local returnevent = nil - local fromstate = fsmparent.current - self:E( fromstate ) - self:E( self.returnevents ) - for _, eventname in pairs( self.returnevents ) do - local event = fsmparent.events[eventname] - self:E( event ) - local to = event and event.map[fromstate] or event.map['*'] - if to and to == state then - return fsmparent, eventname - else - self:E( { "could not find parent event name for state", fromstate, to } ) - end +function STATEMACHINE:_isendstate( Current ) + local FSMParent = self.fsmparent + if FSMParent and self.endstates[Current] then + self:E( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } ) + FSMParent.current = Current + local ParentFrom = FSMParent.current + self:E( ParentFrom ) + self:E( self.ReturnEvents ) + local Event = self.ReturnEvents[Current] + self:E( { ParentFrom, Event, self.ReturnEvents } ) + if Event then + return FSMParent, Event + else + self:E( { "Could not find parent event name for state ", ParentFrom } ) end end @@ -209,6 +262,7 @@ function STATEMACHINE:_isendstate( state ) end function STATEMACHINE:_add_to_map(map, event) + self:E( { map, event } ) if type(event.from) == 'string' then map[event.from] = event.to else @@ -216,6 +270,7 @@ function STATEMACHINE:_add_to_map(map, event) map[from] = event.to end end + self:E( { map, event } ) end function STATEMACHINE:is(state) @@ -224,6 +279,7 @@ end function STATEMACHINE:can(e) local event = self.events[e] + self:E( { self.current, event } ) local to = event and event.map[self.current] or event.map['*'] return to ~= nil, to end @@ -290,7 +346,7 @@ end --- STATEMACHINE_CONTROLLABLE class -- @type STATEMACHINE_CONTROLLABLE -- @field Controllable#CONTROLLABLE Controllable --- @extends StateMachine#STATEMACHINE +-- @extends Core.StateMachine#STATEMACHINE STATEMACHINE_CONTROLLABLE = { ClassName = "STATEMACHINE_CONTROLLABLE", } diff --git a/Moose Development/Moose/Fsm/Process.lua b/Moose Development/Moose/Fsm/Process.lua index bb6c869be..5b17e1e69 100644 --- a/Moose Development/Moose/Fsm/Process.lua +++ b/Moose Development/Moose/Fsm/Process.lua @@ -6,7 +6,7 @@ -- @field Group#GROUP ProcessGroup -- @field Menu#MENU_GROUP MissionMenu -- @field #string ProcessName --- @extends StateMachine#STATEMACHINE_CONTROLLABLE +-- @extends Core.StateMachine#STATEMACHINE_CONTROLLABLE PROCESS = { ClassName = "PROCESS", NextEvent = nil, @@ -29,6 +29,7 @@ function PROCESS:New( FSMT, ProcessName, ProcessUnit ) --self.MissionMenu = Task.Mission:GetMissionMenu( self.ProcessGroup ) self.ProcessName = ProcessName + return self end @@ -67,15 +68,6 @@ function PROCESS:GetMission() return self.ProcessTask.Mission end -function PROCESS:ProcessStart() - -end - -function PROCESS:ProcessStop() - self:E("ProcessStop Base Class") - - self:EventRemoveAll() -end --- Assign the process to a @{Unit} and activate the process. -- @param #PROCESS self @@ -86,8 +78,6 @@ function PROCESS:Assign( ProcessTask, ProcessUnit ) self:SetControllable( ProcessUnit ) self:SetTask( ProcessTask ) - self:ProcessStart() - self.ProcessGroup = ProcessUnit:GetGroup() --self:Activate() diff --git a/Moose Development/Moose/Process/Account.lua b/Moose Development/Moose/Process/Account.lua index 58b4dc5e1..31514b287 100644 --- a/Moose Development/Moose/Process/Account.lua +++ b/Moose Development/Moose/Process/Account.lua @@ -124,8 +124,11 @@ do -- PROCESS_ACCOUNT -- @param #string To function PROCESS_ACCOUNT:onafterStart( ProcessUnit, Event, From, To ) + self:EventOnDead( self.EventDead ) + self:__Wait( 1 ) end + --- StateMachine callback function -- @param #PROCESS_ACCOUNT self @@ -169,6 +172,15 @@ do -- PROCESS_ACCOUNT_DEADS TargetSetUnit = nil, } + + --- Creates a new DESTROY process. + -- @param #PROCESS_ACCOUNT_DEADS self + -- @param Set#SET_UNIT TargetSetUnit + -- @param #string TaskName + function PROCESS_ACCOUNT_DEADS:Template( TargetSetUnit, TaskName ) + return { self, arg } + end + --- Creates a new DESTROY process. -- @param #PROCESS_ACCOUNT_DEADS self @@ -182,12 +194,15 @@ do -- PROCESS_ACCOUNT_DEADS self.TargetSetUnit = TargetSetUnit self.TaskName = TaskName - + return self end + + function PROCESS_ACCOUNT_DEADS:_Destructor() + self:E("_Destructor") + + self:RemoveEventsAll() - function PROCESS_ACCOUNT_DEADS:ProcessStart() - self:EventOnDead( self.EventDead ) end --- Process Events diff --git a/Moose Development/Moose/Process/Assign.lua b/Moose Development/Moose/Process/Assign.lua index 4cc51bd00..11d80cb57 100644 --- a/Moose Development/Moose/Process/Assign.lua +++ b/Moose Development/Moose/Process/Assign.lua @@ -134,6 +134,14 @@ do -- PROCESS_ASSIGN_ACCEPT } + --- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted. + -- @param #PROCESS_ASSIGN_ACCEPT self + -- @param #string TaskBriefing + function PROCESS_ASSIGN_ACCEPT:Template( TaskBriefing ) + return { self, { TaskBriefing } } + end + + --- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted. -- @param #PROCESS_ASSIGN_ACCEPT self -- @param #string TaskBriefing diff --git a/Moose Development/Moose/Process/Route.lua b/Moose Development/Moose/Process/Route.lua index 482f070a4..ba3451623 100644 --- a/Moose Development/Moose/Process/Route.lua +++ b/Moose Development/Moose/Process/Route.lua @@ -107,7 +107,7 @@ do -- PROCESS_ROUTE { name = 'Fail', from = '*', to = 'Failed' }, }, endstates = { - 'Arrived', 'Failed', 'Success' + 'Arrived', 'Failed' }, } @@ -150,10 +150,10 @@ do -- PROCESS_ROUTE -- @param #string Event -- @param #string From -- @param #string To - function PROCESS_ROUTE:onafterRoute( ProcessUnit, Event, From, To ) + function PROCESS_ROUTE:onbeforeRoute( ProcessUnit, Event, From, To ) if ProcessUnit:IsAlive() then - local HasArrived = self:HasArrived( ProcessUnit ) + local HasArrived = self:HasArrived( ProcessUnit ) -- Polymorphic if self.DisplayCount >= self.DisplayInterval then self:T( { HasArrived = HasArrived } ) if not HasArrived then @@ -165,7 +165,12 @@ do -- PROCESS_ROUTE end self:T( { DisplayCount = self.DisplayCount } ) - self:__Route( 1 ) + + if HasArrived then + self:__Arrive( 1 ) + else + self:__Route( 1 ) + end return HasArrived -- if false, then the event will not be executed... end @@ -189,6 +194,14 @@ do -- PROCESS_ROUTE_ZONE PROCESS_ROUTE_ZONE = { ClassName = "PROCESS_ROUTE_ZONE", } + + + --- Creates a new routing state machine. The task will route a controllable to a ZONE until the controllable is within that ZONE. + -- @param #PROCESS_ROUTE_ZONE self + -- @param Zone#ZONE_BASE TargetZone + function PROCESS_ROUTE_ZONE:Template( TargetZone ) + return { self, arg } + end --- Creates a new routing state machine. The task will route a controllable to a ZONE until the controllable is within that ZONE. @@ -206,9 +219,15 @@ do -- PROCESS_ROUTE_ZONE --- Method override to check if the controllable has arrived. -- @param #PROCESS_ROUTE self - -- @param Controllable#CONTROLLABLE ProcessUnit + -- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit -- @return #boolean function PROCESS_ROUTE_ZONE:HasArrived( ProcessUnit ) + + if ProcessUnit:IsInZone( self.TargetZone ) then + local RouteText = ProcessUnit:GetCallsign() .. ": You have arrived within the zone!" + MESSAGE:New( RouteText, self.DisplayTime, self.DisplayCategory ):ToGroup( ProcessUnit:GetGroup() ) + end + return ProcessUnit:IsInZone( self.TargetZone ) end diff --git a/Moose Development/Moose/Process/Smoke.lua b/Moose Development/Moose/Process/Smoke.lua index 0df9b4c93..69e926efb 100644 --- a/Moose Development/Moose/Process/Smoke.lua +++ b/Moose Development/Moose/Process/Smoke.lua @@ -144,13 +144,20 @@ do -- PROCESS_SMOKE_TARGETS_ZONE ClassName = "PROCESS_SMOKE_TARGETS_ZONE", } - function PROCESS_SMOKE_TARGETS_ZONE:ProcessStop() - self:E("ProcessStop Detailed") + 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 + -- @param Set#SET_UNIT TargetSetUnit + -- @param Zone#ZONE_BASE TargetZone + function PROCESS_SMOKE_TARGETS_ZONE:Template( TargetSetUnit, TargetZone ) + return { self, arg } + 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 diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index 62bc19ca8..9a5c812d8 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -9,8 +9,8 @@ -- * @{#TASK_BASE.AssignToGroup}():Assign a task to a group (of players). -- * @{#TASK_BASE.AddProcess}():Add a @{Process} to a task. -- * @{#TASK_BASE.RemoveProcesses}():Remove a running @{Process} from a running task. --- * @{#TASK_BASE.AddStateMachine}():Add a @{StateMachine} to a task. --- * @{#TASK_BASE.RemoveStateMachines}():Remove @{StateMachine}s from a task. +-- * @{#TASK_BASE.SetStateMachine}():Set a @{StateMachine} to a task. +-- * @{#TASK_BASE.RemoveStateMachine}():Remove @{StateMachine} from a task. -- * @{#TASK_BASE.HasStateMachine}():Enquire if the task has a @{StateMachine} -- * @{#TASK_BASE.AssignToUnit}(): Assign a task to a unit. (Needs to be implemented in the derived classes from @{#TASK_BASE}. -- * @{#TASK_BASE.UnAssignFromUnit}(): Unassign the task from a unit. @@ -69,13 +69,13 @@ TASK_BASE = { --- Instantiates a new TASK_BASE. Should never be used. Interface Class. -- @param #TASK_BASE self --- @param Mission#MISSION The mission wherein the Task is registered. --- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned. +-- @param Mission#MISSION Mission The mission wherein the Task is registered. +-- @param Set#SET_GROUP SetGroupAssign The set of groups for which the Task can be assigned. -- @param #string TaskName The name of the Task -- @param #string TaskType The type of the Task -- @param #string TaskCategory The category of the Task (A2G, A2A, Transport, ... ) -- @return #TASK_BASE self -function TASK_BASE:New( Mission, SetGroup, TaskName, TaskType, TaskCategory ) +function TASK_BASE:New( Mission, SetGroupAssign, TaskName, TaskType, TaskCategory ) local self = BASE:Inherit( self, BASE:New() ) self:E( "New TASK " .. TaskName ) @@ -84,7 +84,7 @@ function TASK_BASE:New( Mission, SetGroup, TaskName, TaskType, TaskCategory ) self.Fsm = {} self.Mission = Mission - self.SetGroup = SetGroup + self.SetGroup = SetGroupAssign self:SetCategory( TaskCategory ) self:SetType( TaskType ) @@ -92,6 +92,8 @@ function TASK_BASE:New( Mission, SetGroup, TaskName, TaskType, TaskCategory ) self:SetID( Mission:GetNextTaskID( self ) ) -- The Mission orchestrates the task sequences .. self.TaskBriefing = "You are assigned to the task: " .. self.TaskName .. "." + + self.FsmTemplate = self.FsmTemplate or STATEMACHINE_TASK:New( {}, self ) return self end @@ -109,6 +111,10 @@ function TASK_BASE:CleanUp() return nil end +function TASK_BASE:GetFsmTemplate() + + return self.FsmTemplate +end --- Assign the @{Task}to a @{Group}. -- @param #TASK_BASE self @@ -128,6 +134,7 @@ function TASK_BASE:AssignToGroup( TaskGroup ) for UnitID, UnitData in pairs( TaskUnits ) do local TaskUnit = UnitData -- Unit#UNIT local PlayerName = TaskUnit:GetPlayerName() + self:E(PlayerName) if PlayerName ~= nil or PlayerName ~= "" then self:AssignToUnit( TaskUnit ) end @@ -136,6 +143,65 @@ function TASK_BASE:AssignToGroup( TaskGroup ) return self end +--- Assign the @{Task} to an alive @{Unit}. +-- @param #TASK_BASE self +-- @param Unit#UNIT TaskUnit +-- @return #TASK_BASE self +function TASK_BASE:AssignToUnit( TaskUnit ) + self:F( TaskUnit:GetName() ) + + -- Copy the FsmTemplate, which is not assigned to a Unit. + -- Assign the FsmTemplate to the TaskUnit. + local FsmTemplate = self:GetFsmTemplate() + local FsmUnit = UTILS.DeepCopy( FsmTemplate ) + FsmUnit:Assign( self, TaskUnit ) + + -- Assign each FsmSub in FsmUnit to the TaskUnit. + -- (This is not done during the copy). + for FsmSubID, FsmSub in ipairs( FsmUnit:GetSubs() ) do + self:E( { "Sub ID", FsmSub:GetClassNameAndID() } ) + FsmSub:Assign( self, TaskUnit ) + end + + +-- for TransitionID, TransitionTemplate in ipairs( self.TransitionTemplates ) do +-- self:E( TransitionTemplate ) +-- FSM:AddTransition( TransitionTemplate.From, TransitionTemplate.Event, TransitionTemplate.To ) +-- end + + -- Copy each ProcessTemplate for the TaskUnit that is alive, as set as a template at the Parent. + -- Each Process will start From a state, upon a fired Event. + -- Upon finalization of the Process, the ReturnEvents contain for which Return state which Event of the Parent needs to be fired. + -- The Return state of the Process is transferred to the Parent. +-- for ProcessID, ProcessTemplate in ipairs( self.ProcessTemplates ) do +-- FSM:AddProcess( ProcessTemplate.From, ProcessTemplate.Event, Process, ProcessTemplate.ReturnEvents ) +-- self:E( { "Process ID", Process:GetClassNameAndID() } ) +-- Process:Assign( self, TaskUnit ) +-- end + + FsmUnit:SetInitialState( "Planned" ) + FsmUnit:Accept() -- Each Task needs to start with an Accept event to start the flow. + + return self +end + +--- UnAssign the @{Task} from an alive @{Unit}. +-- @param #TASK_BASE self +-- @param Unit#UNIT TaskUnit +-- @return #TASK_BASE self +function TASK_BASE:UnAssignFromUnit( TaskUnitName ) + self:F( TaskUnitName ) + + if self:HasStateMachine( TaskUnitName ) == true then + self:E("RemoveStateMachines") + self:RemoveStateMachine( TaskUnitName ) + end + + return self +end + + + --- Send the briefng message of the @{Task} to the assigned @{Group}s. -- @param #TASK_BASE self function TASK_BASE:SendBriefingToAssignedGroups() @@ -186,33 +252,6 @@ function TASK_BASE:IsAssignedToGroup( TaskGroup ) return false end ---- Assign the @{Task} to an alive @{Unit}. --- @param #TASK_BASE self --- @param Unit#UNIT TaskUnit --- @return #TASK_BASE self -function TASK_BASE:AssignToUnit( TaskUnit ) - self:F( TaskUnit:GetName() ) - - return nil -end - ---- UnAssign the @{Task} from an alive @{Unit}. --- @param #TASK_BASE self --- @param Unit#UNIT TaskUnit --- @return #TASK_BASE self -function TASK_BASE:UnAssignFromUnit( TaskUnitName ) - self:F( TaskUnitName ) - - if self:HasStateMachine( TaskUnitName ) == true then - self:E("RemoveStateMachines") - self:RemoveStateMachines( TaskUnitName ) - self:E("RemoveProcesses") - self:RemoveProcesses( TaskUnitName ) - end - - return self -end - --- Set the menu options of the @{Task} to all the groups in the SetGroup. -- @param #TASK_BASE self -- @return #TASK_BASE self @@ -406,31 +445,6 @@ function TASK_BASE:GetTaskName() end ---- This is the key worker function for the class. Instantiate a new Process based on the ProcessName to @{Task} and assign it to the ProcessUnit. --- @param #TASK_BASE self --- @param Unit#UNIT ProcessUnit The unit to which the process should be assigned. --- @param #string ProcessName The name of the Process. --- @return Process#PROCESS The Process that was added. -function TASK_BASE:AssignProcess( ProcessUnit, ProcessName ) - self:F( { ProcessName } ) - local ProcessUnitName = ProcessUnit:GetName() - - -- Create the Process instance base on the ProcessClasses collection assigned to the Task - local ProcessTemplate, ProcessArguments - ProcessTemplate = self:GetProcessTemplate( ProcessName ) - - self:E( "Deepcopy" ) - -- This statement copies the process template assigned to the task and creates a new process. - local Process = UTILS.DeepCopy( ProcessTemplate ) -- Fsm.Process#PROCESS - Process:Assign( self, ProcessUnit ) - - self.Processes = self.Processes or {} - self.Processes[ProcessUnitName] = self.Processes[ProcessUnitName] or {} - - self.Processes[ProcessUnitName][ProcessName] = Process - - return Process -end --- Get the default or currently assigned @{Process} template with key ProcessName. @@ -445,35 +459,6 @@ function TASK_BASE:GetProcessTemplate( ProcessName ) end ---- Set the default @{Process} template with key ProcessName providing the ProcessClass and the process object when it is assigned to a @{Controllable} by the task. --- @param #TASK_BASE self --- @param #string ProcessName --- @param Process#PROCESS ProcessTemplate --- @return Process#PROCESS -function TASK_BASE:SetProcessTemplate( ProcessName, ProcessTemplate ) - - self.ProcessClasses[ProcessName] = ProcessTemplate - - return ProcessTemplate -end - - ---- Remove Processes from @{Task} with key @{Unit} --- @param #TASK_BASE self --- @param #string TaskUnitName --- @return #TASK_BASE self -function TASK_BASE:RemoveProcesses( TaskUnitName ) - self:E( TaskUnitName ) - - for ProcessID, ProcessData in pairs( self.Processes[TaskUnitName] ) do - local Process = ProcessData -- Process.Process#PROCESS - Process:ProcessStop() - Process = nil - self.Processes[TaskUnitName][ProcessID] = nil - self:E( self.Processes[TaskUnitName][ProcessID] ) - end - self.Processes[TaskUnitName] = nil -end --- Fail processes from @{Task} with key @{Unit} -- @param #TASK_BASE self @@ -491,10 +476,10 @@ end -- @param #TASK_BASE self -- @param Unit#UNIT TaskUnit -- @return #TASK_BASE self -function TASK_BASE:AddStateMachine( TaskUnit, Fsm ) +function TASK_BASE:SetStateMachine( TaskUnit, Fsm ) local TaskUnitName = TaskUnit:GetName() - self.Fsm[TaskUnitName] = self.Fsm[TaskUnitName] or {} - self.Fsm[TaskUnitName][#self.Fsm[TaskUnitName]+1] = Fsm + self.Fsm[TaskUnitName] = Fsm + return Fsm end @@ -502,14 +487,10 @@ end -- @param #TASK_BASE self -- @param #string TaskUnitName -- @return #TASK_BASE self -function TASK_BASE:RemoveStateMachines( TaskUnitName ) +function TASK_BASE:RemoveStateMachine( TaskUnitName ) - for _, Fsm in pairs( self.Fsm[TaskUnitName] ) do - Fsm = nil - self.Fsm[TaskUnitName][_] = nil - self:E( self.Fsm[TaskUnitName][_] ) - end self.Fsm[TaskUnitName] = nil + collectgarbage() end --- Checks if there is a FiniteStateMachine assigned to @{Unit} for @{Task} @@ -875,7 +856,7 @@ function TASK_BASE:OnStateChange( TaskUnit, Fsm, Event, From, To ) MESSAGE:New( "Task " .. self.TaskName .. " : " .. Event .. " changed to state " .. To, 15 ):ToAll() end - self:E( { Event, From, To } ) + self:T2( { Event, From, To } ) self:SetState( self, "State", To ) if self.Scores[To] then diff --git a/Moose Development/Moose/Tasking/Task_SEAD.lua b/Moose Development/Moose/Tasking/Task_SEAD.lua index bb2669b5c..bd75b717f 100644 --- a/Moose Development/Moose/Tasking/Task_SEAD.lua +++ b/Moose Development/Moose/Tasking/Task_SEAD.lua @@ -67,8 +67,7 @@ do -- TASK_SEAD return nil end - - + --- Assign the @{Task} to a @{Unit}. -- @param #TASK_SEAD self @@ -85,7 +84,7 @@ do -- TASK_SEAD local FSMT = { initial = 'None', events = { - { name = 'Next', from = 'None', to = 'Planned' }, + { name = 'Start', from = 'None', to = 'Planned' }, { name = 'Next', from = 'Planned', to = 'Assigned' }, { name = 'Reject', from = 'Planned', to = 'Rejected' }, { name = 'Next', from = 'Assigned', to = 'Success' }, diff --git a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua index 748afbd32..c56db1af5 100644 --- a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua +++ b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua @@ -1,4 +1,6 @@ +env.info( "Lua Version = " .. _VERSION ) + local Mission = MISSION:New( 'SEAD Targets', "Strategic", "SEAD the enemy", coalition.side.RED ) local Scoring = SCORING:New( "SEAD" ) @@ -9,23 +11,31 @@ local TargetSet = SET_UNIT:New():FilterPrefixes( "US Hawk SR" ):FilterOnce() local TargetZone = ZONE:New( "Target Zone" ) -local TaskSEAD = TASK_SEAD - :New( Mission, SEADSet, "SEAD Radars", TargetSet, TargetZone ) +local TaskSEAD = TASK_BASE:New( Mission, SEADSet, "SEAD Radars", "A2G", "SEAD" ) -- Tasking.Task#TASK_BASE + --:New( Mission, SEADSet, "SEAD Radars", TargetSet, TargetZone ) -TaskSEAD:AddScore( "Success", "Destroyed all target radars", 250 ) -TaskSEAD:AddScore( "Failed", "Failed to destroy all target radars", -100 ) +local FsmSEAD = TaskSEAD:GetFsmTemplate() -local AssignProcess = TaskSEAD:SetProcessTemplate( "ASSIGN", PROCESS_ASSIGN_MENU_ACCEPT:New( "SEAD", "Hello World" ) ) -AssignProcess:AddScore( TaskSEAD, "Assign", "You are assigned to the task", 10 ) +FsmSEAD:AddProcess( "Planned", "Accept", PROCESS_ASSIGN_ACCEPT:New( "SEAD the Area" ), { Assigned = "Route", Rejected = "Eject" } ) +FsmSEAD:AddProcess( "Assigned", "Route", PROCESS_ROUTE_ZONE:New( TargetZone, 3000 ), { Arrived = "Update" } ) +FsmSEAD:AddAction ( "Rejected", "Eject", "Planned" ) +FsmSEAD:AddAction ( "Arrived", "Update", "Updated" ) +FsmSEAD:AddProcess( "Updated", "Account", PROCESS_ACCOUNT_DEADS:New( TargetSet, "SEAD" ), { Destroyed = "Success" } ) +FsmSEAD:AddProcess( "Updated", "Smoke", PROCESS_SMOKE_TARGETS_ZONE:New( TargetSet, TargetZone ) ) +FsmSEAD:AddAction ( "Destroyed", "Success", "Success" ) +FsmSEAD:AddAction ( "Failed", "Fail", "Failed" ) -local AccountProcess = TaskSEAD:SetProcessTemplate( "ACCOUNT", PROCESS_ACCOUNT_DEADS:New( TargetSet, "SEAD" ) ) -AccountProcess:AddScore( TaskSEAD, "Account", "destroyed a radar", 25 ) -AccountProcess:AddScore( TaskSEAD, "Failed", "failed to destroy a radar", -100 ) +--TaskSEAD:AddScoreTask( "Success", "Destroyed all target radars", 250 ) +--TaskSEAD:AddScoreTask( "Failed", "Failed to destroy all target radars", -100 ) +--TaskSEAD:AddScoreProcess( "Account", "Account", "destroyed a radar", 25 ) +--TaskSEAD:AddScoreProcess( "Smoke", "Failed", "failed to destroy a radar", -100 ) ---local SmokeProcess = TaskSEAD:SetProcessTemplate( "SMOKE", PROCESS_SMOKE_TARGETS_ZONE:New( TargetSet, TargetZone ) ) ---SmokeProcess:SetAttackGroup( GROUP:FindByName( "SmokeGroup" ), "Watchdog" ) ---SmokeProcess:AddScore( TaskSEAD, "Account", "destroyed a radar", 25 ) ---SmokeProcess:AddScore( TaskSEAD, "Failed", "failed to destroy a radar", -100 ) +function FsmSEAD:onenterUpdated( TaskUnit ) + TaskSEAD:Account() + TaskSEAD:Smoke() +end +-- Needs to be checked, should not be necessary ... TaskSEAD:AssignToGroup( SEADSet:Get( "Test SEAD" ) ) +Mission:AddTask( TaskSEAD ) diff --git a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.miz b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.miz index 208db4352a7dd1e4fd5ac7b8e3c942ff13e12b2b..ef898521d5f7e903f9c38c0c61926728244a9934 100644 GIT binary patch delta 13285 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 O5BX1Wf!^f5z5fN%T65|E delta 13554 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

=SnUV2k|0p}#-R9Y$-vM`RcwJ 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 Nkd`vr7X~e$J^;;VWfuSd delta 17169 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