Merge branch 'develop' into FF/Ops

This commit is contained in:
Frank 2020-08-30 17:24:57 +02:00
commit 7d2746e7be
4 changed files with 301 additions and 290 deletions

View File

@ -902,7 +902,7 @@ end
function DATABASE:_RegisterAirbases() function DATABASE:_RegisterAirbases()
for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do
-- Get the airbase name. -- Get the airbase name.
local DCSAirbaseName = DCSAirbase:getName() local DCSAirbaseName = DCSAirbase:getName()
@ -914,7 +914,7 @@ function DATABASE:_RegisterAirbases()
-- Debug output. -- Debug output.
self:I(string.format("Register Airbase: %s, getID=%d, GetID=%d (unique=%d)", DCSAirbaseName, DCSAirbase:getID(), airbase:GetID(), airbase:GetID(true))) self:I(string.format("Register Airbase: %s, getID=%d, GetID=%d (unique=%d)", DCSAirbaseName, DCSAirbase:getID(), airbase:GetID(), airbase:GetID(true)))
end end
return self return self

View File

@ -5,9 +5,9 @@
-- === -- ===
-- --
-- ### Author: **TAW CougarNL**, *funkyfranky* -- ### Author: **TAW CougarNL**, *funkyfranky*
-- --
-- @module Utilities.PROFILER -- @module Utilities.PROFILER
-- @image MOOSE.JPG -- @image Utils_Profiler.jpg
--- PROFILER class. --- PROFILER class.
@ -26,67 +26,79 @@
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler". -- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt" -- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
--- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? * --- *The emperor counsels simplicity.* *First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature?*
-- --
-- === -- ===
-- --
-- ![Banner Image](..\Presentations\Utilities\PROFILER_Main.jpg) -- ![Banner Image](..\Presentations\Utilities\PROFILER_Main.jpg)
-- --
-- # The PROFILER Concept -- # The PROFILER Concept
-- --
-- Profile your lua code. This tells you, which functions are called very often and which consume most real time. -- Profile your lua code. This tells you, which functions are called very often and which consume most real time.
-- With this information you can optimize the perfomance of your code. -- With this information you can optimize the perfomance of your code.
-- --
-- # Prerequisites -- # Prerequisites
-- --
-- The modules **os** and **lfs** need to be desanizied. -- The modules **os**, **io** and **lfs** need to be desanizied. Comment out the lines
-- --
-- -- --sanitizeModule('os')
-- --sanitizeModule('io')
-- --sanitizeModule('lfs')
--
-- in your *"DCS World OpenBeta/Scripts/MissionScripting.lua"* file.
--
-- But be aware that these changes can make you system vulnerable to attacks.
--
-- # Disclaimer
--
-- **Profiling itself is CPU expensive!** Don't use this when you want to fly or host a mission.
--
--
-- # Start -- # Start
-- --
-- The profiler can simply be started with the @{#PROFILER.Start}(*Delay, Duration*) function -- The profiler can simply be started with the @{#PROFILER.Start}(*Delay, Duration*) function
-- --
-- PROFILER.Start() -- PROFILER.Start()
-- --
-- The optional parameter *Delay* can be used to delay the start by a certain amount of seconds and the optional parameter *Duration* can be used to -- The optional parameter *Delay* can be used to delay the start by a certain amount of seconds and the optional parameter *Duration* can be used to
-- stop the profiler after a certain amount of seconds. -- stop the profiler after a certain amount of seconds.
-- --
-- # Stop -- # Stop
-- --
-- The profiler automatically stops when the mission ends. But it can be stopped any time with the @{#PROFILER.Stop}(*Delay*) function -- The profiler automatically stops when the mission ends. But it can be stopped any time with the @{#PROFILER.Stop}(*Delay*) function
-- --
-- PROFILER.Stop() -- PROFILER.Stop()
-- --
-- The optional parameter *Delay* can be used to specify a delay after which the profiler is stopped. -- The optional parameter *Delay* can be used to specify a delay after which the profiler is stopped.
-- --
-- When the profiler is stopped, the output is written to a file. -- When the profiler is stopped, the output is written to a file.
-- --
-- # Output -- # Output
-- --
-- The profiler output is written to a file in your DCS home folder -- The profiler output is written to a file in your DCS home folder
-- --
-- X:\User\<Your User Name>\Saved Games\DCS OpenBeta\Logs -- X:\User\<Your User Name>\Saved Games\DCS OpenBeta\Logs
-- --
-- The default file name is "MooseProfiler.txt". If that file exists, the file name is "MooseProfiler-001.txt" etc. -- The default file name is "MooseProfiler.txt". If that file exists, the file name is "MooseProfiler-001.txt" etc.
-- --
-- ## Data -- ## Data
-- --
-- The data in the output file provides information on the functions that were called in the mission. -- The data in the output file provides information on the functions that were called in the mission.
-- --
-- It will tell you how many times a function was called in total, how many times per second, how much time in total and the percentage of time. -- It will tell you how many times a function was called in total, how many times per second, how much time in total and the percentage of time.
-- --
-- If you only want output for functions that are called more than *X* times per second, you can set -- If you only want output for functions that are called more than *X* times per second, you can set
-- --
-- PROFILER.ThreshCPS=1.5 -- PROFILER.ThreshCPS=1.5
-- --
-- With this setting, only functions which are called more than 1.5 times per second are displayed. The default setting is PROFILER.ThreshCPS=0.0 (no threshold). -- With this setting, only functions which are called more than 1.5 times per second are displayed. The default setting is PROFILER.ThreshCPS=0.0 (no threshold).
-- --
-- Furthermore, you can limit the output for functions that consumed a certain amount of CPU time in total by -- Furthermore, you can limit the output for functions that consumed a certain amount of CPU time in total by
-- --
-- PROFILER.ThreshTtot=0.005 -- PROFILER.ThreshTtot=0.005
-- --
-- With this setting, which is also the default, only functions which in total used more than 5 milliseconds CPU time. -- With this setting, which is also the default, only functions which in total used more than 5 milliseconds CPU time.
-- --
-- @field #PROFILER -- @field #PROFILER
PROFILER = { PROFILER = {
ClassName = "PROFILER", ClassName = "PROFILER",
@ -128,11 +140,11 @@ function PROFILER.Start(Delay, Duration)
if not io then if not io then
env.error("ERROR: Profiler needs io to be desanitized!") env.error("ERROR: Profiler needs io to be desanitized!")
go=false go=false
end end
if not lfs then if not lfs then
env.error("ERROR: Profiler needs lfs to be desanitized!") env.error("ERROR: Profiler needs lfs to be desanitized!")
go=false go=false
end end
if not go then if not go then
return return
end end
@ -140,14 +152,14 @@ function PROFILER.Start(Delay, Duration)
if Delay and Delay>0 then if Delay and Delay>0 then
BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration) BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration)
else else
-- Set start time. -- Set start time.
PROFILER.TstartGame=timer.getTime() PROFILER.TstartGame=timer.getTime()
PROFILER.TstartOS=os.clock() PROFILER.TstartOS=os.clock()
-- Add event handler. -- Add event handler.
world.addEventHandler(PROFILER.eventHandler) world.addEventHandler(PROFILER.eventHandler)
-- Info in log. -- Info in log.
env.info('############################ Profiler Started ############################') env.info('############################ Profiler Started ############################')
if Duration then if Duration then
@ -160,22 +172,22 @@ function PROFILER.Start(Delay, Duration)
env.info(string.format("- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename(PROFILER.fileNameSuffix))) env.info(string.format("- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename(PROFILER.fileNameSuffix)))
env.info(string.format("- Output file \"%s\" in CSV format", PROFILER.getfilename("csv"))) env.info(string.format("- Output file \"%s\" in CSV format", PROFILER.getfilename("csv")))
env.info('###############################################################################') env.info('###############################################################################')
-- Message on screen -- Message on screen
local duration=Duration or 600 local duration=Duration or 600
trigger.action.outText("### Profiler running ###", duration) trigger.action.outText("### Profiler running ###", duration)
-- Set hook. -- Set hook.
debug.sethook(PROFILER.hook, "cr") debug.sethook(PROFILER.hook, "cr")
-- Auto stop profiler. -- Auto stop profiler.
if Duration then if Duration then
PROFILER.Stop(Duration) PROFILER.Stop(Duration)
end end
end end
end end
--- Stop profiler. --- Stop profiler.
@ -183,24 +195,24 @@ end
function PROFILER.Stop(Delay) function PROFILER.Stop(Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
BASE:ScheduleOnce(Delay, PROFILER.Stop) BASE:ScheduleOnce(Delay, PROFILER.Stop)
else else
-- Remove hook. -- Remove hook.
debug.sethook() debug.sethook()
-- Run time game. -- Run time game.
local runTimeGame=timer.getTime()-PROFILER.TstartGame local runTimeGame=timer.getTime()-PROFILER.TstartGame
-- Run time real OS. -- Run time real OS.
local runTimeOS=os.clock()-PROFILER.TstartOS local runTimeOS=os.clock()-PROFILER.TstartOS
-- Show info. -- Show info.
PROFILER.showInfo(runTimeGame, runTimeOS) PROFILER.showInfo(runTimeGame, runTimeOS)
end end
end end
@ -221,35 +233,35 @@ end
function PROFILER.hook(event) function PROFILER.hook(event)
local f=debug.getinfo(2, "f").func local f=debug.getinfo(2, "f").func
if event=='call' then if event=='call' then
if PROFILER.Counters[f]==nil then if PROFILER.Counters[f]==nil then
PROFILER.Counters[f]=1 PROFILER.Counters[f]=1
PROFILER.dInfo[f]=debug.getinfo(2,"Sn") PROFILER.dInfo[f]=debug.getinfo(2,"Sn")
if PROFILER.fTimeTotal[f]==nil then if PROFILER.fTimeTotal[f]==nil then
PROFILER.fTimeTotal[f]=0 PROFILER.fTimeTotal[f]=0
end end
else else
PROFILER.Counters[f]=PROFILER.Counters[f]+1 PROFILER.Counters[f]=PROFILER.Counters[f]+1
end end
if PROFILER.fTime[f]==nil then if PROFILER.fTime[f]==nil then
PROFILER.fTime[f]=os.clock() PROFILER.fTime[f]=os.clock()
end end
elseif (event=='return') then elseif (event=='return') then
if PROFILER.fTime[f]~=nil then if PROFILER.fTime[f]~=nil then
PROFILER.fTimeTotal[f]=PROFILER.fTimeTotal[f]+(os.clock()-PROFILER.fTime[f]) PROFILER.fTimeTotal[f]=PROFILER.fTimeTotal[f]+(os.clock()-PROFILER.fTime[f])
PROFILER.fTime[f]=nil PROFILER.fTime[f]=nil
end end
end end
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -265,12 +277,12 @@ end
function PROFILER.getData(func) function PROFILER.getData(func)
local n=PROFILER.dInfo[func] local n=PROFILER.dInfo[func]
if n.what=="C" then if n.what=="C" then
return n.name, "?", "?", PROFILER.fTimeTotal[func] return n.name, "?", "?", PROFILER.fTimeTotal[func]
end end
return n.name, n.short_src, n.linedefined, PROFILER.fTimeTotal[func] return n.name, n.short_src, n.linedefined, PROFILER.fTimeTotal[func]
end end
--- Write text to log file. --- Write text to log file.
@ -287,24 +299,24 @@ end
function PROFILER.showTable(data, f, runTimeGame) function PROFILER.showTable(data, f, runTimeGame)
-- Loop over data. -- Loop over data.
for i=1, #data do for i=1, #data do
local t=data[i] --#PROFILER.Data local t=data[i] --#PROFILER.Data
-- Calls per second. -- Calls per second.
local cps=t.count/runTimeGame local cps=t.count/runTimeGame
local threshCPS=cps>=PROFILER.ThreshCPS local threshCPS=cps>=PROFILER.ThreshCPS
local threshTot=t.tm>=PROFILER.ThreshTtot local threshTot=t.tm>=PROFILER.ThreshTtot
if threshCPS and threshTot then if threshCPS and threshTot then
-- Output -- Output
local text=string.format("%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line)) local text=string.format("%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line))
PROFILER._flog(f, text) PROFILER._flog(f, text)
end end
end end
end end
--- Print csv file. --- Print csv file.
@ -319,20 +331,20 @@ function PROFILER.printCSV(data, runTimeGame)
-- Header. -- Header.
local text="Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number," local text="Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
g:write(text.."\r\n") g:write(text.."\r\n")
-- Loop over data. -- Loop over data.
for i=1, #data do for i=1, #data do
local t=data[i] --#PROFILER.Data local t=data[i] --#PROFILER.Data
-- Calls per second. -- Calls per second.
local cps=t.count/runTimeGame local cps=t.count/runTimeGame
-- Output -- Output
local txt=string.format("%s,%d,%.1f,%.3f,%.3f,%.3f,%s,%s,", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line)) local txt=string.format("%s,%d,%.1f,%.3f,%.3f,%.3f,%s,%s,", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line))
g:write(txt.."\r\n") g:write(txt.."\r\n")
end end
-- Close file. -- Close file.
g:close() g:close()
end end
@ -344,23 +356,23 @@ end
function PROFILER.getfilename(ext) function PROFILER.getfilename(ext)
local dir=lfs.writedir()..[[Logs\]] local dir=lfs.writedir()..[[Logs\]]
ext=ext or PROFILER.fileNameSuffix ext=ext or PROFILER.fileNameSuffix
local file=dir..PROFILER.fileNamePrefix.."."..ext local file=dir..PROFILER.fileNamePrefix.."."..ext
if not UTILS.FileExists(file) then if not UTILS.FileExists(file) then
return file return file
end end
for i=1,999 do for i=1,999 do
local file=string.format("%s%s-%03d.%s", dir,PROFILER.fileNamePrefix, i, ext) local file=string.format("%s%s-%03d.%s", dir,PROFILER.fileNamePrefix, i, ext)
if not UTILS.FileExists(file) then if not UTILS.FileExists(file) then
return file return file
end end
end end
end end
@ -372,30 +384,30 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
-- Output file. -- Output file.
local file=PROFILER.getfilename(PROFILER.fileNameSuffix) local file=PROFILER.getfilename(PROFILER.fileNameSuffix)
local f=io.open(file, 'w') local f=io.open(file, 'w')
-- Gather data. -- Gather data.
local Ttot=0 local Ttot=0
local Calls=0 local Calls=0
local t={} local t={}
local tcopy=nil --#PROFILER.Data local tcopy=nil --#PROFILER.Data
local tserialize=nil --#PROFILER.Data local tserialize=nil --#PROFILER.Data
local tforgen=nil --#PROFILER.Data local tforgen=nil --#PROFILER.Data
local tpairs=nil --#PROFILER.Data local tpairs=nil --#PROFILER.Data
for func, count in pairs(PROFILER.Counters) do for func, count in pairs(PROFILER.Counters) do
local s,src,line,tm=PROFILER.getData(func) local s,src,line,tm=PROFILER.getData(func)
if PROFILER.logUnknown==true then if PROFILER.logUnknown==true then
if s==nil then s="<Unknown>" end if s==nil then s="<Unknown>" end
end end
if s~=nil then if s~=nil then
-- Profile data. -- Profile data.
local T= local T=
{ func=s, { func=s,
@ -404,7 +416,7 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
count=count, count=count,
tm=tm, tm=tm,
} --#PROFILER.Data } --#PROFILER.Data
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data. -- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
if s=="_copy" then if s=="_copy" then
if tcopy==nil then if tcopy==nil then
@ -419,49 +431,49 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
else else
tserialize.count=tserialize.count+T.count tserialize.count=tserialize.count+T.count
tserialize.tm=tserialize.tm+T.tm tserialize.tm=tserialize.tm+T.tm
end end
elseif s=="(for generator)" then elseif s=="(for generator)" then
if tforgen==nil then if tforgen==nil then
tforgen=T tforgen=T
else else
tforgen.count=tforgen.count+T.count tforgen.count=tforgen.count+T.count
tforgen.tm=tforgen.tm+T.tm tforgen.tm=tforgen.tm+T.tm
end end
elseif s=="pairs" then elseif s=="pairs" then
if tpairs==nil then if tpairs==nil then
tpairs=T tpairs=T
else else
tpairs.count=tpairs.count+T.count tpairs.count=tpairs.count+T.count
tpairs.tm=tpairs.tm+T.tm tpairs.tm=tpairs.tm+T.tm
end end
else else
table.insert(t, T) table.insert(t, T)
end end
-- Total function time. -- Total function time.
Ttot=Ttot+tm Ttot=Ttot+tm
-- Total number of calls. -- Total number of calls.
Calls=Calls+count Calls=Calls+count
end end
end end
-- Add special cases. -- Add special cases.
if tcopy then if tcopy then
table.insert(t, tcopy) table.insert(t, tcopy)
end end
if tserialize then if tserialize then
table.insert(t, tserialize) table.insert(t, tserialize)
end end
if tforgen then if tforgen then
table.insert(t, tforgen) table.insert(t, tforgen)
end end
if tpairs then if tpairs then
table.insert(t, tpairs) table.insert(t, tpairs)
end end
env.info('############################ Profiler Stopped ############################') env.info('############################ Profiler Stopped ############################')
env.info(string.format("* Runtime Game : %s = %d sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame)) env.info(string.format("* Runtime Game : %s = %d sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame))
env.info(string.format("* Runtime Real : %s = %d sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS)) env.info(string.format("* Runtime Real : %s = %d sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS))
@ -470,11 +482,11 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
env.info(string.format("* Total func calls : %d", Calls)) env.info(string.format("* Total func calls : %d", Calls))
env.info(string.format("* Writing to file : \"%s\"", file)) env.info(string.format("* Writing to file : \"%s\"", file))
env.info(string.format("* Writing to file : \"%s\"", PROFILER.getfilename("csv"))) env.info(string.format("* Writing to file : \"%s\"", PROFILER.getfilename("csv")))
env.info("##############################################################################") env.info("##############################################################################")
-- Sort by total time. -- Sort by total time.
table.sort(t, function(a,b) return a.tm>b.tm end) table.sort(t, function(a,b) return a.tm>b.tm end)
-- Write data. -- Write data.
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog(f,"************************************************************************************************************************")
@ -493,7 +505,7 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER._flog(f,string.format("* Total func calls = %d", Calls)) PROFILER._flog(f,string.format("* Total func calls = %d", Calls))
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER._flog(f,string.format("* Calls per second threshold = %.3f/sec", PROFILER.ThreshCPS)) PROFILER._flog(f,string.format("* Calls per second threshold = %.3f/sec", PROFILER.ThreshCPS))
PROFILER._flog(f,string.format("* Total func time threshold = %.3f sec", PROFILER.ThreshTtot)) PROFILER._flog(f,string.format("* Total func time threshold = %.3f sec", PROFILER.ThreshTtot))
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"") PROFILER._flog(f,"")
@ -501,7 +513,7 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
-- Sort by number of calls. -- Sort by number of calls.
table.sort(t, function(a,b) return a.tm/a.count>b.tm/b.count end) table.sort(t, function(a,b) return a.tm/a.count>b.tm/b.count end)
-- Detailed data. -- Detailed data.
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog(f,"************************************************************************************************************************")
@ -511,10 +523,10 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER._flog(f,"--------------------------------------") PROFILER._flog(f,"--------------------------------------")
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER.showTable(t, f, runTimeGame) PROFILER.showTable(t, f, runTimeGame)
-- Sort by number of calls. -- Sort by number of calls.
table.sort(t, function(a,b) return a.count>b.count end) table.sort(t, function(a,b) return a.count>b.count end)
-- Detailed data. -- Detailed data.
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog(f,"************************************************************************************************************************")
@ -524,7 +536,7 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER._flog(f,"------------------------------------") PROFILER._flog(f,"------------------------------------")
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER.showTable(t, f, runTimeGame) PROFILER.showTable(t, f, runTimeGame)
-- Closing. -- Closing.
PROFILER._flog(f,"") PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog(f,"************************************************************************************************************************")
@ -532,8 +544,7 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog(f,"************************************************************************************************************************")
-- Close file. -- Close file.
f:close() f:close()
-- Print csv file. -- Print csv file.
PROFILER.printCSV(t, runTimeGame) PROFILER.printCSV(t, runTimeGame)
end end

