This commit is contained in:
Frank 2020-09-10 00:34:17 +02:00
parent d5c4c34759
commit 717842b276
6 changed files with 110 additions and 55 deletions

View File

@ -11,7 +11,7 @@
-- --
-- ### Author: **funkyfranky** -- ### Author: **funkyfranky**
-- @module Core.Timer -- @module Core.Timer
-- @image CORE_Timer.png -- @image Core_Scheduler.JPG
--- TIMER class. --- TIMER class.
@ -19,6 +19,7 @@
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #string lid Class id string for output to DCS log file. -- @field #string lid Class id string for output to DCS log file.
-- @field #number tid Timer ID returned by the DCS API function. -- @field #number tid Timer ID returned by the DCS API function.
-- @field #number uid Unique ID of the timer.
-- @field #function func Timer function. -- @field #function func Timer function.
-- @field #table para Parameters passed to the timer function. -- @field #table para Parameters passed to the timer function.
-- @field #number Tstart Relative start time in seconds. -- @field #number Tstart Relative start time in seconds.
@ -28,7 +29,7 @@
-- @field #number ncallsMax Max number of function calls. If reached, timer is stopped. -- @field #number ncallsMax Max number of function calls. If reached, timer is stopped.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- *Better three hours too soon than a minute too late.* William Shakespeare --- *Better three hours too soon than a minute too late.* - William Shakespeare
-- --
-- === -- ===
-- --
@ -36,7 +37,7 @@
-- --
-- # The TIMER Concept -- # The TIMER Concept
-- --
-- The TIMER class is the little sister of the SCHEDULER class. It does the same thing but is a bit easier to use and has less overhead. It should be sufficient in many cases. -- The TIMER class is the little sister of the @{Core.Scheduler#SCHEDULER} class. It does the same thing but is a bit easier to use and has less overhead. It should be sufficient in many cases.
-- --
-- It provides an easy interface to the DCS [timer.scheduleFunction](https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction). -- It provides an easy interface to the DCS [timer.scheduleFunction](https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction).
-- --
@ -62,20 +63,20 @@
-- --
-- Note that -- Note that
-- --
-- * if *Tstart* is not specified (*nil*), the first function call happens immediately. -- * if *Tstart* is not specified (*nil*), the first function call happens immediately, i.e. after one millisecond.
-- * if *dT* is not specified (*nil*), the function is called only once. -- * if *dT* is not specified (*nil*), the function is called only once.
-- * if *Duration* is not specified (*nil*), the timer runs forever or until stopped manually or until the max function calls are reached (see below). -- * if *Duration* is not specified (*nil*), the timer runs forever or until stopped manually or until the max function calls are reached (see below).
-- --
-- For example, -- For example,
-- --
-- mytimer:Start(3) -- Will call the function once after 3 seconds. -- mytimer:Start(3) -- Will call the function once after 3 seconds.
-- mytimer:Start(nil, 0.5) -- Will call right now and then every 0.5 sec until all eternaty. -- mytimer:Start(nil, 0.5) -- Will call right now and then every 0.5 sec until all eternity.
-- mytimer:Start(nil, 2.0, 20) -- Will call right now and then every 2.0 sec for 20 sec. -- mytimer:Start(nil, 2.0, 20) -- Will call right now and then every 2.0 sec for 20 sec.
-- mytimer:Start(1.0, nil, 10) -- Does not make sense as the function is only called once anyway. -- mytimer:Start(1.0, nil, 10) -- Does not make sense as the function is only called once anyway.
-- --
-- ## Stopping the Timer -- ## Stopping the Timer
-- --
-- The timer can be stopped manually by the @{#TIMER.Start}(*Delay*) function -- The timer can be stopped manually by the @{#TIMER.Stop}(*Delay*) function
-- --
-- mytimer:Stop() -- mytimer:Stop()
-- --
@ -206,7 +207,7 @@ function TIMER:Stop(Delay)
if self.tid then if self.tid then
-- Remove timer function. -- Remove timer function.
self:I(self.lid..string.format("Stopping timer by removing timer function after %d calls!", self.ncalls)) self:T(self.lid..string.format("Stopping timer by removing timer function after %d calls!", self.ncalls))
timer.removeFunction(self.tid) timer.removeFunction(self.tid)
-- Remove DB entry. -- Remove DB entry.

View File

@ -1552,7 +1552,7 @@
WAREHOUSE = { WAREHOUSE = {
ClassName = "WAREHOUSE", ClassName = "WAREHOUSE",
Debug = false, Debug = false,
verbosity = 0, verbosity = 2,
lid = nil, lid = nil,
Report = true, Report = true,
warehouse = nil, warehouse = nil,
@ -1893,7 +1893,7 @@ function WAREHOUSE:New(warehouse, alias)
-- Defaults -- Defaults
self:SetMarker(true) self:SetMarker(true)
self:SetReportOff() self:SetReportOff()
self:SetVerbosityLevel(0) --self:SetVerbosityLevel(0)
-- Add warehouse to database. -- Add warehouse to database.
_WAREHOUSEDB.Warehouses[self.uid]=self _WAREHOUSEDB.Warehouses[self.uid]=self
@ -3881,7 +3881,7 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu
self:_DebugMessage(string.format("Removing group %s", group:GetName()), 5) self:_DebugMessage(string.format("Removing group %s", group:GetName()), 5)
-- Setting parameter to false, i.e. creating NO dead or remove unit event, seems to not confuse the dispatcher logic. -- Setting parameter to false, i.e. creating NO dead or remove unit event, seems to not confuse the dispatcher logic.
-- TODO: It would be nice, however, to have the remove event. -- TODO: It would be nice, however, to have the remove event.
group:Destroy(false) group:Destroy() --(false)
end end
else else
@ -5158,7 +5158,7 @@ end
-- @param #WAREHOUSE.Pendingitem request The request of the dead asset. -- @param #WAREHOUSE.Pendingitem request The request of the dead asset.
function WAREHOUSE:onafterAssetSpawned(From, Event, To, group, asset, request) function WAREHOUSE:onafterAssetSpawned(From, Event, To, group, asset, request)
local text=string.format("Asset %s from request id=%d was spawned!", asset.spawngroupname, request.uid) local text=string.format("Asset %s from request id=%d was spawned!", asset.spawngroupname, request.uid)
self:T(self.lid..text) self:I(self.lid..text)
-- Sete asset state to spawned. -- Sete asset state to spawned.
asset.spawned=true asset.spawned=true
@ -5169,22 +5169,22 @@ function WAREHOUSE:onafterAssetSpawned(From, Event, To, group, asset, request)
local assetitem=_asset --#WAREHOUSE.Assetitem local assetitem=_asset --#WAREHOUSE.Assetitem
-- Debug info. -- Debug info.
self:T(self.lid..string.format("Asset %s spawned %s as %s", assetitem.templatename, tostring(assetitem.spawned), tostring(assetitem.spawngroupname))) self:I(self.lid..string.format("Asset %s spawned %s as %s", assetitem.templatename, tostring(assetitem.spawned), tostring(assetitem.spawngroupname)))
if assetitem.spawned then if assetitem.spawned then
n=n+1 n=n+1
else else
self:T(self.lid.."FF What?! This should not happen!") self:I(self.lid.."FF What?! This should not happen!")
end end
end end
-- Trigger event. -- Trigger event.
if n==request.nasset+request.ntransport then if n==request.nasset+request.ntransport then
self:T3(self.lid..string.format("All assets %d (ncargo=%d + ntransport=%d) of request rid=%d spawned. Calling RequestSpawned", n, request.nasset, request.ntransport, request.uid)) self:I(self.lid..string.format("All assets %d (ncargo=%d + ntransport=%d) of request rid=%d spawned. Calling RequestSpawned", n, request.nasset, request.ntransport, request.uid))
self:RequestSpawned(request, request.cargogroupset, request.transportgroupset) self:RequestSpawned(request, request.cargogroupset, request.transportgroupset)
else else
self:T3(self.lid..string.format("Not all assets %d (ncargo=%d + ntransport=%d) of request rid=%d spawned YET", n, request.nasset, request.ntransport, request.uid)) self:I(self.lid..string.format("Not all assets %d (ncargo=%d + ntransport=%d) of request rid=%d spawned YET", n, request.nasset, request.ntransport, request.uid))
end end
end end
@ -6119,36 +6119,44 @@ function WAREHOUSE:_OnEventBirth(EventData)
-- Get asset and request from id. -- Get asset and request from id.
local asset=self:GetAssetByID(aid) local asset=self:GetAssetByID(aid)
local request=self:GetRequestByID(rid) local request=self:GetRequestByID(rid)
-- Debug message. if asset and request then
self:T(self.lid..string.format("Warehouse %s captured event birth of its asset unit %s. spawned=%s", self.alias, EventData.IniUnitName, tostring(asset.spawned)))
-- Birth is triggered for each unit. We need to make sure not to call this too often! -- Debug message.
if not asset.spawned then self:I(self.lid..string.format("Warehouse %s captured event birth of request ID=%d, asset ID=%d, unit %s spawned=%s", self.alias, request.uid, asset.uid, EventData.IniUnitName, tostring(asset.spawned)))
-- Remove asset from stock. -- Birth is triggered for each unit. We need to make sure not to call this too often!
self:_DeleteStockItem(asset) if not asset.spawned then
-- Set spawned switch. -- Remove asset from stock.
asset.spawned=true self:_DeleteStockItem(asset)
asset.spawngroupname=group:GetName()
-- Set spawned switch.
-- Add group. asset.spawned=true
if asset.iscargo==true then asset.spawngroupname=group:GetName()
request.cargogroupset=request.cargogroupset or SET_GROUP:New()
request.cargogroupset:AddGroup(group) -- Add group.
else if asset.iscargo==true then
request.transportgroupset=request.transportgroupset or SET_GROUP:New() request.cargogroupset=request.cargogroupset or SET_GROUP:New()
request.transportgroupset:AddGroup(group) request.cargogroupset:AddGroup(group)
else
request.transportgroupset=request.transportgroupset or SET_GROUP:New()
request.transportgroupset:AddGroup(group)
end
-- Set warehouse state.
group:SetState(group, "WAREHOUSE", self)
-- Asset spawned FSM function.
--self:__AssetSpawned(1, group, asset, request)
env.info(string.format("FF asset spawned %s, %s", asset.spawngroupname, EventData.IniUnitName))
self:AssetSpawned(group, asset, request)
end end
-- Set warehouse state. else
group:SetState(group, "WAREHOUSE", self) self:E(self.lid..string.format("ERROR: Either asset AID=%s or request RID=%s are nil in event birth of unit %s", tostring(aid), tostring(rid), tostring(EventData.IniUnitName)))
-- Asset spawned FSM function.
--self:__AssetSpawned(1, group, asset, request)
self:AssetSpawned(group, asset, request)
end end
else else

View File

@ -829,7 +829,6 @@ function AIRWING:onafterStatus(From, Event, To)
------------------ ------------------
if self.verbose>=2 then if self.verbose>=2 then
local text=string.format("Missions Total=%d:", #self.missionqueue) local text=string.format("Missions Total=%d:", #self.missionqueue)
env.info("FF verbose "..self.verbose)
for i,_mission in pairs(self.missionqueue) do for i,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG

View File

@ -3384,6 +3384,7 @@ function AIRBOSS:onafterStart(From, Event, To)
self:HandleEvent(EVENTS.Ejection) self:HandleEvent(EVENTS.Ejection)
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft) self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft)
self:HandleEvent(EVENTS.MissionEnd) self:HandleEvent(EVENTS.MissionEnd)
self:HandleEvent(EVENTS.RemoveUnit)
--self.StatusScheduler=SCHEDULER:New(self) --self.StatusScheduler=SCHEDULER:New(self)
--self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5) --self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5)
@ -8833,6 +8834,58 @@ function AIRBOSS:OnEventEjection(EventData)
end end
--- Airboss event handler for event REMOVEUNIT.
-- @param #AIRBOSS self
-- @param Core.Event#EVENTDATA EventData
function AIRBOSS:OnEventRemoveUnit(EventData)
self:F3({eventland = EventData})
-- Nil checks.
if EventData==nil then
self:E(self.lid.."ERROR: EventData=nil in event REMOVEUNIT!")
self:E(EventData)
return
end
if EventData.IniUnit==nil then
self:E(self.lid.."ERROR: EventData.IniUnit=nil in event REMOVEUNIT!")
self:E(EventData)
return
end
local _unitName=EventData.IniUnitName
local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
self:T3(self.lid.."EJECT: unit = "..tostring(EventData.IniUnitName))
self:T3(self.lid.."EJECT: group = "..tostring(EventData.IniGroupName))
self:T3(self.lid.."EJECT: player = "..tostring(_playername))
if _unit and _playername then
self:T(self.lid..string.format("Player %s removed!",_playername))
-- Get player flight.
local flight=self.players[_playername]
-- Remove flight completely from all queues and collapse marshal if necessary.
if flight then
self:_RemoveFlight(flight, true)
end
else
-- Debug message.
self:T(self.lid..string.format("AI unit %s removed!", EventData.IniUnitName))
-- Remove element/unit from flight group and from all queues if no elements alive.
self:_RemoveUnitFromFlight(EventData.IniUnit)
-- What could happen is, that another element has landed (recovered) already and this one crashes.
-- This would mean that the flight would not be deleted from the queue ==> Check if section recovered.
local flight=self:_GetFlightFromGroupInQueue(EventData.IniGroup, self.flights)
self:_CheckSectionRecovered(flight)
end
end
--- Airboss event handler for event player leave unit. --- Airboss event handler for event player leave unit.
-- @param #AIRBOSS self -- @param #AIRBOSS self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData

View File

@ -2565,17 +2565,15 @@ function FLIGHTGROUP:_InitGroup()
-- Set default radio. -- Set default radio.
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On) self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On)
--TODO callsign from template or getCallsign -- Set callsign.
local callsign=self.template.units[1].callsign local callsign=self.template.units[1].callsign
env.info("FF callsign:",showMessageBox) if type(callsign)=="number" then -- Sometimes callsign is just "101".
if type(callsign)=="number" then
local cs=tostring(callsign) local cs=tostring(callsign)
callsign={} callsign={}
callsign[1]=cs:sub(1,1) callsign[1]=cs:sub(1,1)
callsign[2]=cs:sub(2,2) callsign[2]=cs:sub(2,2)
callsign[3]=cs:sub(3,3) callsign[3]=cs:sub(3,3)
end end
self:I({callsign=callsign})
self.callsign.NumberSquad=callsign[1] self.callsign.NumberSquad=callsign[1]
self.callsign.NumberGroup=callsign[2] self.callsign.NumberGroup=callsign[2]
self.callsign.NumberElement=callsign[3] -- First element only self.callsign.NumberElement=callsign[3] -- First element only

