Skip to content

Commit 3212db8

Browse files
committed
perf: debug channel for perf metrics
1 parent 2f20ee1 commit 3212db8

8 files changed

Lines changed: 82 additions & 17 deletions

File tree

Courseplay.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function Courseplay:setupGui()
145145
g_messageCenter:publishDelayed(MessageType.GUI_CP_INGAME_OPEN)
146146
end, false, true, false, true)
147147
g_inputBinding:setActionEventTextVisibility(id, false)
148-
-- CpDebug.registerEvents()
148+
CpDebug.registerEvents()
149149
end
150150
PlayerInputComponent.registerGlobalPlayerActionEvents = Utils.overwrittenFunction(
151151
PlayerInputComponent.registerGlobalPlayerActionEvents, addPlayerActionEvents)

config/DebugChannels.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
<DebugChannel active="false" name="DBG_HUD" text="hud action"/>
2121
<DebugChannel active="false" name="DBG_MULTIPLAYER" text="multiplayer"/>
2222
<DebugChannel active="true" name="DBG_IMPLEMENTS" text="implements"/>
23-
<DebugChannel active="false" name="DBG_AI_DRIVER" text="AIDriver common"/>
23+
<DebugChannel active="false" name="DBG_AI_DRIVER" text="ai common"/>
24+
<DebugChannel active="true" name="DBG_PERF" text="perf"/>
2425
</DebugChannels>

modDesc.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Changelog 8.1.0.0
109109
<sourceFile filename="scripts/util/MovingAverage.lua"/>
110110
<sourceFile filename="scripts/util/CpRemainingTime.lua"/>
111111
<sourceFile filename="scripts/util/HelperNode.lua"/>
112+
<sourceFile filename="scripts/util/Profiler.lua"/>
112113

113114
<sourceFile filename="scripts/geometry/Vector.lua"/>
114115
<sourceFile filename="scripts/geometry/Vertex.lua"/>

scripts/ai/strategies/AIDriveStrategyFieldWorkCourse.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ end
147147

148148
--- This is the interface to the Giant's AIFieldWorker specialization, telling it the direction and speed
149149
function AIDriveStrategyFieldWorkCourse:getDriveData(dt, vX, vY, vZ)
150-
151150
self:updateFieldworkOffset(self.course)
152151
self:updateLowFrequencyImplementControllers()
153152
Markers.refreshMarkerNodes(self.vehicle, self.measuredBackDistance)

scripts/debug/CpDebug.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@ end
132132

133133
function CpDebug:activateEvents()
134134
for _, id in pairs(CpDebug.eventIds) do
135-
g_currentMission.inputManager:setActionEventActive(id, true)
135+
g_inputBinding:setActionEventActive(id, true)
136136
end
137137
end
138138

139139
function CpDebug:deactivateEvents()
140140
for _, id in pairs(CpDebug.eventIds) do
141-
g_currentMission.inputManager:setActionEventActive(id, false)
141+
g_inputBinding:setActionEventActive(id, false)
142142
end
143143
end
144144

scripts/specializations/CpAIFieldWorker.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ CpAIFieldWorker.NAME = ".cpAIFieldWorker"
99
CpAIFieldWorker.SPEC_NAME = CpAIFieldWorker.MOD_NAME .. CpAIFieldWorker.NAME
1010
CpAIFieldWorker.KEY = "."..CpAIFieldWorker.MOD_NAME..CpAIFieldWorker.NAME
1111

12+
local profilers = {}
13+
1214
-- shortcut to access the spec
1315
function CpAIFieldWorker.getSpec(self)
1416
return self["spec_" .. CpAIFieldWorker.SPEC_NAME]
@@ -311,7 +313,16 @@ end
311313
--- Makes sure a callstack is printed, when an error appeared.
312314
--- TODO: Might be a good idea to stop the cp helper.
313315
local function onUpdate(vehicle, superFunc, ...)
316+
if not profilers[vehicle] then
317+
profilers[vehicle] = Profiler(vehicle)
318+
end
319+
profilers[vehicle]:start()
314320
CpUtil.try(superFunc, vehicle, ...)
321+
profilers[vehicle]:stop()
322+
profilers[vehicle]:render()
323+
if g_updateLoopIndex % 100 == 0 then
324+
profilers[vehicle]:log()
325+
end
315326
end
316327

317328
AIFieldWorker.onUpdate = Utils.overwrittenFunction(AIFieldWorker.onUpdate, onUpdate)

scripts/specializations/CpAIWorker.lua

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ CpAIWorker.SPEC_NAME = CpAIWorker.MOD_NAME .. CpAIWorker.NAME
1010
CpAIWorker.KEY = "." .. CpAIWorker.MOD_NAME .. CpAIWorker.NAME .. "."
1111
CpAIWorker.LAST_JOB_KEY = "vehicles.vehicle(?).aiJobVehicle.lastJob"
1212

13+
local logger = Logger('CpAIWorker', Logger.level.debug, CpUtil.DBG_AI_DRIVER)
14+
1315
function CpAIWorker.initSpecialization()
1416
local schema = Vehicle.xmlSchemaSavegame
1517
--- Registers the last job key.
@@ -248,15 +250,15 @@ end
248250

