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.
|
||||
-- * **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
|
||||
--
|
||||
-- * **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.
|
||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||
|
||||
@ -165,7 +165,9 @@
|
||||
--
|
||||
-- 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
|
||||
|
||||
-- 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
|
||||
-- @type EVENT
|
||||
@ -443,8 +441,9 @@ function EVENT:Remove( EventClass, EventID )
|
||||
self.Events[EventID][EventPriority][EventClass] = nil
|
||||
end
|
||||
|
||||
--- Removes an Events entry for a Unit
|
||||
--- Removes an Events entry for a UNIT.
|
||||
-- @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 Dcs.DCSWorld#world.event EventID
|
||||
-- @return #EVENT.Events
|
||||
@ -457,6 +456,21 @@ function EVENT:RemoveForUnit( UnitName, EventClass, EventID )
|
||||
Event.IniUnit[UnitName] = nil
|
||||
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.
|
||||
-- @param #EVENT self
|
||||
-- @param Core.Base#BASE EventObject
|
||||
@ -505,23 +519,43 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
|
||||
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 #string EventDCSUnitName
|
||||
-- @param #function EventFunction The function to be called when the event occurs for the unit.
|
||||
-- @param #string UnitName The name of 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 EventID
|
||||
-- @return #EVENT
|
||||
function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventClass, EventID )
|
||||
self:F2( EventDCSUnitName )
|
||||
function EVENT:OnEventForUnit( UnitName, EventFunction, EventClass, EventID )
|
||||
self:F2( UnitName )
|
||||
|
||||
local Event = self:Init( EventID, EventClass )
|
||||
if not Event.IniUnit then
|
||||
Event.IniUnit = {}
|
||||
end
|
||||
Event.IniUnit[EventDCSUnitName] = {}
|
||||
Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction
|
||||
Event.IniUnit[EventDCSUnitName].EventClass = EventClass
|
||||
Event.IniUnit[UnitName] = {}
|
||||
Event.IniUnit[UnitName].EventFunction = EventFunction
|
||||
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
|
||||
end
|
||||
|
||||
@ -1084,7 +1118,9 @@ function EVENT:onEvent( Event )
|
||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
self:E( { IniGroup = Event.IniGroup } )
|
||||
if Event.IniGroup then
|
||||
Event.IniGroupName = Event.IniDCSGroupName
|
||||
end
|
||||
end
|
||||
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
@ -1125,6 +1161,10 @@ function EVENT:onEvent( Event )
|
||||
Event.TgtDCSGroupName = ""
|
||||
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
||||
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||
if Event.TgtGroup then
|
||||
Event.TgtGroupName = Event.TgtDCSGroupName
|
||||
end
|
||||
end
|
||||
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
||||
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.
|
||||
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 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
|
||||
if EventData.IniUnit[Event.IniDCSUnitName].EventFunction then
|
||||
|
||||
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
self:E( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
@ -1193,7 +1234,6 @@ function EVENT:onEvent( Event )
|
||||
|
||||
-- Now call the default event function.
|
||||
self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
@ -1204,38 +1244,69 @@ function EVENT:onEvent( Event )
|
||||
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 the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP.
|
||||
if Event.IniDCSUnitName and Event.IniDCSGroupName and Event.IniGroupName and EventData.IniGroup and EventData.IniGroup[Event.IniGroupName] 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
|
||||
if EventData.EventFunction then
|
||||
local Result, Value = xpcall(
|
||||
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(
|
||||
function()
|
||||
return EventData.EventFunction( EventClass, Event )
|
||||
return EventFunction( EventClass, Event )
|
||||
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.
|
||||
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 } )
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||
if EventData.EventFunction then
|
||||
|
||||
-- There is an EventFunction defined, so call the EventFunction.
|
||||
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventFunction( EventClass, Event )
|
||||
return EventData.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 Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -897,4 +897,29 @@ function GROUP:OnReSpawn( ReSpawnFunction )
|
||||
self.ReSpawnFunction = ReSpawnFunction
|
||||
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