mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Updated documentation
This commit is contained in:
@@ -46,227 +46,14 @@
|
||||
-- I've reworked this development (taken the concept), and created a **hierarchical state machine** out of it, embedded within the DCS simulator.
|
||||
-- Additionally, I've added extendability and created an API that allows seamless FSM implementation.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#FSM} class, extends @{Base#BASE}
|
||||
--
|
||||
-- 
|
||||
-- The following derived classes are available in the MOOSE framework, that implement a specialised form of a FSM:
|
||||
--
|
||||
-- The FSM class is the base class of all FSM\_ derived classes. It implements the main functionality to define and execute Finite State Machines.
|
||||
-- The derived FSM\_ classes extend the Finite State Machine functionality to run a workflow process for a specific purpose or component.
|
||||
-- * @{#FSM_TASK}: Models Finite State Machines for @{Task}s.
|
||||
-- * @{#FSM_PROCESS}: Models Finite State Machines for @{Task} actions, which control @{Client}s.
|
||||
-- * @{#FSM_CONTROLLABLE}: Models Finite State Machines for @{Controllable}s, which are @{Group}s, @{Unit}s, @{Client}s.
|
||||
-- * @{#FSM_SET}: Models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
|
||||
-- for multiple objects or the position of the state machine in the process.
|
||||
--
|
||||
-- Finite State Machines have **Transition Rules**, **Transition Handlers** and **Event Triggers**.
|
||||
--
|
||||
-- The **Transition Rules** define the "Process Flow Boundaries", that is,
|
||||
-- the path that can be followed hopping from state to state upon triggered events.
|
||||
-- If an event is triggered, and there is no valid path found for that event,
|
||||
-- an error will be raised and the FSM will stop functioning.
|
||||
--
|
||||
-- The **Transition Handlers** are special methods that can be defined by the mission designer, following a defined syntax.
|
||||
-- If the FSM object finds a method of such a handler, then the method will be called by the FSM, passing specific parameters.
|
||||
-- The method can then define its own custom logic to implement the FSM workflow, and to conduct other actions.
|
||||
--
|
||||
-- The **Event Triggers** are methods that are defined by the FSM, which the mission designer can use to implement the workflow.
|
||||
-- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine.
|
||||
--
|
||||
-- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation.
|
||||
-- The below documentation has a seperate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
|
||||
--
|
||||
-- ## 1.1) FSM Linear Transitions
|
||||
--
|
||||
-- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**.
|
||||
-- The Lineair transition rule evaluation will always be done from the **current state** of the FSM.
|
||||
-- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop.
|
||||
--
|
||||
-- ### 1.1.1) FSM Transition Rules
|
||||
--
|
||||
-- The FSM has transition rules that it follows and validates, as it walks the process.
|
||||
-- These rules define when an FSM can transition from a specific state towards an other specific state upon a triggered event.
|
||||
--
|
||||
-- The method @{#FSM.AddTransition}() specifies a new possible Transition Rule for the FSM.
|
||||
--
|
||||
-- The initial state can be defined using the method @{#FSM.SetStartState}(). The default start state of an FSM is "None".
|
||||
--
|
||||
-- Find below an example of a Linear Transition Rule definition for an FSM.
|
||||
--
|
||||
-- local Fsm3Switch = FSM:New() -- #FsmDemo
|
||||
-- FsmSwitch:SetStartState( "Off" )
|
||||
-- FsmSwitch:AddTransition( "Off", "SwitchOn", "On" )
|
||||
-- FsmSwitch:AddTransition( "Off", "SwitchMiddle", "Middle" )
|
||||
-- FsmSwitch:AddTransition( "On", "SwitchOff", "Off" )
|
||||
-- FsmSwitch:AddTransition( "Middle", "SwitchOff", "Off" )
|
||||
--
|
||||
-- The above code snippet models a 3-way switch Linear Transition:
|
||||
--
|
||||
-- * It can be switched **On** by triggering event **SwitchOn**.
|
||||
-- * It can be switched to the **Middle** position, by triggering event **SwitchMiddle**.
|
||||
-- * It can be switched **Off** by triggering event **SwitchOff**.
|
||||
-- * Note that once the Switch is **On** or **Middle**, it can only be switched **Off**.
|
||||
--
|
||||
-- ### Some additional comments:
|
||||
--
|
||||
-- Note that Linear Transition Rules **can be declared in a few variations**:
|
||||
--
|
||||
-- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**.
|
||||
-- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM.
|
||||
--
|
||||
-- The below code snippet shows how the two last lines can be rewritten and consensed.
|
||||
--
|
||||
-- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" )
|
||||
--
|
||||
-- ### 1.1.2) Transition Handling
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An FSM transitions in **4 moments** when an Event is being triggered and processed.
|
||||
-- The mission designer can define for each moment specific logic within methods implementations following a defined API syntax.
|
||||
-- These methods define the flow of the FSM process; because in those methods the FSM Internal Events will be triggered.
|
||||
--
|
||||
-- * To handle **State** transition moments, create methods starting with OnLeave or OnEnter concatenated with the State name.
|
||||
-- * To handle **Event** transition moments, create methods starting with OnBefore or OnAfter concatenated with the Event name.
|
||||
--
|
||||
-- **The OnLeave and OnBefore transition methods may return false, which will cancel the transition!**
|
||||
--
|
||||
-- Transition Handler methods need to follow the above specified naming convention, but are also passed parameters from the FSM.
|
||||
-- These parameters are on the correct order: From, Event, To:
|
||||
--
|
||||
-- * From = A string containing the From state.
|
||||
-- * Event = A string containing the Event name that was triggered.
|
||||
-- * To = A string containing the To state.
|
||||
--
|
||||
-- On top, each of these methods can have a variable amount of parameters passed. See the example in section [1.1.3](#1.1.3\)-event-triggers).
|
||||
--
|
||||
-- ### 1.1.3) Event Triggers
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The FSM creates for each Event two **Event Trigger methods**.
|
||||
-- There are two modes how Events can be triggered, which is **synchronous** and **asynchronous**:
|
||||
--
|
||||
-- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**.
|
||||
-- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__.
|
||||
--
|
||||
-- The destinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
|
||||
-- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact.
|
||||
--
|
||||
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
||||
--
|
||||
-- function FSM:OnAfterEvent( From, Event, To, Amount )
|
||||
-- self:T( { Amount = Amount } )
|
||||
-- end
|
||||
--
|
||||
-- local Amount = 1
|
||||
-- FSM:__Event( 5, Amount )
|
||||
--
|
||||
-- Amount = Amount + 1
|
||||
-- FSM:Event( Text, Amount )
|
||||
--
|
||||
-- In this example, the **:OnAfterEvent**() Transition Handler implementation will get called when **Event** is being triggered.
|
||||
-- Before we go into more detail, let's look at the last 4 lines of the example.
|
||||
-- The last line triggers synchronously the **Event**, and passes Amount as a parameter.
|
||||
-- The 3rd last line of the example triggers asynchronously **Event**.
|
||||
-- Event will be processed after 5 seconds, and Amount is given as a parameter.
|
||||
--
|
||||
-- The output of this little code fragment will be:
|
||||
--
|
||||
-- * Amount = 2
|
||||
-- * Amount = 2
|
||||
--
|
||||
-- Because ... When Event was asynchronously processed after 5 seconds, Amount was set to 2. So be careful when processing and passing values and objects in asynchronous processing!
|
||||
--
|
||||
-- ### 1.1.4) Linear Transition Example
|
||||
--
|
||||
-- This example is fully implemented in the MOOSE test mission on GITHUB: [FSM-100 - Transition Explanation](https://github.com/FlightControl-Master/MOOSE/blob/master/Moose%20Test%20Missions/FSM%20-%20Finite%20State%20Machine/FSM-100%20-%20Transition%20Explanation/FSM-100%20-%20Transition%20Explanation.lua)
|
||||
--
|
||||
-- It models a unit standing still near Batumi, and flaring every 5 seconds while switching between a Green flare and a Red flare.
|
||||
-- The purpose of this example is not to show how exciting flaring is, but it demonstrates how a Linear Transition FSM can be build.
|
||||
-- Have a look at the source code. The source code is also further explained below in this section.
|
||||
--
|
||||
-- The example creates a new FsmDemo object from class FSM.
|
||||
-- It will set the start state of FsmDemo to state **Green**.
|
||||
-- Two Linear Transition Rules are created, where upon the event **Switch**,
|
||||
-- the FsmDemo will transition from state **Green** to **Red** and from **Red** back to **Green**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- local FsmDemo = FSM:New() -- #FsmDemo
|
||||
-- FsmDemo:SetStartState( "Green" )
|
||||
-- FsmDemo:AddTransition( "Green", "Switch", "Red" )
|
||||
-- FsmDemo:AddTransition( "Red", "Switch", "Green" )
|
||||
--
|
||||
-- In the above example, the FsmDemo could flare every 5 seconds a Green or a Red flare into the air.
|
||||
-- The next code implements this through the event handling method **OnAfterSwitch**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
-- else
|
||||
-- if From == "Red" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Red)
|
||||
-- end
|
||||
-- end
|
||||
-- self:__Switch( 5, FsmUnit ) -- Trigger the next Switch event to happen in 5 seconds.
|
||||
-- end
|
||||
--
|
||||
-- FsmDemo:__Switch( 5, FsmUnit ) -- Trigger the first Switch event to happen in 5 seconds.
|
||||
--
|
||||
-- The OnAfterSwitch implements a loop. The last line of the code fragment triggers the Switch Event within 5 seconds.
|
||||
-- Upon the event execution (after 5 seconds), the OnAfterSwitch method is called of FsmDemo (cfr. the double point notation!!! ":").
|
||||
-- The OnAfterSwitch method receives from the FSM the 3 transition parameter details ( From, Event, To ),
|
||||
-- and one additional parameter that was given when the event was triggered, which is in this case the Unit that is used within OnSwitchAfter.
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
--
|
||||
-- For debugging reasons the received parameters are traced within the DCS.log.
|
||||
--
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- The method will check if the From state received is either "Green" or "Red" and will flare the respective color from the FsmUnit.
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
-- else
|
||||
-- if From == "Red" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Red)
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- It is important that the Switch event is again triggered, otherwise, the FsmDemo would stop working after having the first Event being handled.
|
||||
--
|
||||
-- FsmDemo:__Switch( 5, FsmUnit ) -- Trigger the next Switch event to happen in 5 seconds.
|
||||
--
|
||||
-- The below code fragment extends the FsmDemo, demonstrating multiple **From states declared as a table**, adding a **Linear Transition Rule**.
|
||||
-- The new event **Stop** will cancel the Switching process.
|
||||
-- The transition for event Stop can be executed if the current state of the FSM is either "Red" or "Green".
|
||||
--
|
||||
-- local FsmDemo = FSM:New() -- #FsmDemo
|
||||
-- FsmDemo:SetStartState( "Green" )
|
||||
-- FsmDemo:AddTransition( "Green", "Switch", "Red" )
|
||||
-- FsmDemo:AddTransition( "Red", "Switch", "Green" )
|
||||
-- FsmDemo:AddTransition( { "Red", "Green" }, "Stop", "Stopped" )
|
||||
--
|
||||
-- The transition for event Stop can also be simplified, as any current state of the FSM is valid.
|
||||
--
|
||||
-- FsmDemo:AddTransition( "*", "Stop", "Stopped" )
|
||||
--
|
||||
-- So... When FsmDemo:Stop() is being triggered, the state of FsmDemo will transition from Red or Green to Stopped.
|
||||
-- And there is no transition handling method defined for that transition, thus, no new event is being triggered causing the FsmDemo process flow to halt.
|
||||
--
|
||||
-- ## 1.5) FSM Hierarchical Transitions
|
||||
--
|
||||
-- Hierarchical Transitions allow to re-use readily available and implemented FSMs.
|
||||
-- This becomes in very useful for mission building, where mission designers build complex processes and workflows,
|
||||
-- combining smaller FSMs to one single FSM.
|
||||
--
|
||||
-- The FSM can embed **Sub-FSMs** that will execute and return **multiple possible Return (End) States**.
|
||||
-- Depending upon **which state is returned**, the main FSM can continue the flow **triggering specific events**.
|
||||
--
|
||||
-- The method @{#FSM.AddProcess}() adds a new Sub-FSM to the FSM.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
@@ -300,8 +87,233 @@
|
||||
do -- FSM
|
||||
|
||||
--- FSM class
|
||||
-- @type FSM
|
||||
--- @type FSM
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
|
||||
--- # 1) FSM class, extends @{Base#BASE}
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The FSM class is the base class of all FSM\_ derived classes. It implements the main functionality to define and execute Finite State Machines.
|
||||
-- The derived FSM\_ classes extend the Finite State Machine functionality to run a workflow process for a specific purpose or component.
|
||||
--
|
||||
-- Finite State Machines have **Transition Rules**, **Transition Handlers** and **Event Triggers**.
|
||||
--
|
||||
-- The **Transition Rules** define the "Process Flow Boundaries", that is,
|
||||
-- the path that can be followed hopping from state to state upon triggered events.
|
||||
-- If an event is triggered, and there is no valid path found for that event,
|
||||
-- an error will be raised and the FSM will stop functioning.
|
||||
--
|
||||
-- The **Transition Handlers** are special methods that can be defined by the mission designer, following a defined syntax.
|
||||
-- If the FSM object finds a method of such a handler, then the method will be called by the FSM, passing specific parameters.
|
||||
-- The method can then define its own custom logic to implement the FSM workflow, and to conduct other actions.
|
||||
--
|
||||
-- The **Event Triggers** are methods that are defined by the FSM, which the mission designer can use to implement the workflow.
|
||||
-- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine.
|
||||
--
|
||||
-- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation.
|
||||
-- The below documentation has a seperate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
|
||||
--
|
||||
-- ## 1.1) FSM Linear Transitions
|
||||
--
|
||||
-- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**.
|
||||
-- The Lineair transition rule evaluation will always be done from the **current state** of the FSM.
|
||||
-- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop.
|
||||
--
|
||||
-- ### 1.1.1) FSM Transition Rules
|
||||
--
|
||||
-- The FSM has transition rules that it follows and validates, as it walks the process.
|
||||
-- These rules define when an FSM can transition from a specific state towards an other specific state upon a triggered event.
|
||||
--
|
||||
-- The method @{#FSM.AddTransition}() specifies a new possible Transition Rule for the FSM.
|
||||
--
|
||||
-- The initial state can be defined using the method @{#FSM.SetStartState}(). The default start state of an FSM is "None".
|
||||
--
|
||||
-- Find below an example of a Linear Transition Rule definition for an FSM.
|
||||
--
|
||||
-- local Fsm3Switch = FSM:New() -- #FsmDemo
|
||||
-- FsmSwitch:SetStartState( "Off" )
|
||||
-- FsmSwitch:AddTransition( "Off", "SwitchOn", "On" )
|
||||
-- FsmSwitch:AddTransition( "Off", "SwitchMiddle", "Middle" )
|
||||
-- FsmSwitch:AddTransition( "On", "SwitchOff", "Off" )
|
||||
-- FsmSwitch:AddTransition( "Middle", "SwitchOff", "Off" )
|
||||
--
|
||||
-- The above code snippet models a 3-way switch Linear Transition:
|
||||
--
|
||||
-- * It can be switched **On** by triggering event **SwitchOn**.
|
||||
-- * It can be switched to the **Middle** position, by triggering event **SwitchMiddle**.
|
||||
-- * It can be switched **Off** by triggering event **SwitchOff**.
|
||||
-- * Note that once the Switch is **On** or **Middle**, it can only be switched **Off**.
|
||||
--
|
||||
-- ### Some additional comments:
|
||||
--
|
||||
-- Note that Linear Transition Rules **can be declared in a few variations**:
|
||||
--
|
||||
-- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**.
|
||||
-- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM.
|
||||
--
|
||||
-- The below code snippet shows how the two last lines can be rewritten and consensed.
|
||||
--
|
||||
-- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" )
|
||||
--
|
||||
-- ### 1.1.2) Transition Handling
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An FSM transitions in **4 moments** when an Event is being triggered and processed.
|
||||
-- The mission designer can define for each moment specific logic within methods implementations following a defined API syntax.
|
||||
-- These methods define the flow of the FSM process; because in those methods the FSM Internal Events will be triggered.
|
||||
--
|
||||
-- * To handle **State** transition moments, create methods starting with OnLeave or OnEnter concatenated with the State name.
|
||||
-- * To handle **Event** transition moments, create methods starting with OnBefore or OnAfter concatenated with the Event name.
|
||||
--
|
||||
-- **The OnLeave and OnBefore transition methods may return false, which will cancel the transition!**
|
||||
--
|
||||
-- Transition Handler methods need to follow the above specified naming convention, but are also passed parameters from the FSM.
|
||||
-- These parameters are on the correct order: From, Event, To:
|
||||
--
|
||||
-- * From = A string containing the From state.
|
||||
-- * Event = A string containing the Event name that was triggered.
|
||||
-- * To = A string containing the To state.
|
||||
--
|
||||
-- On top, each of these methods can have a variable amount of parameters passed. See the example in section [1.1.3](#1.1.3\)-event-triggers).
|
||||
--
|
||||
-- ### 1.1.3) Event Triggers
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The FSM creates for each Event two **Event Trigger methods**.
|
||||
-- There are two modes how Events can be triggered, which is **synchronous** and **asynchronous**:
|
||||
--
|
||||
-- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**.
|
||||
-- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__.
|
||||
--
|
||||
-- The destinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
|
||||
-- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact.
|
||||
--
|
||||
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
||||
--
|
||||
-- function FSM:OnAfterEvent( From, Event, To, Amount )
|
||||
-- self:T( { Amount = Amount } )
|
||||
-- end
|
||||
--
|
||||
-- local Amount = 1
|
||||
-- FSM:__Event( 5, Amount )
|
||||
--
|
||||
-- Amount = Amount + 1
|
||||
-- FSM:Event( Text, Amount )
|
||||
--
|
||||
-- In this example, the **:OnAfterEvent**() Transition Handler implementation will get called when **Event** is being triggered.
|
||||
-- Before we go into more detail, let's look at the last 4 lines of the example.
|
||||
-- The last line triggers synchronously the **Event**, and passes Amount as a parameter.
|
||||
-- The 3rd last line of the example triggers asynchronously **Event**.
|
||||
-- Event will be processed after 5 seconds, and Amount is given as a parameter.
|
||||
--
|
||||
-- The output of this little code fragment will be:
|
||||
--
|
||||
-- * Amount = 2
|
||||
-- * Amount = 2
|
||||
--
|
||||
-- Because ... When Event was asynchronously processed after 5 seconds, Amount was set to 2. So be careful when processing and passing values and objects in asynchronous processing!
|
||||
--
|
||||
-- ### 1.1.4) Linear Transition Example
|
||||
--
|
||||
-- This example is fully implemented in the MOOSE test mission on GITHUB: [FSM-100 - Transition Explanation](https://github.com/FlightControl-Master/MOOSE/blob/master/Moose%20Test%20Missions/FSM%20-%20Finite%20State%20Machine/FSM-100%20-%20Transition%20Explanation/FSM-100%20-%20Transition%20Explanation.lua)
|
||||
--
|
||||
-- It models a unit standing still near Batumi, and flaring every 5 seconds while switching between a Green flare and a Red flare.
|
||||
-- The purpose of this example is not to show how exciting flaring is, but it demonstrates how a Linear Transition FSM can be build.
|
||||
-- Have a look at the source code. The source code is also further explained below in this section.
|
||||
--
|
||||
-- The example creates a new FsmDemo object from class FSM.
|
||||
-- It will set the start state of FsmDemo to state **Green**.
|
||||
-- Two Linear Transition Rules are created, where upon the event **Switch**,
|
||||
-- the FsmDemo will transition from state **Green** to **Red** and from **Red** back to **Green**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- local FsmDemo = FSM:New() -- #FsmDemo
|
||||
-- FsmDemo:SetStartState( "Green" )
|
||||
-- FsmDemo:AddTransition( "Green", "Switch", "Red" )
|
||||
-- FsmDemo:AddTransition( "Red", "Switch", "Green" )
|
||||
--
|
||||
-- In the above example, the FsmDemo could flare every 5 seconds a Green or a Red flare into the air.
|
||||
-- The next code implements this through the event handling method **OnAfterSwitch**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
-- else
|
||||
-- if From == "Red" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Red)
|
||||
-- end
|
||||
-- end
|
||||
-- self:__Switch( 5, FsmUnit ) -- Trigger the next Switch event to happen in 5 seconds.
|
||||
-- end
|
||||
--
|
||||
-- FsmDemo:__Switch( 5, FsmUnit ) -- Trigger the first Switch event to happen in 5 seconds.
|
||||
--
|
||||
-- The OnAfterSwitch implements a loop. The last line of the code fragment triggers the Switch Event within 5 seconds.
|
||||
-- Upon the event execution (after 5 seconds), the OnAfterSwitch method is called of FsmDemo (cfr. the double point notation!!! ":").
|
||||
-- The OnAfterSwitch method receives from the FSM the 3 transition parameter details ( From, Event, To ),
|
||||
-- and one additional parameter that was given when the event was triggered, which is in this case the Unit that is used within OnSwitchAfter.
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
--
|
||||
-- For debugging reasons the received parameters are traced within the DCS.log.
|
||||
--
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- The method will check if the From state received is either "Green" or "Red" and will flare the respective color from the FsmUnit.
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
-- else
|
||||
-- if From == "Red" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Red)
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- It is important that the Switch event is again triggered, otherwise, the FsmDemo would stop working after having the first Event being handled.
|
||||
--
|
||||
-- FsmDemo:__Switch( 5, FsmUnit ) -- Trigger the next Switch event to happen in 5 seconds.
|
||||
--
|
||||
-- The below code fragment extends the FsmDemo, demonstrating multiple **From states declared as a table**, adding a **Linear Transition Rule**.
|
||||
-- The new event **Stop** will cancel the Switching process.
|
||||
-- The transition for event Stop can be executed if the current state of the FSM is either "Red" or "Green".
|
||||
--
|
||||
-- local FsmDemo = FSM:New() -- #FsmDemo
|
||||
-- FsmDemo:SetStartState( "Green" )
|
||||
-- FsmDemo:AddTransition( "Green", "Switch", "Red" )
|
||||
-- FsmDemo:AddTransition( "Red", "Switch", "Green" )
|
||||
-- FsmDemo:AddTransition( { "Red", "Green" }, "Stop", "Stopped" )
|
||||
--
|
||||
-- The transition for event Stop can also be simplified, as any current state of the FSM is valid.
|
||||
--
|
||||
-- FsmDemo:AddTransition( "*", "Stop", "Stopped" )
|
||||
--
|
||||
-- So... When FsmDemo:Stop() is being triggered, the state of FsmDemo will transition from Red or Green to Stopped.
|
||||
-- And there is no transition handling method defined for that transition, thus, no new event is being triggered causing the FsmDemo process flow to halt.
|
||||
--
|
||||
-- ## 1.5) FSM Hierarchical Transitions
|
||||
--
|
||||
-- Hierarchical Transitions allow to re-use readily available and implemented FSMs.
|
||||
-- This becomes in very useful for mission building, where mission designers build complex processes and workflows,
|
||||
-- combining smaller FSMs to one single FSM.
|
||||
--
|
||||
-- The FSM can embed **Sub-FSMs** that will execute and return **multiple possible Return (End) States**.
|
||||
-- Depending upon **which state is returned**, the main FSM can continue the flow **triggering specific events**.
|
||||
--
|
||||
-- The method @{#FSM.AddProcess}() adds a new Sub-FSM to the FSM.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #FSM FSM
|
||||
--
|
||||
FSM = {
|
||||
ClassName = "FSM",
|
||||
}
|
||||
@@ -720,10 +732,18 @@ end
|
||||
|
||||
do -- FSM_CONTROLLABLE
|
||||
|
||||
--- FSM_CONTROLLABLE class
|
||||
-- @type FSM_CONTROLLABLE
|
||||
--- @type FSM_CONTROLLABLE
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE Controllable
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- # FSM_CONTROLLABLE, extends @{#FSM}
|
||||
--
|
||||
-- FSM_CONTROLLABLE class models Finite State Machines for @{Controllable}s, which are @{Group}s, @{Unit}s, @{Client}s.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #FSM_CONTROLLABLE FSM_CONTROLLABLE
|
||||
--
|
||||
FSM_CONTROLLABLE = {
|
||||
ClassName = "FSM_CONTROLLABLE",
|
||||
}
|
||||
@@ -844,10 +864,19 @@ end
|
||||
|
||||
do -- FSM_PROCESS
|
||||
|
||||
--- FSM_PROCESS class
|
||||
-- @type FSM_PROCESS
|
||||
--- @type FSM_PROCESS
|
||||
-- @field Tasking.Task#TASK Task
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
|
||||
|
||||
--- # FSM_PROCESS, extends @{#FSM}
|
||||
--
|
||||
-- FSM_PROCESS class models Finite State Machines for @{Task} actions, which control @{Client}s.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #FSM_PROCESS FSM_PROCESS
|
||||
--
|
||||
FSM_PROCESS = {
|
||||
ClassName = "FSM_PROCESS",
|
||||
}
|
||||
@@ -1074,6 +1103,15 @@ do -- FSM_TASK
|
||||
-- @type FSM_TASK
|
||||
-- @field Tasking.Task#TASK Task
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- # FSM_TASK, extends @{#FSM}
|
||||
--
|
||||
-- FSM_TASK class models Finite State Machines for @{Task}s.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #FSM_TASK FSM_TASK
|
||||
--
|
||||
FSM_TASK = {
|
||||
ClassName = "FSM_TASK",
|
||||
}
|
||||
@@ -1109,6 +1147,17 @@ do -- FSM_SET
|
||||
-- @type FSM_SET
|
||||
-- @field Core.Set#SET_BASE Set
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
|
||||
--- # FSM_SET, extends @{#FSM}
|
||||
--
|
||||
-- FSM_SET class models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
|
||||
-- for multiple objects or the position of the state machine in the process.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #FSM_SET FSM_SET
|
||||
--
|
||||
FSM_SET = {
|
||||
ClassName = "FSM_SET",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user