GROUPSET and UNITSET are working now !!

- GROUPSET and UNITSET inherit SET
- DATABASE optimized
- Tracing levels tuned.
This commit is contained in:
FlightControl
2016-05-27 11:32:49 +02:00
parent dc662849d4
commit 645d074a7d
19 changed files with 634 additions and 33881 deletions

View File

@@ -10,12 +10,6 @@
-- * Unit types
-- * Starting with certain prefix strings.
--
-- This list will grow over time. Planned developments are to include filters and iterators.
-- Additional filters will be added around @{Zone#ZONEs}, Radiuses, Active players, ...
-- More iterators will be implemented in the near future ...
--
-- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor.
--
-- UNITSET construction methods:
-- =================================
-- Create a new UNITSET object with the @{#UNITSET.New} method:
@@ -56,16 +50,13 @@
-- * @{#UNITSET.ForEachUnitInGroup}: Calls a function for each group contained within the UNITSET.
-- * @{#UNITSET.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the UNITSET.
--
-- @module Set
-- @module UnitSet
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Menu" )
Include.File( "Group" )
Include.File( "Unit" )
Include.File( "Event" )
Include.File( "Client" )
Include.File( "Set" )
--- UNITSET class
@@ -97,21 +88,6 @@ UNITSET = {
},
}
local _DATABASECoalition =
{
[1] = "Red",
[2] = "Blue",
}
local _DATABASECategory =
{
[Unit.Category.AIRPLANE] = "Plane",
[Unit.Category.HELICOPTER] = "Helicopter",
[Unit.Category.GROUND_UNIT] = "Vehicle",
[Unit.Category.SHIP] = "Ship",
[Unit.Category.STRUCTURE] = "Structure",
}
--- Creates a new UNITSET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
-- @param #UNITSET self
@@ -122,42 +98,25 @@ local _DATABASECategory =
function UNITSET:New()
-- Inherits from BASE
local self = BASE:Inherit( self, SET:New( _DATABASE.Units ) )
-- -- Follow alive players and clients
-- _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self )
-- _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self )
-- self:_RegisterPlayers()
local self = BASE:Inherit( self, SET:New( _DATABASE.UNITS ) )
return self
end
--- Finds a Unit based on the Unit Name.
-- @param #UNITSET self
-- @param #string UnitName
-- @return Unit#UNIT The found Unit.
function UNITSET:FindUnit( UnitName )
local UnitFound = self.Units[UnitName]
local UnitFound = self.Set[UnitName]
return UnitFound
end
--- Finds a Unit based on the Unit Name.
-- @param #UNITSET self
-- @param Unit#UNIT UnitName
-- @param Unit#UNIT UnitData
-- @return Unit#UNIT The added Unit.
function UNITSET:_AddUnit( UnitName, UnitData )
self.Units[UnitName] = _DATABASE:FindUnit( UnitName )
end
--- Builds a set of units of coalitons.
--- Builds a set of units of coalitions.
-- Possible current coalitions are red, blue and neutral.
-- @param #UNITSET self
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral".
@@ -252,23 +211,6 @@ function UNITSET:FilterPrefixes( Prefixes )
end
----- Builds a set of units of defined group prefixes.
---- All the units starting with the given group prefixes will be included within the set.
---- @param #UNITSET self
---- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with.
---- @return #UNITSET self
--function UNITSET:FilterGroupPrefixes( Prefixes )
-- if not self.Filter.GroupPrefixes then
-- self.Filter.GroupPrefixes = {}
-- end
-- if type( Prefixes ) ~= "table" then
-- Prefixes = { Prefixes }
-- end
-- for PrefixID, Prefix in pairs( Prefixes ) do
-- self.Filter.GroupPrefixes[Prefix] = Prefix
-- end
-- return self
--end
--- Starts the filtering.
@@ -277,173 +219,78 @@ end
function UNITSET:FilterStart()
if _DATABASE then
self:_FilterStart( self.DatabaseCollection )
self:_FilterStart()
end
FollowEventBirth( )
_EVENTDISPATCHER:OnBirth( self._EventOnBirth, self )
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
return self
end
--- Events
--- Handles the OnBirth event for the alive units set.
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET birth event!
-- @param #UNITSET self
-- @param Event#EVENTDATA Event
function UNITSET:_EventOnBirth( Event )
self:F( { Event } )
-- @return #string The name of the UNIT
-- @return #table The UNIT
function UNITSET:AddInDatabase( Event )
self:F3( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeUnit( Event.IniDCSUnit ) then
self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit
self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit
self:_AddUnit( UNIT:Register( Event.IniDCSUnit ) )
--self.Units[Event.IniDCSUnitName] = UNIT:Register( Event.IniDCSUnit )
--if not self.DCSGroups[Event.IniDCSGroupName] then
-- self.DCSGroups[Event.IniDCSGroupName] = Event.IniDCSGroupName
-- self.DCSGroupsAlive[Event.IniDCSGroupName] = Event.IniDCSGroupName
-- self.Groups[Event.IniDCSGroupName] = GROUP:New( Event.IniDCSGroup )
--end
self:_EventOnPlayerEnterUnit( Event )
end
if not self.Database[Event.IniDCSUnitName] then
self.Database[Event.IniDCSUnitName] = UNIT:Register( Event.IniDCSUnitName )
self:T3( self.Database[Event.IniDCSUnitName] )
end
return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName]
end
--- Handles the OnDead or OnCrash event for alive units set.
--- Handles the Database to check on any event that Object exists in the Database.
-- This is required, because sometimes the _DATABASE event gets called later than the SET event or vise versa!
-- @param #UNITSET self
-- @param Event#EVENTDATA Event
function UNITSET:_EventOnDeadOrCrash( Event )
self:F( { Event } )
-- @return #string The name of the UNIT
-- @return #table The UNIT
function UNITSET:FindInDatabase( Event )
self:F3( { Event } )
if Event.IniDCSUnit then
if self.DCSUnitsAlive[Event.IniDCSUnitName] then
self.DCSUnits[Event.IniDCSUnitName] = nil
self.DCSUnitsAlive[Event.IniDCSUnitName] = nil
end
end
return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName]
end
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
--- Interate the UNITSET and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters.
-- @param #UNITSET self
-- @param Event#EVENTDATA Event
function UNITSET:_EventOnPlayerEnterUnit( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeUnit( Event.IniDCSUnit ) then
if not self.PlayersAlive[Event.IniDCSUnitName] then
self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } )
self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName()
self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ]
end
end
end
end
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
-- @param #UNITSET self
-- @param Event#EVENTDATA Event
function UNITSET:_EventOnPlayerLeaveUnit( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeUnit( Event.IniDCSUnit ) then
if self.PlayersAlive[Event.IniDCSUnitName] then
self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } )
self.PlayersAlive[Event.IniDCSUnitName] = nil
self.ClientsAlive[Event.IniDCSUnitName] = nil
end
end
end
end
--- Iterators
--- Interate the UNITSET and call an interator function for the given set, providing the Object for each element within the set and optional parameters.
-- @param #UNITSET self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET.
-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the UNITSET. The function needs to accept a UNIT parameter.
-- @return #UNITSET self
function UNITSET:ForEach( IteratorFunction, arg, Set )
self:F( arg )
function UNITSET:ForEachUnit( IteratorFunction, ... )
self:F2( arg )
local function CoRoutine()
local Count = 0
for ObjectID, Object in pairs( Set ) do
self:T2( Object )
IteratorFunction( Object, unpack( arg ) )
Count = Count + 1
if Count % 10 == 0 then
coroutine.yield( false )
end
end
return true
end
local co = coroutine.create( CoRoutine )
local function Schedule()
local status, res = coroutine.resume( co )
self:T( { status, res } )
if status == false then
error( res )
end
if res == false then
return true -- resume next time the loop
end
return false
end
local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 )
return self
end
--- Interate the UNITSET and call an interator function for each **alive** unit, providing the Unit and optional parameters.
-- @param #UNITSET self
-- @param #function IteratorFunction The function that will be called when there is an alive unit in the UNITSET. The function needs to accept a UNIT parameter.
-- @return #UNITSET self
function UNITSET:ForEachDCSUnitAlive( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive )
self:ForEach( IteratorFunction, arg, self.Set )
return self
end
--- Interate the UNITSET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters.
-- @param #UNITSET self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET. The function needs to accept a UNIT parameter.
-- @return #UNITSET self
function UNITSET:ForEachPlayer( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.PlayersAlive )
return self
end
--- Interate the UNITSET and call an interator function for each client, providing the Client to the function and optional parameters.
-- @param #UNITSET self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET. The function needs to accept a CLIENT parameter.
-- @return #UNITSET self
function UNITSET:ForEachClient( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.Clients )
return self
end
----- Interate the UNITSET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters.
---- @param #UNITSET self
---- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET. The function needs to accept a UNIT parameter.
---- @return #UNITSET self
--function UNITSET:ForEachPlayer( IteratorFunction, ... )
-- self:F2( arg )
--
-- self:ForEach( IteratorFunction, arg, self.PlayersAlive )
--
-- return self
--end
--
--
----- Interate the UNITSET and call an interator function for each client, providing the Client to the function and optional parameters.
---- @param #UNITSET self
---- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET. The function needs to accept a CLIENT parameter.
---- @return #UNITSET self
--function UNITSET:ForEachClient( IteratorFunction, ... )
-- self:F2( arg )
--
-- self:ForEach( IteratorFunction, arg, self.Clients )
--
-- return self
--end
---
@@ -451,13 +298,13 @@ end
-- @param Unit#UNIT MUnit
-- @return #UNITSET self
function UNITSET:IsIncludeObject( MUnit )
self:F( MUnit )
self:F2( MUnit )
local MUnitInclude = true
if self.Filter.Coalitions then
local MUnitCoalition = false
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
self:T( { "Coalition:", MUnit:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
self:T3( { "Coalition:", MUnit:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == MUnit:GetCoalition() then
MUnitCoalition = true
end
@@ -468,7 +315,7 @@ function UNITSET:IsIncludeObject( MUnit )
if self.Filter.Categories then
local MUnitCategory = false
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
self:T( { "Category:", MUnit:GetDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } )
self:T3( { "Category:", MUnit:GetDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } )
if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == MUnit:GetDesc().category then
MUnitCategory = true
end
@@ -479,7 +326,7 @@ function UNITSET:IsIncludeObject( MUnit )
if self.Filter.Types then
local MUnitType = false
for TypeID, TypeName in pairs( self.Filter.Types ) do
self:T( { "Type:", MUnit:GetTypeName(), TypeName } )
self:T3( { "Type:", MUnit:GetTypeName(), TypeName } )
if TypeName == MUnit:GetTypeName() then
MUnitType = true
end
@@ -490,7 +337,7 @@ function UNITSET:IsIncludeObject( MUnit )
if self.Filter.Countries then
local MUnitCountry = false
for CountryID, CountryName in pairs( self.Filter.Countries ) do
self:T( { "Country:", MUnit:GetCountry(), CountryName } )
self:T3( { "Country:", MUnit:GetCountry(), CountryName } )
if country.id[CountryName] == MUnit:GetCountry() then
MUnitCountry = true
end
@@ -501,7 +348,7 @@ function UNITSET:IsIncludeObject( MUnit )
if self.Filter.UnitPrefixes then
local MUnitPrefix = false
for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do
self:T( { "Unit Prefix:", string.find( MUnit:GetName(), UnitPrefix, 1 ), UnitPrefix } )
self:T3( { "Prefix:", string.find( MUnit:GetName(), UnitPrefix, 1 ), UnitPrefix } )
if string.find( MUnit:GetName(), UnitPrefix, 1 ) then
MUnitPrefix = true
end
@@ -509,7 +356,7 @@ function UNITSET:IsIncludeObject( MUnit )
MUnitInclude = MUnitInclude and MUnitPrefix
end
self:T( MUnitInclude )
self:T2( MUnitInclude )
return MUnitInclude
end