View File

@ -461,19 +461,19 @@ function AIRBASE:Register(AirbaseName)
-- Inherit everything from positionable. -- Inherit everything from positionable.
local self=BASE:Inherit(self, POSITIONABLE:New(AirbaseName)) --#AIRBASE local self=BASE:Inherit(self, POSITIONABLE:New(AirbaseName)) --#AIRBASE
-- Set airbase name. -- Set airbase name.
self.AirbaseName=AirbaseName self.AirbaseName=AirbaseName
-- Set airbase ID. -- Set airbase ID.
self.AirbaseID=self:GetID(true) self.AirbaseID=self:GetID(true)
-- Get descriptors. -- Get descriptors.
self.descriptors=self:GetDesc() self.descriptors=self:GetDesc()
-- Category. -- Category.
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
-- Set category. -- Set category.
if self.category==Airbase.Category.AIRDROME then if self.category==Airbase.Category.AIRDROME then
self.isAirdrome=true self.isAirdrome=true
@ -484,14 +484,14 @@ function AIRBASE:Register(AirbaseName)
else else
self:E("ERROR: Unknown airbase category!") self:E("ERROR: Unknown airbase category!")
end end
self:_InitParkingSpots() self:_InitParkingSpots()
local vec2=self:GetVec2() local vec2=self:GetVec2()
-- Init coordinate. -- Init coordinate.
self:GetCoordinate() self:GetCoordinate()
if vec2 then if vec2 then
-- TODO: For ships we need a moving zone. -- TODO: For ships we need a moving zone.
self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 ) self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
@ -628,7 +628,7 @@ function AIRBASE:GetID(unique)
local airbaseID=tonumber(DCSAirbase:getID()) local airbaseID=tonumber(DCSAirbase:getID())
local airbaseCategory=self:GetAirbaseCategory() local airbaseCategory=self:GetAirbaseCategory()
if AirbaseName==self.AirbaseName then if AirbaseName==self.AirbaseName then
if airbaseCategory==Airbase.Category.SHIP or airbaseCategory==Airbase.Category.HELIPAD then if airbaseCategory==Airbase.Category.SHIP or airbaseCategory==Airbase.Category.HELIPAD then
-- Ships get a negative sign as their unit number might be the same as the ID of another airbase. -- Ships get a negative sign as their unit number might be the same as the ID of another airbase.
@ -819,16 +819,16 @@ function AIRBASE:_InitParkingSpots()
-- Init table. -- Init table.
self.parking={} self.parking={}
self.parkingByID={} self.parkingByID={}
self.NparkingTotal=0 self.NparkingTotal=0
self.NparkingTerminal={} self.NparkingTerminal={}
for _,terminalType in pairs(AIRBASE.TerminalType) do for _,terminalType in pairs(AIRBASE.TerminalType) do
self.NparkingTerminal[terminalType]=0 self.NparkingTerminal[terminalType]=0
end end
-- Put coordinates of parking spots into table. -- Put coordinates of parking spots into table.
for _,spot in pairs(parkingdata) do for _,spot in pairs(parkingdata) do
-- New parking spot. -- New parking spot.
local park={} --#AIRBASE.ParkingSpot local park={} --#AIRBASE.ParkingSpot
park.Vec3=spot.vTerminalPos park.Vec3=spot.vTerminalPos
@ -839,13 +839,13 @@ function AIRBASE:_InitParkingSpots()
park.TerminalID0=spot.Term_Index_0 park.TerminalID0=spot.Term_Index_0
park.TerminalType=spot.Term_Type park.TerminalType=spot.Term_Type
park.TOAC=spot.TO_AC park.TOAC=spot.TO_AC
for _,terminalType in pairs(AIRBASE.TerminalType) do for _,terminalType in pairs(AIRBASE.TerminalType) do
if self._CheckTerminalType(terminalType, park.TerminalType) then if self._CheckTerminalType(terminalType, park.TerminalType) then
self.NparkingTerminal[terminalType]=self.NparkingTerminal[terminalType]+1 self.NparkingTerminal[terminalType]=self.NparkingTerminal[terminalType]+1
end end
end end
self.parkingByID[park.TerminalID]=park self.parkingByID[park.TerminalID]=park
table.insert(self.parking, park) table.insert(self.parking, park)
end end
@ -869,7 +869,7 @@ function AIRBASE:GetParkingSpotsTable(termtype)
-- Get parking data of all spots (free or occupied) -- Get parking data of all spots (free or occupied)
local parkingdata=self:GetParkingData(false) local parkingdata=self:GetParkingData(false)
-- Get parking data of all free spots. -- Get parking data of all free spots.
local parkingfree=self:GetParkingData(true) local parkingfree=self:GetParkingData(true)
@ -886,17 +886,17 @@ function AIRBASE:GetParkingSpotsTable(termtype)
-- Put coordinates of parking spots into table. -- Put coordinates of parking spots into table.
local spots={} local spots={}
for _,_spot in pairs(parkingdata) do for _,_spot in pairs(parkingdata) do
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then
local spot=self:_GetParkingSpotByID(_spot.Term_Index) local spot=self:_GetParkingSpotByID(_spot.Term_Index)
spot.Free=_isfree(_spot) -- updated spot.Free=_isfree(_spot) -- updated
spot.TOAC=_spot.TO_AC -- updated spot.TOAC=_spot.TO_AC -- updated
table.insert(spots, spot) table.insert(spots, spot)
end end
end end
return spots return spots
@ -917,14 +917,14 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
for _,_spot in pairs(parkingfree) do for _,_spot in pairs(parkingfree) do
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
local spot=self:_GetParkingSpotByID(_spot.Term_Index) local spot=self:_GetParkingSpotByID(_spot.Term_Index)
spot.Free=true -- updated spot.Free=true -- updated
spot.TOAC=_spot.TO_AC -- updated spot.TOAC=_spot.TO_AC -- updated
table.insert(freespots, spot) table.insert(freespots, spot)
end end
end end
end end
@ -1245,7 +1245,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
-- Get spawn points on runway. These can be used to determine the runway heading. -- Get spawn points on runway. These can be used to determine the runway heading.
local runwaycoords=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway) local runwaycoords=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
-- Debug: For finding the numbers of the spawn points belonging to each runway. -- Debug: For finding the numbers of the spawn points belonging to each runway.
if false then if false then
for i,_coord in pairs(runwaycoords) do for i,_coord in pairs(runwaycoords) do
@ -1264,7 +1264,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
-- Airbase name. -- Airbase name.
local name=self:GetName() local name=self:GetName()
-- Exceptions -- Exceptions
if name==AIRBASE.Nevada.Jean_Airport or if name==AIRBASE.Nevada.Jean_Airport or
@ -1277,35 +1277,35 @@ function AIRBASE:GetRunwayData(magvar, mark)
-- 1-->4, 2-->3, 3-->2, 4-->1 -- 1-->4, 2-->3, 3-->2, 4-->1
exception=1 exception=1
elseif UTILS.GetDCSMap()==DCSMAP.Syria and N>=2 and elseif UTILS.GetDCSMap()==DCSMAP.Syria and N>=2 and
name~=AIRBASE.Syria.Minakh and name~=AIRBASE.Syria.Minakh and
name~=AIRBASE.Syria.Damascus and name~=AIRBASE.Syria.Damascus and
name~=AIRBASE.Syria.Khalkhalah and name~=AIRBASE.Syria.Khalkhalah and
name~=AIRBASE.Syria.Marj_Ruhayyil and name~=AIRBASE.Syria.Marj_Ruhayyil and
name~=AIRBASE.Syria.Beirut_Rafic_Hariri then name~=AIRBASE.Syria.Beirut_Rafic_Hariri then
-- 1-->3, 2-->4, 3-->1, 4-->2 -- 1-->3, 2-->4, 3-->1, 4-->2
exception=2 exception=2
end end
local function f(i) local function f(i)
local j local j
if exception==1 then if exception==1 then
j=N-(i+1) -- 1-->4, 2-->3 j=N-(i+1) -- 1-->4, 2-->3
elseif exception==2 then elseif exception==2 then
if i<=N2 then if i<=N2 then
j=i+N2 -- 1-->3, 2-->4 j=i+N2 -- 1-->3, 2-->4
else else
j=i-N2 -- 3-->1, 4-->3 j=i-N2 -- 3-->1, 4-->3
end end
else else
if i%2==0 then if i%2==0 then
@ -1313,9 +1313,9 @@ function AIRBASE:GetRunwayData(magvar, mark)
else else
j=i+1 -- odd 1-->2, 3-->4 j=i+1 -- odd 1-->2, 3-->4
end end
end end
-- Special case where there is no obvious order. -- Special case where there is no obvious order.
if name==AIRBASE.Syria.Beirut_Rafic_Hariri then if name==AIRBASE.Syria.Beirut_Rafic_Hariri then
if i==1 then if i==1 then
@ -1348,7 +1348,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
j=2 j=2
end end
end end
return j return j
end end

