Formatting and typos (#1652)

* Formatting and typo fixes.

General formatting and typo fixes.

* Update STTS.lua

Keep class table on separate lines.
This commit is contained in:
TommyC81 2021-12-04 21:49:47 +04:00 committed by GitHub
parent 2ba5215036
commit 32deb160ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 2095 additions and 2260 deletions

View File

@ -11,7 +11,7 @@
--
-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit.
--
-- Other Moose classe also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
-- Other Moose classes also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
--
-- @module ENUMS
-- @image MOOSE.JPG
@ -30,16 +30,16 @@ ENUMS = {}
-- @type ENUMS.ROE
-- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target.
-- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking.
-- @field #number OpenFire AI will engage only targets specified in its taskings.
-- @field #number OpenFire AI will engage only targets specified in its tasking.
-- @field #number ReturnFire AI will only engage threats that shoot first.
-- @field #number WeaponHold AI will hold fire under all circumstances.
ENUMS.ROE = {
WeaponFree=0,
OpenFireWeaponFree=1,
OpenFire=2,
ReturnFire=3,
WeaponHold=4,
}
WeaponFree = 0,
OpenFireWeaponFree = 1,
OpenFire = 2,
ReturnFire = 3,
WeaponHold = 4,
}
--- Reaction On Threat.
-- @type ENUMS.ROT
@ -49,11 +49,11 @@ ENUMS.ROE = {
-- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats.
-- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base.
ENUMS.ROT = {
NoReaction=0,
PassiveDefense=1,
EvadeFire=2,
BypassAndEscape=3,
AllowAbortMission=4,
NoReaction = 0,
PassiveDefense = 1,
EvadeFire = 2,
BypassAndEscape = 3,
AllowAbortMission = 4,
}
--- Alarm state.
@ -62,12 +62,12 @@ ENUMS.ROT = {
-- @field #number Green Group is not combat ready. Sensors are stowed if possible.
-- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state.
ENUMS.AlarmState = {
Auto=0,
Green=1,
Red=2,
Auto = 0,
Green = 1,
Red = 2,
}
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerotor on hoggit wiki.
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on Hoggit wiki.
-- @type ENUMS.WeaponFlag
ENUMS.WeaponFlag={
-- Bombs
@ -111,7 +111,7 @@ ENUMS.WeaponFlag={
--
-- Bombs
GuidedBomb = 14, -- (LGB + TvGB + SNSGB)
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb)
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispenser + CandleBomb + ParachuteBomb)
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
--- Rockets
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
@ -173,7 +173,7 @@ ENUMS.MissionTask={
TRANSPORT="Transport",
}
--- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki.
--- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
-- @type ENUMS.Formation
ENUMS.Formation={}
ENUMS.Formation.FixedWing={}
@ -216,23 +216,23 @@ ENUMS.Formation.FixedWing.FighterVic.Close = 917505
ENUMS.Formation.FixedWing.FighterVic.Open = 917506
ENUMS.Formation.RotaryWing={}
ENUMS.Formation.RotaryWing.Column={}
ENUMS.Formation.RotaryWing.Column.D70=720896
ENUMS.Formation.RotaryWing.Column.D70 = 720896
ENUMS.Formation.RotaryWing.Wedge={}
ENUMS.Formation.RotaryWing.Wedge.D70=8
ENUMS.Formation.RotaryWing.Wedge.D70 = 8
ENUMS.Formation.RotaryWing.FrontRight={}
ENUMS.Formation.RotaryWing.FrontRight.D300=655361
ENUMS.Formation.RotaryWing.FrontRight.D600=655362
ENUMS.Formation.RotaryWing.FrontRight.D300 = 655361
ENUMS.Formation.RotaryWing.FrontRight.D600 = 655362
ENUMS.Formation.RotaryWing.FrontLeft={}
ENUMS.Formation.RotaryWing.FrontLeft.D300=655617
ENUMS.Formation.RotaryWing.FrontLeft.D600=655618
ENUMS.Formation.RotaryWing.FrontLeft.D300 = 655617
ENUMS.Formation.RotaryWing.FrontLeft.D600 = 655618
ENUMS.Formation.RotaryWing.EchelonRight={}
ENUMS.Formation.RotaryWing.EchelonRight.D70 =589825
ENUMS.Formation.RotaryWing.EchelonRight.D300=589826
ENUMS.Formation.RotaryWing.EchelonRight.D600=589827
ENUMS.Formation.RotaryWing.EchelonRight.D70 = 589825
ENUMS.Formation.RotaryWing.EchelonRight.D300 = 589826
ENUMS.Formation.RotaryWing.EchelonRight.D600 = 589827
ENUMS.Formation.RotaryWing.EchelonLeft={}
ENUMS.Formation.RotaryWing.EchelonLeft.D70 =590081
ENUMS.Formation.RotaryWing.EchelonLeft.D300=590082
ENUMS.Formation.RotaryWing.EchelonLeft.D600=590083
ENUMS.Formation.RotaryWing.EchelonLeft.D70 = 590081
ENUMS.Formation.RotaryWing.EchelonLeft.D300 = 590082
ENUMS.Formation.RotaryWing.EchelonLeft.D600 = 590083
ENUMS.Formation.Vehicle={}
ENUMS.Formation.Vehicle.Vee="Vee"
ENUMS.Formation.Vehicle.EchelonRight="EchelonR"
@ -244,25 +244,25 @@ ENUMS.Formation.Vehicle.Cone="Cone"
ENUMS.Formation.Vehicle.Diamond="Diamond"
--- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings.
-- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki.
-- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
-- @type ENUMS.FormationOld
ENUMS.FormationOld={}
ENUMS.FormationOld.FixedWing={}
ENUMS.FormationOld.FixedWing.LineAbreast=1
ENUMS.FormationOld.FixedWing.Trail=2
ENUMS.FormationOld.FixedWing.Wedge=3
ENUMS.FormationOld.FixedWing.EchelonRight=4
ENUMS.FormationOld.FixedWing.EchelonLeft=5
ENUMS.FormationOld.FixedWing.FingerFour=6
ENUMS.FormationOld.FixedWing.SpreadFour=7
ENUMS.FormationOld.FixedWing.BomberElement=12
ENUMS.FormationOld.FixedWing.BomberElementHeight=13
ENUMS.FormationOld.FixedWing.FighterVic=14
ENUMS.FormationOld.FixedWing.LineAbreast = 1
ENUMS.FormationOld.FixedWing.Trail = 2
ENUMS.FormationOld.FixedWing.Wedge = 3
ENUMS.FormationOld.FixedWing.EchelonRight = 4
ENUMS.FormationOld.FixedWing.EchelonLeft = 5
ENUMS.FormationOld.FixedWing.FingerFour = 6
ENUMS.FormationOld.FixedWing.SpreadFour = 7
ENUMS.FormationOld.FixedWing.BomberElement = 12
ENUMS.FormationOld.FixedWing.BomberElementHeight = 13
ENUMS.FormationOld.FixedWing.FighterVic = 14
ENUMS.FormationOld.RotaryWing={}
ENUMS.FormationOld.RotaryWing.Wedge=8
ENUMS.FormationOld.RotaryWing.Echelon=9
ENUMS.FormationOld.RotaryWing.Front=10
ENUMS.FormationOld.RotaryWing.Column=11
ENUMS.FormationOld.RotaryWing.Wedge = 8
ENUMS.FormationOld.RotaryWing.Echelon = 9
ENUMS.FormationOld.RotaryWing.Front = 10
ENUMS.FormationOld.RotaryWing.Column = 11
--- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code).

View File

@ -9,7 +9,6 @@
-- @module Utilities.PROFILER
-- @image MOOSE.JPG
--- PROFILER class.
-- @type PROFILER
-- @field #string ClassName Name of the class.
@ -25,7 +24,6 @@
-- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value.
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
-- @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? *
--
-- ===
@ -35,12 +33,11 @@
-- # The PROFILER Concept
--
-- 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 performance of your code.
--
-- # Prerequisites
--
-- The modules **os** and **lfs** need to be desanizied.
--
-- The modules **os** and **lfs** need to be de-sanitized.
--
-- # Start
--
@ -117,61 +114,60 @@ PROFILER = {
--- Start profiler.
-- @param #number Delay Delay in seconds before profiler is stated. Default is immediately.
-- @param #number Duration Duration in (game) seconds before the profiler is stopped. Default is when mission ends.
function PROFILER.Start(Delay, Duration)
function PROFILER.Start( Delay, Duration )
-- Check if os, io and lfs are available.
local go=true
local go = true
if not os then
env.error("ERROR: Profiler needs os to be desanitized!")
go=false
env.error( "ERROR: Profiler needs os to be de-sanitized!" )
go = false
end
if not io then
env.error("ERROR: Profiler needs io to be desanitized!")
go=false
env.error( "ERROR: Profiler needs io to be de-sanitized!" )
go = false
end
if not lfs then
env.error("ERROR: Profiler needs lfs to be desanitized!")
go=false
env.error( "ERROR: Profiler needs lfs to be de-sanitized!" )
go = false
end
if not go then
return
end
if Delay and Delay>0 then
BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration)
if Delay and Delay > 0 then
BASE:ScheduleOnce( Delay, PROFILER.Start, 0, Duration )
else
-- Set start time.
PROFILER.TstartGame=timer.getTime()
PROFILER.TstartOS=os.clock()
PROFILER.TstartGame = timer.getTime()
PROFILER.TstartOS = os.clock()
-- Add event handler.
world.addEventHandler(PROFILER.eventHandler)
world.addEventHandler( PROFILER.eventHandler )
-- Info in log.
env.info('############################ Profiler Started ############################')
env.info( '############################ Profiler Started ############################' )
if Duration then
env.info(string.format("- Will be running for %d seconds", Duration))
env.info( string.format( "- Will be running for %d seconds", Duration ) )
else
env.info(string.format("- Will be stopped when mission ends"))
env.info( string.format( "- Will be stopped when mission ends" ) )
end
env.info(string.format("- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS))
env.info(string.format("- Total function time threshold %.3f sec", PROFILER.ThreshTtot))
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('###############################################################################')
env.info( string.format( "- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS ) )
env.info( string.format( "- Total function time threshold %.3f sec", PROFILER.ThreshTtot ) )
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( '###############################################################################' )
-- Message on screen
local duration=Duration or 600
trigger.action.outText("### Profiler running ###", duration)
local duration = Duration or 600
trigger.action.outText( "### Profiler running ###", duration )
-- Set hook.
debug.sethook(PROFILER.hook, "cr")
debug.sethook( PROFILER.hook, "cr" )
-- Auto stop profiler.
if Duration then
PROFILER.Stop(Duration)
PROFILER.Stop( Duration )
end
end
@ -180,34 +176,33 @@ end
--- Stop profiler.
-- @param #number Delay Delay before stop in seconds.
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
-- Remove hook.
debug.sethook()
-- Run time game.
local runTimeGame=timer.getTime()-PROFILER.TstartGame
local runTimeGame = timer.getTime() - PROFILER.TstartGame
-- Run time real OS.
local runTimeOS=os.clock()-PROFILER.TstartOS
local runTimeOS = os.clock() - PROFILER.TstartOS
-- Show info.
PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER.showInfo( runTimeGame, runTimeOS )
end
end
--- Event handler.
function PROFILER.eventHandler:onEvent(event)
if event.id==world.event.S_EVENT_MISSION_END then
function PROFILER.eventHandler:onEvent( event )
if event.id == world.event.S_EVENT_MISSION_END then
PROFILER.Stop()
end
end
@ -218,34 +213,34 @@ end
--- Debug hook.
-- @param #table event Event.
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.dInfo[f]=debug.getinfo(2,"Sn")
PROFILER.Counters[f] = 1
PROFILER.dInfo[f] = debug.getinfo( 2, "Sn" )
if PROFILER.fTimeTotal[f]==nil then
PROFILER.fTimeTotal[f]=0
if PROFILER.fTimeTotal[f] == nil then
PROFILER.fTimeTotal[f] = 0
end
else
PROFILER.Counters[f]=PROFILER.Counters[f]+1
PROFILER.Counters[f] = PROFILER.Counters[f] + 1
end
if PROFILER.fTime[f]==nil then
PROFILER.fTime[f]=os.clock()
if PROFILER.fTime[f] == nil then
PROFILER.fTime[f] = os.clock()
end
elseif (event=='return') then
elseif (event == 'return') then
if PROFILER.fTime[f]~=nil then
PROFILER.fTimeTotal[f]=PROFILER.fTimeTotal[f]+(os.clock()-PROFILER.fTime[f])
PROFILER.fTime[f]=nil
if PROFILER.fTime[f] ~= nil then
PROFILER.fTimeTotal[f] = PROFILER.fTimeTotal[f] + (os.clock() - PROFILER.fTime[f])
PROFILER.fTime[f] = nil
end
end
@ -262,11 +257,11 @@ end
-- @return #string Source file name.
-- @return #string Line number.
-- @return #number Function time in seconds.
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]
end
@ -276,31 +271,31 @@ end
--- Write text to log file.
-- @param #function f The file.
-- @param #string txt The text.
function PROFILER._flog(f, txt)
f:write(txt.."\r\n")
function PROFILER._flog( f, txt )
f:write( txt .. "\r\n" )
end
--- Show table.
-- @param #table data Data table.
-- @param #function f The file.
-- @param #number runTimeGame Game run time in seconds.
function PROFILER.showTable(data, f, runTimeGame)
function PROFILER.showTable( data, f, runTimeGame )
-- Loop over data.
for i=1, #data do
local t=data[i] --#PROFILER.Data
for i = 1, #data do
local t = data[i] -- #PROFILER.Data
-- Calls per second.
local cps=t.count/runTimeGame
local cps = t.count / runTimeGame
local threshCPS=cps>=PROFILER.ThreshCPS
local threshTot=t.tm>=PROFILER.ThreshTtot
local threshCPS = cps >= PROFILER.ThreshCPS
local threshTot = t.tm >= PROFILER.ThreshTtot
if threshCPS and threshTot then
-- 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))
PROFILER._flog(f, text)
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 )
end
end
@ -310,26 +305,26 @@ end
--- Print csv file.
-- @param #table data Data table.
-- @param #number runTimeGame Game run time in seconds.
function PROFILER.printCSV(data, runTimeGame)
function PROFILER.printCSV( data, runTimeGame )
-- Output file.
local file=PROFILER.getfilename("csv")
local g=io.open(file, 'w')
local file = PROFILER.getfilename( "csv" )
local g = io.open( file, 'w' )
-- Header.
local text="Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
g:write(text.."\r\n")
local text = "Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
g:write( text .. "\r\n" )
-- Loop over data.
for i=1, #data do
local t=data[i] --#PROFILER.Data
for i = 1, #data do
local t = data[i] -- #PROFILER.Data
-- Calls per second.
local cps=t.count/runTimeGame
local cps = t.count / runTimeGame
-- 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))
g:write(txt.."\r\n")
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" )
end
@ -337,27 +332,26 @@ function PROFILER.printCSV(data, runTimeGame)
g:close()
end
--- Write info to output file.
-- @param #string ext Extension.
-- @return #string File name.
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
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
end
@ -368,81 +362,76 @@ end
--- Write info to output file.
-- @param #number runTimeGame Game time in seconds.
-- @param #number runTimeOS OS time in seconds.
function PROFILER.showInfo(runTimeGame, runTimeOS)
function PROFILER.showInfo( runTimeGame, runTimeOS )
-- Output file.
local file=PROFILER.getfilename(PROFILER.fileNameSuffix)
local f=io.open(file, 'w')
local file = PROFILER.getfilename( PROFILER.fileNameSuffix )
local f = io.open( file, 'w' )
-- Gather data.
local Ttot=0
local Calls=0
local Ttot = 0
local Calls = 0
local t={}
local t = {}
local tcopy=nil --#PROFILER.Data
local tserialize=nil --#PROFILER.Data
local tforgen=nil --#PROFILER.Data
local tpairs=nil --#PROFILER.Data
local tcopy = nil -- #PROFILER.Data
local tserialize = nil -- #PROFILER.Data
local tforgen = 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 s==nil then s="<Unknown>" end
if PROFILER.logUnknown == true then
if s == nil then
s = "<Unknown>"
end
end
if s~=nil then
if s ~= nil then
-- Profile data.
local T=
{ func=s,
src=src,
line=line,
count=count,
tm=tm,
} --#PROFILER.Data
local T = { func = s, src = src, line = line, count = count, tm = tm } -- #PROFILER.Data
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
if s=="_copy" then
if tcopy==nil then
tcopy=T
if s == "_copy" then
if tcopy == nil then
tcopy = T
else
tcopy.count=tcopy.count+T.count
tcopy.tm=tcopy.tm+T.tm
tcopy.count = tcopy.count + T.count
tcopy.tm = tcopy.tm + T.tm
end
elseif s=="_Serialize" then
if tserialize==nil then
tserialize=T
elseif s == "_Serialize" then
if tserialize == nil then
tserialize = T
else
tserialize.count=tserialize.count+T.count
tserialize.tm=tserialize.tm+T.tm
tserialize.count = tserialize.count + T.count
tserialize.tm = tserialize.tm + T.tm
end
elseif s=="(for generator)" then
if tforgen==nil then
tforgen=T
elseif s == "(for generator)" then
if tforgen == nil then
tforgen = T
else
tforgen.count=tforgen.count+T.count
tforgen.tm=tforgen.tm+T.tm
tforgen.count = tforgen.count + T.count
tforgen.tm = tforgen.tm + T.tm
end
elseif s=="pairs" then
if tpairs==nil then
tpairs=T
elseif s == "pairs" then
if tpairs == nil then
tpairs = T
else
tpairs.count=tpairs.count+T.count
tpairs.tm=tpairs.tm+T.tm
tpairs.count = tpairs.count + T.count
tpairs.tm = tpairs.tm + T.tm
end
else
table.insert(t, T)
table.insert( t, T )
end
-- Total function time.
Ttot=Ttot+tm
Ttot = Ttot + tm
-- Total number of calls.
Calls=Calls+count
Calls = Calls + count
end
@ -450,90 +439,95 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
-- Add special cases.
if tcopy then
table.insert(t, tcopy)
table.insert( t, tcopy )
end
if tserialize then
table.insert(t, tserialize)
table.insert( t, tserialize )
end
if tforgen then
table.insert(t, tforgen)
table.insert( t, tforgen )
end
if tpairs then
table.insert(t, tpairs)
table.insert( t, tpairs )
end
env.info('############################ Profiler Stopped ############################')
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("* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
env.info(string.format("* Total functions : %d", #t))
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\"", PROFILER.getfilename("csv")))
env.info("##############################################################################")
env.info( '############################ Profiler Stopped ############################' )
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( "* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock( Ttot, true ), Ttot, Ttot / runTimeGame * 100 ) )
env.info( string.format( "* Total functions : %d", #t ) )
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\"", PROFILER.getfilename( "csv" ) ) )
env.info( "##############################################################################" )
-- 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.
PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"")
PROFILER._flog(f,"-------------------------")
PROFILER._flog(f,"---- Profiler Report ----")
PROFILER._flog(f,"-------------------------")
PROFILER._flog(f,"")
PROFILER._flog(f,string.format("* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame))
PROFILER._flog(f,string.format("* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS))
PROFILER._flog(f,string.format("* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
PROFILER._flog(f,"")
PROFILER._flog(f,string.format("* Total functions = %d", #t))
PROFILER._flog(f,string.format("* Total func calls = %d", Calls))
PROFILER._flog(f,"")
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,"")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"")
PROFILER.showTable(t, f, runTimeGame)
PROFILER._flog( f, "" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "" )
PROFILER._flog( f, "-------------------------" )
PROFILER._flog( f, "---- Profiler Report ----" )
PROFILER._flog( f, "-------------------------" )
PROFILER._flog( f, "" )
PROFILER._flog( f, string.format( "* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock( runTimeGame, true ), runTimeGame ) )
PROFILER._flog( f, string.format( "* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock( runTimeOS, true ), runTimeOS ) )
PROFILER._flog( f, string.format( "* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock( Ttot, true ), Ttot, Ttot / runTimeGame * 100 ) )
PROFILER._flog( f, "" )
PROFILER._flog( f, string.format( "* Total functions = %d", #t ) )
PROFILER._flog( f, string.format( "* Total func calls = %d", Calls ) )
PROFILER._flog( f, "" )
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, "" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "" )
PROFILER.showTable( t, f, runTimeGame )
-- 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.
PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"")
PROFILER._flog(f,"--------------------------------------")
PROFILER._flog(f,"---- Data Sorted by Time per Call ----")
PROFILER._flog(f,"--------------------------------------")
PROFILER._flog(f,"")
PROFILER.showTable(t, f, runTimeGame)
PROFILER._flog( f, "" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "" )
PROFILER._flog( f, "--------------------------------------" )
PROFILER._flog( f, "---- Data Sorted by Time per Call ----" )
PROFILER._flog( f, "--------------------------------------" )
PROFILER._flog( f, "" )
PROFILER.showTable( t, f, runTimeGame )
-- 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.
PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"")
PROFILER._flog(f,"------------------------------------")
PROFILER._flog(f,"---- Data Sorted by Total Calls ----")
PROFILER._flog(f,"------------------------------------")
PROFILER._flog(f,"")
PROFILER.showTable(t, f, runTimeGame)
PROFILER._flog( f, "" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "" )
PROFILER._flog( f, "------------------------------------" )
PROFILER._flog( f, "---- Data Sorted by Total Calls ----" )
PROFILER._flog( f, "------------------------------------" )
PROFILER._flog( f, "" )
PROFILER.showTable( t, f, runTimeGame )
-- Closing.
PROFILER._flog(f,"")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog(f,"************************************************************************************************************************")
PROFILER._flog( f, "" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog( f, "************************************************************************************************************************" )
-- Close file.
f:close()
-- Print csv file.
PROFILER.printCSV(t, runTimeGame)
PROFILER.printCSV( t, runTimeGame )
end

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,18 @@
--- **Utilities** DCS Simple Text-To-Speech (STTS).
--
--
--
-- @module Utils.STTS
-- @image MOOSE.JPG
--- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world)
-- @type STTS
-- @field #string DIRECTORY Path of the SRS directory.
--- Simple Text-To-Speech
--
-- Version 0.4 - Compatible with SRS version 1.9.6.0+
--
-- # DCS Modification Required
--
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitisation.
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitization.
-- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)"
-- Do this without DCS running to allow mission scripts to use os functions.
--
@ -23,7 +20,7 @@
--
-- # USAGE:
--
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialise it
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialize it
-- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission.
-- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts.
--
@ -55,7 +52,7 @@
--
-- ## Example
--
--This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT"
-- This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT"
--
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,Unit.getByName("A UNIT"):getPoint(),-5,"male","en-GB")
--
@ -75,12 +72,12 @@
-- STTS.PlayMP3("C:\\Users\\Ciaran\\Downloads\\PR-Music.mp3","255,31","AM,FM","0.5","Multiple",0)
--
-- @field #STTS
STTS={
ClassName="STTS",
DIRECTORY="",
SRS_PORT=5002,
GOOGLE_CREDENTIALS="C:\\Users\\Ciaran\\Downloads\\googletts.json",
EXECUTABLE="DCS-SR-ExternalAudio.exe",
STTS = {
ClassName = "STTS",
DIRECTORY = "",
SRS_PORT = 5002,
GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json",
EXECUTABLE = "DCS-SR-ExternalAudio.exe"
}
--- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER
@ -95,24 +92,27 @@ STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json"
--- DONT CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe"
--- Function for UUID.
function STTS.uuid()
local random = math.random
local template ='yxxx-xxxxxxxxxxxx'
return string.gsub(template, '[xy]', function (c)
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
return string.format('%x', v)
end)
local template = 'yxxx-xxxxxxxxxxxx'
return string.gsub( template, '[xy]', function( c )
local v = (c == 'x') and random( 0, 0xf ) or random( 8, 0xb )
return string.format( '%x', v )
end )
end
--- Round a number.
-- @param #number x Number.
-- @param #number n Precision.
function STTS.round(x, n)
n = math.pow(10, n or 0)
function STTS.round( x, n )
n = math.pow( 10, n or 0 )
x = x * n
if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end
if x >= 0 then
x = math.floor( x + 0.5 )
else
x = math.ceil( x - 0.5 )
end
return x / n
end
@ -125,7 +125,7 @@ end
--
-- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
--
function STTS.getSpeechTime(length,speed,isGoogle)
function STTS.getSpeechTime( length, speed, isGoogle )
local maxRateRatio = 3
@ -137,27 +137,27 @@ function STTS.getSpeechTime(length,speed,isGoogle)
speedFactor = speed
else
if speed ~= 0 then
speedFactor = math.abs(speed) * (maxRateRatio - 1) / 10 + 1
speedFactor = math.abs( speed ) * (maxRateRatio - 1) / 10 + 1
end
if speed < 0 then
speedFactor = 1/speedFactor
speedFactor = 1 / speedFactor
end
end
local wpm = math.ceil(100 * speedFactor)
local cps = math.floor((wpm * 5)/60)
local wpm = math.ceil( 100 * speedFactor )
local cps = math.floor( (wpm * 5) / 60 )
if type(length) == "string" then
length = string.len(length)
if type( length ) == "string" then
length = string.len( length )
end
return math.ceil(length/cps)
return math.ceil( length / cps )
end
--- Text to speech function.
function STTS.TextToSpeech(message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS)
function STTS.TextToSpeech( message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS )
if os == nil or io == nil then
env.info("[DCS-STTS] LUA modules os or io are sanitized. skipping. ")
env.info( "[DCS-STTS] LUA modules os or io are sanitized. skipping. " )
return
end
@ -165,69 +165,68 @@ function STTS.TextToSpeech(message, freqs, modulations, volume, name, coalition,
gender = gender or "female"
culture = culture or ""
voice = voice or ""
coalition=coalition or "0"
name=name or "ROBOT"
volume=1
speed=1
coalition = coalition or "0"
name = name or "ROBOT"
volume = 1
speed = 1
message = message:gsub( "\"", "\\\"" )
message = message:gsub("\"","\\\"")
local cmd = string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name)
local cmd = string.format( "start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name )
if voice ~= "" then
cmd = cmd .. string.format(" -V \"%s\"",voice)
cmd = cmd .. string.format( " -V \"%s\"", voice )
else
if culture ~= "" then
cmd = cmd .. string.format(" -l %s",culture)
cmd = cmd .. string.format( " -l %s", culture )
end
if gender ~= "" then
cmd = cmd .. string.format(" -g %s",gender)
cmd = cmd .. string.format( " -g %s", gender )
end
end
if googleTTS == true then
cmd = cmd .. string.format(" -G \"%s\"",STTS.GOOGLE_CREDENTIALS)
cmd = cmd .. string.format( " -G \"%s\"", STTS.GOOGLE_CREDENTIALS )
end
if speed ~= 1 then
cmd = cmd .. string.format(" -s %s",speed)
cmd = cmd .. string.format( " -s %s", speed )
end
if volume ~= 1.0 then
cmd = cmd .. string.format(" -v %s",volume)
cmd = cmd .. string.format( " -v %s", volume )
end
if point and type(point) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL(point)
if point and type( point ) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL( point )
lat = STTS.round(lat,4)
lon = STTS.round(lon,4)
alt = math.floor(alt)
lat = STTS.round( lat, 4 )
lon = STTS.round( lon, 4 )
alt = math.floor( alt )
cmd = cmd .. string.format(" -L %s -O %s -A %s",lat,lon,alt)
cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
end
cmd = cmd ..string.format(" -t \"%s\"",message)
cmd = cmd .. string.format( " -t \"%s\"", message )
if string.len(cmd) > 255 then
local filename = os.getenv('TMP') .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat"
local script = io.open(filename,"w+")
script:write(cmd .. " && exit" )
if string.len( cmd ) > 255 then
local filename = os.getenv( 'TMP' ) .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat"
local script = io.open( filename, "w+" )
script:write( cmd .. " && exit" )
script:close()
cmd = string.format("\"%s\"",filename)
timer.scheduleFunction(os.remove, filename, timer.getTime() + 1)
cmd = string.format( "\"%s\"", filename )
timer.scheduleFunction( os.remove, filename, timer.getTime() + 1 )
end
if string.len(cmd) > 255 then
env.info("[DCS-STTS] - cmd string too long")
env.info("[DCS-STTS] TextToSpeech Command :\n" .. cmd.."\n")
if string.len( cmd ) > 255 then
env.info( "[DCS-STTS] - cmd string too long" )
env.info( "[DCS-STTS] TextToSpeech Command :\n" .. cmd .. "\n" )
end
os.execute(cmd)
os.execute( cmd )
return STTS.getSpeechTime(message,speed,googleTTS)
return STTS.getSpeechTime( message, speed, googleTTS )
end
--- Play mp3 function.
@ -235,22 +234,21 @@ end
-- @param #string freqs Frequencies, e.g. "305, 256".
-- @param #string modulations Modulations, e.g. "AM, FM".
-- @param #string volume Volume, e.g. "0.5".
function STTS.PlayMP3(pathToMP3, freqs, modulations, volume, name, coalition, point)
function STTS.PlayMP3( pathToMP3, freqs, modulations, volume, name, coalition, point )
local cmd = string.format("start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h",
STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1")
local cmd = string.format( "start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1" )
if point and type(point) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL(point)
if point and type( point ) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL( point )
lat = STTS.round(lat,4)
lon = STTS.round(lon,4)
alt = math.floor(alt)
lat = STTS.round( lat, 4 )
lon = STTS.round( lon, 4 )
alt = math.floor( alt )
cmd = cmd .. string.format(" -L %s -O %s -A %s",lat,lon,alt)
cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
end
env.info("[DCS-STTS] MP3/OGG Command :\n" .. cmd.."\n")
os.execute(cmd)
env.info( "[DCS-STTS] MP3/OGG Command :\n" .. cmd .. "\n" )
os.execute( cmd )
end