mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Implemented event dispatching for GROUP
-- Created EVT-200 test mission -- Documentation
This commit is contained in:
parent
ef67c82c0f
commit
af85399975
@ -50,11 +50,14 @@
|
|||||||
--
|
--
|
||||||
-- * **None** ( Group ): The process is not started yet.
|
-- * **None** ( Group ): The process is not started yet.
|
||||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||||
-- * **Returning** ( Group ): The AI is returning to Base..
|
-- * **Returning** ( Group ): The AI is returning to Base.
|
||||||
|
-- * **Stopped** ( Group ): The process is stopped.
|
||||||
|
-- * **Crashed** ( Group ): The AI has crashed or is dead.
|
||||||
--
|
--
|
||||||
-- ### 1.2.2) AI_PATROL_ZONE Events
|
-- ### 1.2.2) AI_PATROL_ZONE Events
|
||||||
--
|
--
|
||||||
-- * **Start** ( Group ): Start the process.
|
-- * **Start** ( Group ): Start the process.
|
||||||
|
-- * **Stop** ( Group ): Stop the process.
|
||||||
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
||||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||||
|
|||||||
@ -165,7 +165,9 @@
|
|||||||
--
|
--
|
||||||
-- Hereby the change log:
|
-- Hereby the change log:
|
||||||
--
|
--
|
||||||
-- * 2016-02-07: Did a complete revision of the Event Handing API and underlying mechanisms.
|
-- * 2017-03-07: Added the correct event dispatching in case the event is subscribed by a GROUP.
|
||||||
|
--
|
||||||
|
-- * 2017-02-07: Did a complete revision of the Event Handing API and underlying mechanisms.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -179,10 +181,6 @@
|
|||||||
--
|
--
|
||||||
-- @module Event
|
-- @module Event
|
||||||
|
|
||||||
-- TODO: Need to update the EVENTDATA documentation with IniPlayerName and TgtPlayerName
|
|
||||||
-- TODO: Need to update the EVENTDATA documentation with IniObjectCategory and TgtObjectCategory
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- The EVENT structure
|
--- The EVENT structure
|
||||||
-- @type EVENT
|
-- @type EVENT
|
||||||
@ -443,8 +441,9 @@ function EVENT:Remove( EventClass, EventID )
|
|||||||
self.Events[EventID][EventPriority][EventClass] = nil
|
self.Events[EventID][EventPriority][EventClass] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Removes an Events entry for a Unit
|
--- Removes an Events entry for a UNIT.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
|
-- @param #string UnitName The name of the UNIT.
|
||||||
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
||||||
-- @param Dcs.DCSWorld#world.event EventID
|
-- @param Dcs.DCSWorld#world.event EventID
|
||||||
-- @return #EVENT.Events
|
-- @return #EVENT.Events
|
||||||
@ -457,6 +456,21 @@ function EVENT:RemoveForUnit( UnitName, EventClass, EventID )
|
|||||||
Event.IniUnit[UnitName] = nil
|
Event.IniUnit[UnitName] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Removes an Events entry for a GROUP.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param #string GroupName The name of the GROUP.
|
||||||
|
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
||||||
|
-- @param Dcs.DCSWorld#world.event EventID
|
||||||
|
-- @return #EVENT.Events
|
||||||
|
function EVENT:RemoveForGroup( GroupName, EventClass, EventID )
|
||||||
|
self:F3( { EventClass, _EVENTMETA[EventID].Text } )
|
||||||
|
|
||||||
|
local EventClass = EventClass
|
||||||
|
local EventPriority = EventClass:GetEventPriority()
|
||||||
|
local Event = self.Events[EventID][EventPriority][EventClass]
|
||||||
|
Event.IniGroup[GroupName] = nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Clears all event subscriptions for a @{Base#BASE} derived object.
|
--- Clears all event subscriptions for a @{Base#BASE} derived object.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param Core.Base#BASE EventObject
|
-- @param Core.Base#BASE EventObject
|
||||||
@ -505,23 +519,43 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set a new listener for an S_EVENT_X event
|
--- Set a new listener for an S_EVENT_X event for a UNIT.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param #string EventDCSUnitName
|
-- @param #string UnitName The name of the UNIT.
|
||||||
-- @param #function EventFunction The function to be called when the event occurs for the unit.
|
-- @param #function EventFunction The function to be called when the event occurs for the GROUP.
|
||||||
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
||||||
-- @param EventID
|
-- @param EventID
|
||||||
-- @return #EVENT
|
-- @return #EVENT
|
||||||
function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventClass, EventID )
|
function EVENT:OnEventForUnit( UnitName, EventFunction, EventClass, EventID )
|
||||||
self:F2( EventDCSUnitName )
|
self:F2( UnitName )
|
||||||
|
|
||||||
local Event = self:Init( EventID, EventClass )
|
local Event = self:Init( EventID, EventClass )
|
||||||
if not Event.IniUnit then
|
if not Event.IniUnit then
|
||||||
Event.IniUnit = {}
|
Event.IniUnit = {}
|
||||||
end
|
end
|
||||||
Event.IniUnit[EventDCSUnitName] = {}
|
Event.IniUnit[UnitName] = {}
|
||||||
Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction
|
Event.IniUnit[UnitName].EventFunction = EventFunction
|
||||||
Event.IniUnit[EventDCSUnitName].EventClass = EventClass
|
Event.IniUnit[UnitName].EventClass = EventClass
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set a new listener for an S_EVENT_X event for a GROUP.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param #string GroupName The name of the GROUP.
|
||||||
|
-- @param #function EventFunction The function to be called when the event occurs for the GROUP.
|
||||||
|
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
||||||
|
-- @param EventID
|
||||||
|
-- @return #EVENT
|
||||||
|
function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID )
|
||||||
|
self:F2( GroupName )
|
||||||
|
|
||||||
|
local Event = self:Init( EventID, EventClass )
|
||||||
|
if not Event.IniGroup then
|
||||||
|
Event.IniGroup = {}
|
||||||
|
end
|
||||||
|
Event.IniGroup[GroupName] = {}
|
||||||
|
Event.IniGroup[GroupName].EventFunction = EventFunction
|
||||||
|
Event.IniGroup[GroupName].EventClass = EventClass
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1084,7 +1118,9 @@ function EVENT:onEvent( Event )
|
|||||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
self:E( { IniGroup = Event.IniGroup } )
|
if Event.IniGroup then
|
||||||
|
Event.IniGroupName = Event.IniDCSGroupName
|
||||||
|
end
|
||||||
end
|
end
|
||||||
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
||||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||||
@ -1125,6 +1161,10 @@ function EVENT:onEvent( Event )
|
|||||||
Event.TgtDCSGroupName = ""
|
Event.TgtDCSGroupName = ""
|
||||||
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
||||||
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
||||||
|
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||||
|
if Event.TgtGroup then
|
||||||
|
Event.TgtGroupName = Event.TgtDCSGroupName
|
||||||
|
end
|
||||||
end
|
end
|
||||||
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
||||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||||
@ -1170,6 +1210,8 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
||||||
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
||||||
|
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
|
|
||||||
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
||||||
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
|
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
|
||||||
@ -1177,8 +1219,7 @@ function EVENT:onEvent( Event )
|
|||||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||||
if EventData.IniUnit[Event.IniDCSUnitName].EventFunction then
|
if EventData.IniUnit[Event.IniDCSUnitName].EventFunction then
|
||||||
|
|
||||||
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
self:E( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
function()
|
function()
|
||||||
@ -1193,7 +1234,6 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
-- Now call the default event function.
|
-- Now call the default event function.
|
||||||
self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
function()
|
function()
|
||||||
@ -1204,38 +1244,69 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- If the EventData is not bound to a specific unit, then call the EventClass EventFunction.
|
-- If the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP.
|
||||||
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
if Event.IniDCSUnitName and Event.IniDCSGroupName and Event.IniGroupName and EventData.IniGroup and EventData.IniGroup[Event.IniGroupName] then
|
||||||
if Event.IniDCSUnit and not EventData.IniUnit then
|
|
||||||
|
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||||
|
if EventData.IniGroup[Event.IniGroupName].EventFunction then
|
||||||
|
|
||||||
if EventClass == EventData.EventClass then
|
self:E( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||||
|
|
||||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
local Result, Value = xpcall(
|
||||||
if EventData.EventFunction then
|
function()
|
||||||
|
return EventData.IniGroup[Event.IniGroupName].EventFunction( EventClass, Event )
|
||||||
|
end, ErrorHandler )
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||||
|
local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ]
|
||||||
|
if EventFunction and type( EventFunction ) == "function" then
|
||||||
|
|
||||||
|
-- Now call the default event function.
|
||||||
|
self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
|
|
||||||
-- There is an EventFunction defined, so call the EventFunction.
|
|
||||||
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
function()
|
function()
|
||||||
return EventData.EventFunction( EventClass, Event )
|
return EventFunction( EventClass, Event )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
else
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- If the EventData is not bound to a specific unit, then call the EventClass EventFunction.
|
||||||
|
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
||||||
|
if Event.IniDCSUnit and not EventData.IniUnit then
|
||||||
|
|
||||||
|
if EventClass == EventData.EventClass then
|
||||||
|
|
||||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||||
local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ]
|
if EventData.EventFunction then
|
||||||
if EventFunction and type( EventFunction ) == "function" then
|
|
||||||
|
|
||||||
-- Now call the default event function.
|
|
||||||
self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
|
||||||
|
|
||||||
|
-- There is an EventFunction defined, so call the EventFunction.
|
||||||
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
function()
|
function()
|
||||||
return EventFunction( EventClass, Event )
|
return EventData.EventFunction( EventClass, Event )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
|
else
|
||||||
|
|
||||||
|
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||||
|
local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ]
|
||||||
|
if EventFunction and type( EventFunction ) == "function" then
|
||||||
|
|
||||||
|
-- Now call the default event function.
|
||||||
|
self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
|
|
||||||
|
local Result, Value = xpcall(
|
||||||
|
function()
|
||||||
|
return EventFunction( EventClass, Event )
|
||||||
|
end, ErrorHandler )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -897,4 +897,29 @@ function GROUP:OnReSpawn( ReSpawnFunction )
|
|||||||
self.ReSpawnFunction = ReSpawnFunction
|
self.ReSpawnFunction = ReSpawnFunction
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do -- Event Handling
|
||||||
|
|
||||||
|
--- Subscribe to a DCS Event.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @param Core.Event#EVENTS Event
|
||||||
|
-- @param #function EventFunction (optional) The function to be called when the event occurs for the GROUP.
|
||||||
|
-- @return #GROUP
|
||||||
|
function GROUP:HandleEvent( Event, EventFunction )
|
||||||
|
|
||||||
|
self:EventDispatcher():OnEventForGroup( self:GetName(), EventFunction, self, Event )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- UnSubscribe to a DCS event.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @param Core.Event#EVENTS Event
|
||||||
|
-- @return #GROUP
|
||||||
|
function GROUP:UnHandleEvent( Event )
|
||||||
|
|
||||||
|
self:EventDispatcher():RemoveForGroup( self:GetName(), self, Event )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
-- Name: EVT-200 - GROUP OnEventShot Example
|
||||||
|
-- Author: FlightControl
|
||||||
|
-- Date Created: 07 Mar 2017
|
||||||
|
--
|
||||||
|
-- # Situation:
|
||||||
|
--
|
||||||
|
-- Two groups of planes are flying in the air and shoot an missile to a multitude of ground targets.
|
||||||
|
--
|
||||||
|
-- # Test cases:
|
||||||
|
--
|
||||||
|
-- 1. Observe the planes shooting the missile.
|
||||||
|
-- 2. Observe when the planes shoots the missile, a dcs.log entry is written in the logging.
|
||||||
|
-- 3. Check the contents of the fields of the S_EVENT_SHOT entry.
|
||||||
|
-- 4. The planes of GROUP "Group Plane A", should only send a message when they shoot a missile.
|
||||||
|
-- 5. The planes of GROUP "Group Plane B", should NOT send a message when they shoot a missile.
|
||||||
|
|
||||||
|
local PlaneGroup = GROUP:FindByName( "Group Plane A" )
|
||||||
|
|
||||||
|
PlaneGroup:HandleEvent( EVENTS.Shot )
|
||||||
|
|
||||||
|
function PlaneGroup:OnEventShot( EventData )
|
||||||
|
|
||||||
|
self:E( "I just fired a missile and I am part of " .. EventData.IniGroupName )
|
||||||
|
EventData.IniUnit:MessageToAll( "I just fired a missile and I am part of " .. EventData.IniGroupName, 15, "Alert!" )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user