View File

@ -1919,7 +1919,6 @@ function OPSGROUP:onafterTaskCancel(From, Event, To, Task)
else else
local text=string.format("WARNING: No (current) task to cancel!") local text=string.format("WARNING: No (current) task to cancel!")
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:E(self.lid..text) self:E(self.lid..text)
end end
@ -2211,7 +2210,6 @@ function OPSGROUP:onafterMissionStart(From, Event, To, Mission)
-- Debug output. -- Debug output.
local text=string.format("Starting %s Mission %s, target %s", Mission.type, tostring(Mission.name), Mission:GetTargetName()) local text=string.format("Starting %s Mission %s, target %s", Mission.type, tostring(Mission.name), Mission:GetTargetName())
self:T(self.lid..text) self:T(self.lid..text)
MESSAGE:New(text, 30, self.groupname):ToAllIf(self.Debug)
-- Set current mission. -- Set current mission.
self.currentmission=Mission.auftragsnummer self.currentmission=Mission.auftragsnummer
@ -2237,7 +2235,6 @@ function OPSGROUP:onafterMissionExecute(From, Event, To, Mission)
local text=string.format("Executing %s Mission %s, target %s", Mission.type, tostring(Mission.name), Mission:GetTargetName()) local text=string.format("Executing %s Mission %s, target %s", Mission.type, tostring(Mission.name), Mission:GetTargetName())
self:T(self.lid..text) self:T(self.lid..text)
MESSAGE:New(text, 30, self.groupname):ToAllIf(self.Debug)
-- Set group mission status to EXECUTING. -- Set group mission status to EXECUTING.
Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.EXECUTING) Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.EXECUTING)
@ -3454,7 +3451,7 @@ function OPSGROUP:SwitchROE(roe)
self.group:OptionROE(self.option.ROE) self.group:OptionROE(self.option.ROE)
self:I(self.lid..string.format("Setting current ROE=%d (%s)", self.option.ROE, self:_GetROEName(self.option.ROE))) self:T(self.lid..string.format("Setting current ROE=%d (%s)", self.option.ROE, self:_GetROEName(self.option.ROE)))
end end
@ -3893,7 +3890,7 @@ function OPSGROUP:SwitchRadio(Frequency, Modulation)
self:I(self.lid..string.format("Switching radio to frequency %.3f MHz %s", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu))) self:I(self.lid..string.format("Switching radio to frequency %.3f MHz %s", self.radio.Freq, UTILS.GetModulationName(self.radio.Modu)))
else else
self:I(self.lid.."INFO: Current radio not switched as freq/modulation did not change") self:T(self.lid.."INFO: Current radio not switched as freq/modulation did not change")
end end
else else
@ -4573,7 +4570,6 @@ function OPSGROUP:GetAmmoUnit(unit, display)
else else
self:T3(self.lid..text) self:T3(self.lid..text)
end end
MESSAGE:New(text, 10):ToAllIf(display)
-- Total amount of ammunition. -- Total amount of ammunition.
nammo=nshells+nrockets+nmissiles+nbombs+ntorps nammo=nshells+nrockets+nmissiles+nbombs+ntorps