View File

@ -1,5 +1,5 @@
--- **Wrapper** - Markers On the F10 map. --- **Wrapper** - Markers On the F10 map.
-- --
-- **Main Features:** -- **Main Features:**
-- --
-- * Convenient handling of markers via multiple user API functions. -- * Convenient handling of markers via multiple user API functions.
@ -8,7 +8,7 @@
-- * Retrieve data such as text and coordinate. -- * Retrieve data such as text and coordinate.
-- * Marker specific FSM events when a marker is added, removed or changed. -- * Marker specific FSM events when a marker is added, removed or changed.
-- * Additional FSM events when marker text or position is changed. -- * Additional FSM events when marker text or position is changed.
-- --
-- === -- ===
-- --
-- ### Author: **funkyfranky** -- ### Author: **funkyfranky**
@ -36,104 +36,104 @@
-- ![Banner Image](..\Presentations\MARKER\Marker_Main.jpg) -- ![Banner Image](..\Presentations\MARKER\Marker_Main.jpg)
-- --
-- # The MARKER Class Idea -- # The MARKER Class Idea
-- --
-- The MARKER class simplifies creating, updating and removing of markers on the F10 map. -- The MARKER class simplifies creating, updating and removing of markers on the F10 map.
-- --
-- # Create a Marker -- # Create a Marker
-- --
-- -- Create a MARKER object at Batumi with a trivial text. -- -- Create a MARKER object at Batumi with a trivial text.
-- local Coordinate=AIRBASE:FindByName("Batumi"):GetCoordinate() -- local Coordinate=AIRBASE:FindByName("Batumi"):GetCoordinate()
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield") -- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield")
-- --
-- Now this does **not** show the marker yet. We still need to specifiy to whom it is shown. There are several options, i.e. -- Now this does **not** show the marker yet. We still need to specifiy to whom it is shown. There are several options, i.e.
-- show the marker to everyone, to a speficic coaliton only, or only to a specific group. -- show the marker to everyone, to a speficic coaliton only, or only to a specific group.
-- --
-- ## For Everyone -- ## For Everyone
-- --
-- If the marker should be visible to everyone, you can use the :ToAll() function. -- If the marker should be visible to everyone, you can use the :ToAll() function.
-- --
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToAll() -- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToAll()
-- --
-- ## For a Coaliton -- ## For a Coaliton
-- --
-- If the maker should be visible to a specific coalition, you can use the :ToCoalition() function. -- If the maker should be visible to a specific coalition, you can use the :ToCoalition() function.
-- --
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToCoaliton(coaliton.side.BLUE) -- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToCoaliton(coaliton.side.BLUE)
-- --
-- ### To Blue Coaliton -- ### To Blue Coaliton
-- --
-- ### To Red Coalition -- ### To Red Coalition
-- --
-- This would show the marker only to the Blue coaliton. -- This would show the marker only to the Blue coaliton.
-- --
-- ## For a Group -- ## For a Group
-- --
-- --
-- # Removing a Marker -- # Removing a Marker
-- --
-- --
-- # Updating a Marker -- # Updating a Marker
-- --
-- The marker text and coordinate can be updated easily as shown below. -- The marker text and coordinate can be updated easily as shown below.
-- --
-- However, note that **updateing involves to remove and recreate the marker if either text or its coordinate is changed**. -- However, note that **updateing involves to remove and recreate the marker if either text or its coordinate is changed**.
-- *This is a DCS scripting engine limitation.* -- *This is a DCS scripting engine limitation.*
-- --
-- ## Update Text -- ## Update Text
-- --
-- If you created a marker "mymarker" as shown above, you can update the dispayed test by -- If you created a marker "mymarker" as shown above, you can update the dispayed test by
-- --
-- mymarker:UpdateText("I am the new text at Batumi") -- mymarker:UpdateText("I am the new text at Batumi")
-- --
-- The update can also be delayed by, e.g. 90 seconds, using -- The update can also be delayed by, e.g. 90 seconds, using
-- --
-- mymarker:UpdateText("I am the new text at Batumi", 90) -- mymarker:UpdateText("I am the new text at Batumi", 90)
-- --
-- ## Update Coordinate -- ## Update Coordinate
-- --
-- If you created a marker "mymarker" as shown above, you can update its coordinate on the F10 map by -- If you created a marker "mymarker" as shown above, you can update its coordinate on the F10 map by
-- --
-- mymarker:UpdateCoordinate(NewCoordinate) -- mymarker:UpdateCoordinate(NewCoordinate)
-- --
-- The update can also be delayed by, e.g. 60 seconds, using -- The update can also be delayed by, e.g. 60 seconds, using
-- --
-- mymarker:UpdateCoordinate(NewCoordinate, 60) -- mymarker:UpdateCoordinate(NewCoordinate, 60)
-- --
-- # Retrieve Data -- # Retrieve Data
-- --
-- The important data as the displayed text and the coordinate of the marker can be retrieved easily. -- The important data as the displayed text and the coordinate of the marker can be retrieved easily.
-- --
-- ## Text -- ## Text
-- --
-- local text=mymarker:GetText() -- local text=mymarker:GetText()
-- env.info("Marker Text = " .. text) -- env.info("Marker Text = " .. text)
-- --
-- ## Coordinate -- ## Coordinate
-- --
-- local Coordinate=mymarker:GetCoordinate() -- local Coordinate=mymarker:GetCoordinate()
-- env.info("Marker Coordinate LL DSM = " .. Coordinate:ToStringLLDMS()) -- env.info("Marker Coordinate LL DSM = " .. Coordinate:ToStringLLDMS())
-- --
-- --
-- # FSM Events -- # FSM Events
-- --
-- Moose creates addditonal events, so called FSM event, when markers are added, changed, removed, and text or the coordianteis updated. -- Moose creates addditonal events, so called FSM event, when markers are added, changed, removed, and text or the coordianteis updated.
-- --
-- These events can be captured and used for processing via OnAfter functions as shown below. -- These events can be captured and used for processing via OnAfter functions as shown below.
-- --
-- ## Added -- ## Added
-- --
-- ## Changed -- ## Changed
-- --
-- ## Removed -- ## Removed
-- --
-- ## TextUpdate -- ## TextUpdate
-- --
-- ## CoordUpdate -- ## CoordUpdate
-- --
-- --
-- # Examples -- # Examples
-- --
-- --
-- @field #MARKER -- @field #MARKER
MARKER = { MARKER = {
ClassName = "MARKER", ClassName = "MARKER",
@ -170,29 +170,29 @@ MARKER.version="0.1.0"
--- Create a new MARKER class object. --- Create a new MARKER class object.
-- @param #MARKER self -- @param #MARKER self
-- @param Core.Point#COORDINATE Coordinate Coordinate where to place the marker. -- @param Core.Point#COORDINATE Coordinate Coordinate where to place the marker.
-- @param #string Text Text displayed on the mark panel. -- @param #string Text Text displayed on the mark panel.
-- @return #MARKER self -- @return #MARKER self
function MARKER:New(Coordinate, Text) function MARKER:New(Coordinate, Text)
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, FSM:New()) -- #MARKER local self=BASE:Inherit(self, FSM:New()) -- #MARKER
self.coordinate=Coordinate self.coordinate=Coordinate
self.text=Text self.text=Text
-- Defaults -- Defaults
self.readonly=false self.readonly=false
self.message="" self.message=""
-- New marker ID. This is not the one of the actual marker. -- New marker ID. This is not the one of the actual marker.
_MARKERID=_MARKERID+1 _MARKERID=_MARKERID+1
self.myid=_MARKERID self.myid=_MARKERID
-- Log ID. -- Log ID.
self.lid=string.format("Marker #%d | ", self.myid) self.lid=string.format("Marker #%d | ", self.myid)
-- Start State. -- Start State.
self:SetStartState("Invisible") self:SetStartState("Invisible")
@ -201,7 +201,7 @@ function MARKER:New(Coordinate, Text)
self:AddTransition("Invisible", "Added", "Visible") -- Marker was added. self:AddTransition("Invisible", "Added", "Visible") -- Marker was added.
self:AddTransition("Visible", "Removed", "Invisible") -- Marker was removed. self:AddTransition("Visible", "Removed", "Invisible") -- Marker was removed.
self:AddTransition("*", "Changed", "*") -- Marker was changed. self:AddTransition("*", "Changed", "*") -- Marker was changed.
self:AddTransition("*", "TextUpdate", "*") -- Text updated. self:AddTransition("*", "TextUpdate", "*") -- Text updated.
self:AddTransition("*", "CoordUpdate", "*") -- Coordinates updated. self:AddTransition("*", "CoordUpdate", "*") -- Coordinates updated.
@ -304,8 +304,8 @@ function MARKER:New(Coordinate, Text)
self:HandleEvent(EVENTS.MarkAdded) self:HandleEvent(EVENTS.MarkAdded)
self:HandleEvent(EVENTS.MarkRemoved) self:HandleEvent(EVENTS.MarkRemoved)
self:HandleEvent(EVENTS.MarkChange) self:HandleEvent(EVENTS.MarkChange)
return self return self
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -318,7 +318,7 @@ end
function MARKER:ReadOnly() function MARKER:ReadOnly()
self.readonly=true self.readonly=true
return self return self
end end
@ -329,7 +329,7 @@ end
function MARKER:Message(Text) function MARKER:Message(Text)
self.message=Text or "" self.message=Text or ""
return self return self
end end
@ -349,14 +349,14 @@ function MARKER:ToAll(Delay)
self.togroup=nil self.togroup=nil
self.groupname=nil self.groupname=nil
self.groupid=nil self.groupid=nil
-- First remove an existing mark. -- First remove an existing mark.
if self.shown then if self.shown then
self:Remove() self:Remove()
end end
self.mid=UTILS.GetMarkID() self.mid=UTILS.GetMarkID()
-- Call DCS function. -- Call DCS function.
trigger.action.markToAll(self.mid, self.text, self.coordinate:GetVec3(), self.readonly, self.message) trigger.action.markToAll(self.mid, self.text, self.coordinate:GetVec3(), self.readonly, self.message)
@ -377,25 +377,25 @@ function MARKER:ToCoalition(Coalition, Delay)
else else
self.coalition=Coalition self.coalition=Coalition
self.tocoaliton=true self.tocoaliton=true
self.toall=false self.toall=false
self.togroup=false self.togroup=false
self.groupname=nil self.groupname=nil
self.groupid=nil self.groupid=nil
-- First remove an existing mark. -- First remove an existing mark.
if self.shown then if self.shown then
self:Remove() self:Remove()
end end
self.mid=UTILS.GetMarkID() self.mid=UTILS.GetMarkID()
-- Call DCS function. -- Call DCS function.
trigger.action.markToCoalition(self.mid, self.text, self.coordinate:GetVec3(), self.coalition, self.readonly, self.message) trigger.action.markToCoalition(self.mid, self.text, self.coordinate:GetVec3(), self.coalition, self.readonly, self.message)
end end
return self return self
end end
@ -440,36 +440,36 @@ function MARKER:ToGroup(Group, Delay)
-- Check if group exists. -- Check if group exists.
if Group and Group:IsAlive()~=nil then if Group and Group:IsAlive()~=nil then
self.groupid=Group:GetID() self.groupid=Group:GetID()
if self.groupid then if self.groupid then
self.groupname=Group:GetName() self.groupname=Group:GetName()
self.togroup=true self.togroup=true
self.tocoaliton=nil self.tocoaliton=nil
self.coalition=nil self.coalition=nil
self.toall=nil self.toall=nil
-- First remove an existing mark. -- First remove an existing mark.
if self.shown then if self.shown then
self:Remove() self:Remove()
end end
self.mid=UTILS.GetMarkID() self.mid=UTILS.GetMarkID()
-- Call DCS function. -- Call DCS function.
trigger.action.markToGroup(self.mid, self.text, self.coordinate:GetVec3(), self.groupid, self.readonly, self.message) trigger.action.markToGroup(self.mid, self.text, self.coordinate:GetVec3(), self.groupid, self.readonly, self.message)
end end
else else
--TODO: Warning! --TODO: Warning!
end end
end end
return self return self
end end
@ -482,14 +482,14 @@ function MARKER:UpdateText(Text, Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
self:ScheduleOnce(Delay, MARKER.UpdateText, self, Text) self:ScheduleOnce(Delay, MARKER.UpdateText, self, Text)
else else
self.text=tostring(Text) self.text=tostring(Text)
self:Refresh() self:Refresh()
self:TextUpdate(tostring(Text)) self:TextUpdate(tostring(Text))
end end
return self return self
@ -504,14 +504,14 @@ function MARKER:UpdateCoordinate(Coordinate, Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
self:ScheduleOnce(Delay, MARKER.UpdateCoordinate, self, Coordinate) self:ScheduleOnce(Delay, MARKER.UpdateCoordinate, self, Coordinate)
else else
self.coordinate=Coordinate self.coordinate=Coordinate
self:Refresh() self:Refresh()
self:CoordUpdate(Coordinate) self:CoordUpdate(Coordinate)
end end
return self return self
@ -525,26 +525,26 @@ function MARKER:Refresh(Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
self:ScheduleOnce(Delay, MARKER.Refresh, self) self:ScheduleOnce(Delay, MARKER.Refresh, self)
else else
if self.toall then if self.toall then
self:ToAll() self:ToAll()
elseif self.tocoaliton then elseif self.tocoaliton then
self:ToCoalition(self.coalition) self:ToCoalition(self.coalition)
elseif self.togroup then elseif self.togroup then
local group=GROUP:FindByName(self.groupname) local group=GROUP:FindByName(self.groupname)
self:ToGroup(group) self:ToGroup(group)
else else
self:E(self.lid.."ERROR: unknown To in :Refresh()!") self:E(self.lid.."ERROR: unknown To in :Refresh()!")
end end
end end
return self return self
@ -564,9 +564,9 @@ function MARKER:Remove(Delay)
-- Call DCS function. -- Call DCS function.
trigger.action.removeMark(self.mid) trigger.action.removeMark(self.mid)
end end
end end
return self return self
@ -605,7 +605,7 @@ end
--- Check if marker is currently invisible on the F10 map. --- Check if marker is currently invisible on the F10 map.
-- @param #MARKER self -- @param #MARKER self
-- @return -- @return
function MARKER:IsInvisible() function MARKER:IsInvisible()
return self:Is("Invisible") return self:Is("Invisible")
end end
@ -620,17 +620,17 @@ end
function MARKER:OnEventMarkAdded(EventData) function MARKER:OnEventMarkAdded(EventData)
if EventData and EventData.MarkID then if EventData and EventData.MarkID then
local MarkID=EventData.MarkID local MarkID=EventData.MarkID
self:T3(self.lid..string.format("Captured event MarkAdded for Mark ID=%s", tostring(MarkID))) self:T3(self.lid..string.format("Captured event MarkAdded for Mark ID=%s", tostring(MarkID)))
if MarkID==self.mid then if MarkID==self.mid then
self.shown=true self.shown=true
self:Added(EventData) self:Added(EventData)
end end
end end
@ -643,21 +643,21 @@ end
function MARKER:OnEventMarkRemoved(EventData) function MARKER:OnEventMarkRemoved(EventData)
if EventData and EventData.MarkID then if EventData and EventData.MarkID then
local MarkID=EventData.MarkID local MarkID=EventData.MarkID
self:T3(self.lid..string.format("Captured event MarkAdded for Mark ID=%s", tostring(MarkID))) self:T3(self.lid..string.format("Captured event MarkAdded for Mark ID=%s", tostring(MarkID)))
if MarkID==self.mid then if MarkID==self.mid then
self.shown=false self.shown=false
self:Removed(EventData) self:Removed(EventData)
end end
end end
end end
--- Event function when a MARKER changed. --- Event function when a MARKER changed.
@ -666,17 +666,17 @@ end
function MARKER:OnEventMarkChange(EventData) function MARKER:OnEventMarkChange(EventData)
if EventData and EventData.MarkID then if EventData and EventData.MarkID then
local MarkID=EventData.MarkID local MarkID=EventData.MarkID
self:T3(self.lid..string.format("Captured event MarkChange for Mark ID=%s", tostring(MarkID))) self:T3(self.lid..string.format("Captured event MarkChange for Mark ID=%s", tostring(MarkID)))
if MarkID==self.mid then if MarkID==self.mid then
self:Changed(EventData) self:Changed(EventData)
self:TextChanged(tostring(EventData.MarkText)) self:TextChanged(tostring(EventData.MarkText))
end end
end end
@ -696,7 +696,7 @@ end
function MARKER:onafterAdded(From, Event, To, EventData) function MARKER:onafterAdded(From, Event, To, EventData)
-- Debug info. -- Debug info.
local text=string.format("Captured event MarkAdded for myself:\n") local text=string.format("Captured event MarkAdded for myself:\n")
text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID)) text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID))
text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition)) text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition))
text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID)) text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID))
@ -716,7 +716,7 @@ end
function MARKER:onafterRemoved(From, Event, To, EventData) function MARKER:onafterRemoved(From, Event, To, EventData)
-- Debug info. -- Debug info.
local text=string.format("Captured event MarkRemoved for myself:\n") local text=string.format("Captured event MarkRemoved for myself:\n")
text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID)) text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID))
text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition)) text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition))
text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID)) text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID))
@ -736,7 +736,7 @@ end
function MARKER:onafterChanged(From, Event, To, EventData) function MARKER:onafterChanged(From, Event, To, EventData)
-- Debug info. -- Debug info.
local text=string.format("Captured event MarkChange for myself:\n") local text=string.format("Captured event MarkChange for myself:\n")
text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID)) text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID))
text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition)) text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition))
text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID)) text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID))
@ -768,7 +768,7 @@ end
function MARKER:onafterCoordUpdate(From, Event, To, Coordinate) function MARKER:onafterCoordUpdate(From, Event, To, Coordinate)
self:T(self.lid..string.format("New Marker Coordinate in LL DMS: %s", Coordinate:ToStringLLDMS())) self:T(self.lid..string.format("New Marker Coordinate in LL DMS: %s", Coordinate:ToStringLLDMS()))
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------