Skip to content

Commit f3c31f3

Browse files
RainbowwPhoenixxThisAMJ
authored andcommitted
fix: better performance for long-running scripts
1 parent c5c873e commit f3c31f3

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

src/Features/Tas/TasPlayer.cpp

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ void TasPlayer::Activate(TasPlaybackInfo info) {
152152

153153
for (int slot = 0; slot < 2; ++slot) {
154154
playbackInfo.slots[slot].ClearGeneratedContent();
155+
156+
currentInputFramebulkIndex[slot] = 0;
157+
currentToolsFramebulkIndex[slot] = 0;
155158
}
156159

157160
active = true;
@@ -303,16 +306,50 @@ void TasPlayer::AdvanceFrame() {
303306

304307
// returns raw framebulk that should be used for given tick
305308
TasFramebulk TasPlayer::GetRawFramebulkAt(int slot, int tick) {
306-
int closestTime = INT_MAX;
307-
TasFramebulk closest;
308-
for (TasFramebulk framebulk : playbackInfo.slots[slot].framebulks) {
309-
int timeDist = tick - framebulk.tick;
310-
if (timeDist >= 0 && timeDist < closestTime) {
311-
closestTime = timeDist;
312-
closest = framebulk;
309+
// Do binary search for bulks immediately before and after our target tick
310+
uint32_t before = 0;
311+
uint32_t after = playbackInfo.slots[slot].framebulks.size() - 1;
312+
313+
if (playbackInfo.slots[slot].framebulks[before].tick == tick) {
314+
return playbackInfo.slots[slot].framebulks[before];
315+
}
316+
if (playbackInfo.slots[slot].framebulks[after].tick == tick) {
317+
return playbackInfo.slots[slot].framebulks[after];
318+
}
319+
320+
while (before + 1 != after) {
321+
uint32_t middle = (before + after) / 2;
322+
TasFramebulk middle_bulk = playbackInfo.slots[slot].framebulks[middle];
323+
324+
if (middle_bulk.tick < tick) {
325+
before = middle;
326+
} else if (middle_bulk.tick > tick) {
327+
after = middle;
328+
} else {
329+
return middle_bulk;
313330
}
314331
}
315-
return closest;
332+
333+
return playbackInfo.slots[slot].framebulks[before];
334+
}
335+
336+
// returns raw framebulk using more efficient method with cached incremented index of last used tick
337+
TasFramebulk TasPlayer::GetRawFramebulkAt(int slot, int tick, int& cachedIndex) {
338+
if (cachedIndex < 0) {
339+
cachedIndex = 0;
340+
}
341+
342+
auto maxIndex = playbackInfo.slots[slot].framebulks.size() - 1;
343+
344+
if (cachedIndex >= maxIndex) {
345+
return playbackInfo.slots[slot].framebulks[maxIndex];
346+
}
347+
348+
while (cachedIndex < maxIndex && playbackInfo.slots[slot].framebulks[cachedIndex + 1].tick <= tick) {
349+
cachedIndex++;
350+
}
351+
352+
return playbackInfo.slots[slot].framebulks[cachedIndex];
316353
}
317354

318355
TasPlayerInfo TasPlayer::GetPlayerInfo(int slot, void *player, CUserCmd *cmd, bool clientside) {
@@ -494,7 +531,7 @@ void TasPlayer::FetchInputs(int slot, TasController *controller) {
494531
// to actually hook at _Host_RunFrame_Input or CL_Move.
495532
int tick = currentTick + 1;
496533

497-
TasFramebulk fb = GetRawFramebulkAt(slot, tick);
534+
TasFramebulk fb = GetRawFramebulkAt(slot, tick, currentInputFramebulkIndex[slot]);
498535

499536
int fbTick = fb.tick;
500537

@@ -563,7 +600,7 @@ void TasPlayer::PostProcess(int slot, void *player, CUserCmd *cmd) {
563600
return;
564601
}
565602

566-
TasFramebulk fb = GetRawFramebulkAt(slot, tasTick);
603+
TasFramebulk fb = GetRawFramebulkAt(slot, tasTick, currentToolsFramebulkIndex[slot]);
567604

568605
// update all tools that needs to be updated
569606
auto fbTick = fb.tick;

src/Features/Tas/TasPlayer.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class TasPlayer : public Feature {
6666

6767
int wasEnginePaused = false; // Used to check if we need to revert incrementing a tick
6868

69+
// used to cache last used framebulk to quickly access it for playback
70+
int currentInputFramebulkIndex[2];
71+
int currentToolsFramebulkIndex[2];
6972
public:
7073
void Update();
7174
void UpdateServer();
@@ -99,6 +102,7 @@ class TasPlayer : public Feature {
99102
void AdvanceFrame();
100103

101104
TasFramebulk GetRawFramebulkAt(int slot, int tick);
105+
TasFramebulk GetRawFramebulkAt(int slot, int tick, int &cachedIndex);
102106

103107
TasPlayerInfo GetPlayerInfo(int slot, void *player, CUserCmd *cmd, bool clientside = false);
104108

0 commit comments

Comments
 (0)