249251
--- Directly starts a cp job or stops a currently active job.
250252
function CpAIWorker:cpStartStopDriver(isStartedByHud)
251-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Start/stop cp helper")
253+
logger:debug(self, "Start/stop cp helper")
252254
if self:getIsAIActive() then
253255
self:stopCurrentAIJob(AIMessageSuccessStoppedByUser.new())
254-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Stopped current helper.")
256+
logger:debug(self, "Stopped current helper.")
255257
else
256258
self:updateAIFieldWorkerImplementData()
257259
local job = self:getCpStartableJob(isStartedByHud)
258260
if job == nil then
259-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Could not find a CP job to start!")
261+
logger:debug(self, "Could not find a CP job to start!")
260262
return
261263
end
262264
if self:getCanStartCp() and job then
@@ -266,15 +268,15 @@ function CpAIWorker:cpStartStopDriver(isStartedByHud)
266268
local success, message = job:validate()
267269
if success then
268270
g_client:getServerConnection():sendEvent(AIJobStartRequestEvent.new(job, self:getOwnerFarmId()))
269-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Cp helper started.")
271+
logger:debug(self, "Cp helper started.")
270272
else
271-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Could not start CP helper: %s", tostring(message))
273+
logger:debug(self, "Could not start CP helper: %s", tostring(message))
272274
if message then
273275
g_currentMission:showBlinkingWarning("CP: " .. message, 5000)
274276
end
275277
end
276278
else
277-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Could not start CP helper!")
279+
logger:debug(self, "Could not start CP helper!")
278280
end
279281
end
280282
end
@@ -352,10 +354,10 @@ function CpAIWorker:stopCurrentAIJob(superFunc, message, ...)
352354
-- since we often stop for instance in convoy mode when waiting for another vehicle to turn
353355
-- (when we do this, we set our maxSpeed to 0). So we also check our maxSpeed, this way the Giants timer will
354356
-- fire if we are blocked (thus have a maxSpeed > 0 but not moving)
355-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, 'Overriding the Giants did not move timer, with speed: %.2f', maxSpeed)
357+
logger:debug(self, 'Overriding the Giants did not move timer, with speed: %.2f', maxSpeed)
356358
return
357359
else
358-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, 'Giants did not move timer triggered, with speed: %.2f!', maxSpeed)
360+
logger:debug(self, 'Giants did not move timer triggered, with speed: %.2f!', maxSpeed)
359361
end
360362
end
361363
end
@@ -364,7 +366,7 @@ function CpAIWorker:stopCurrentAIJob(superFunc, message, ...)
364366
return
365367
end
366368
end
367-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "stop message: %s", message:getI18NText())
369+
logger:debug(self, "stop message: %s", message:getI18NText())
368370
superFunc(self, message,...)
369371
end
370372

@@ -385,6 +387,7 @@ function CpAIWorker:onUpdate(dt)
385387
return
386388
end
387389
local tX, tZ, moveForwards, maxSpeedStrategy = spec.driveStrategy:getDriveData(dt)
390+
logger:debug('Speed %.1f', maxSpeedStrategy)
388391
local maxSpeed = math.min(maxSpeedStrategy or math.huge, self:getCruiseControlMaxSpeed())
389392
if not spec.driveStrategy then
390393
return
@@ -533,13 +536,13 @@ end
533536
--- Auto drive stop
534537
function CpAIWorker:onStopAutoDrive(isPassingToCP, isStartingAIVE)
535538
if g_server then
536-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "isPassingToCP: %s, isStartingAIVE: %s", tostring(isPassingToCP), tostring(isStartingAIVE))
539+
logger:debug(self, "isPassingToCP: %s, isStartingAIVE: %s", tostring(isPassingToCP), tostring(isStartingAIVE))
537540
if self.ad.restartCP then
538541
--- Is restarted for refilling or unloading.
539-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Was refilled/unloaded by AD.")
542+
logger:debug(self, "Was refilled/unloaded by AD.")
540543
else
541544
--- Is sent to a field.
542-
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, self, "Was sent to field by AD.")
545+
logger:debug(self, "Was sent to field by AD.")
543546
end
544547
end
545548
end

scripts/util/Profiler.lua

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Profiler = CpObject()
2+
3+
function Profiler:init(vehicle, n)
4+
self.logger = Logger('Profiler', Logger.level.debug, CpUtil.DBG_PERF)
5+
self.movingAverage = MovingAverage(n or 100)
6+
self.elapsed = 0
7+
self.max = 0
8+
self.min = math.huge
9+
self.vehicle = vehicle
10+
end
11+
12+
function Profiler:start()
13+
self.startSec = getTimeSec()
14+
end
15+
16+
function Profiler:stop()
17+
self.elapsed = getTimeSec() - self.startSec
18+
self.movingAverage:update(self.elapsed)
19+
if self.elapsed > self.max then
20+
self.max = self.elapsed
21+
end
22+
if self.elapsed < self.min then
23+
self.min = self.elapsed
24+
end
25+
end
26+
27+
function Profiler:getAverageMs()
28+
return self.movingAverage:get() * 1000
29+
end
30+
31+
function Profiler:getMaxMs()
32+
return self.max * 1000
33+
end
34+
35+
function Profiler:getMinMs()
36+
return self.min * 1000
37+
end
38+
39+
function Profiler:log()
40+
self.logger:debug(self.vehicle, "avg: %.3f ms, min: %.3f ms, max: %.3f ms",
41+
self:getAverageMs(), self:getMinMs(), self:getMaxMs())
42+
end
43+
44+
function Profiler:render()
45+
if not CpUtil.isVehicleDebugActive(self.vehicle) or not CpDebug:isChannelActive(CpDebug.DBG_PERF) then
46+
return
47+
end
48+
renderText(0.8, 0.9, 0.018, string.format('current: %.1f ms, average: %.1f ms',
49+
self.elapsed * 1000, self:getAverageMs()))
50+
end

0 commit comments

Comments
 (0)