demo slicing is now done in a separate task to prevent ingame freeze

This commit is contained in:
Corantin H 2019-05-25 00:24:13 +02:00
parent bf435e8b72
commit e35951dedc
4 changed files with 53 additions and 14 deletions

View file

@ -3324,18 +3324,10 @@ void CClient::SaveReplay()
// Slice the demo to get only the last cl_replay_length seconds
const int EndTick = GameTick();
const int StartTick = EndTick - g_Config.m_ClReplayLength * GameTickSpeed();
m_DemoEditor.Slice(pSrc, aFilename, StartTick, EndTick, NULL, 0);
const char *pFilename = (&m_DemoRecorder[RECORDER_REPLAYS])->GetCurrentFilename();
Storage()->RemoveFile(pFilename, IStorage::TYPE_SAVE);
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Successfully saved the replay to %s!", aFilename);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "replay", aBuf);
Notify(Localize("Replay"), Localize("Successfully saved the replay!"));
// And we restart the recorder
DemoRecorder_StartReplayRecorder();
// Create a job to do this slicing in background because it can be a bit long depending on the file size
std::shared_ptr<CDemoEdit> pDemoEditTask = std::make_shared<CDemoEdit>(this, m_pConsole, &m_DemoEditor, pSrc, aFilename, StartTick, EndTick);
Engine()->AddJob(pDemoEditTask);
}
}
}
@ -3996,3 +3988,35 @@ void CClient::GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float Mix
*pSmoothTick = (int)(SmoothTime*50/time_freq())+1;
*pSmoothIntraTick = (SmoothTime - (*pSmoothTick-1)*time_freq()/50) / (float)(time_freq()/50);
}
CDemoEdit::CDemoEdit(CClient *pClient, IConsole *pConsole, CDemoEditor *pDemoEditor, const char *pDemo, const char *pDst, int StartTick, int EndTick) :
m_pClient(pClient),
m_pConsole(pConsole),
m_pDemoEditor(pDemoEditor)
{
str_copy(m_pDemo, pDemo, sizeof(m_pDemo));
str_copy(m_pDst, pDst, sizeof(m_pDst));
m_StartTick = StartTick;
m_EndTick = EndTick;
}
void CDemoEdit::Run()
{
// Slice the actual demo
m_pDemoEditor->Slice(m_pDemo, m_pDst, m_StartTick, m_EndTick, NULL, 0);
// Notify the player via console and a hud notification
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Successfully saved the replay to %s!", m_pDst);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "replay", aBuf);
m_pClient->Notify(Localize("Replay"), Localize("Successfully saved the replay!"));
// We remove the temporary demo file
const char *pFilename = m_pClient->DemoRecorder(RECORDER_REPLAYS)->GetCurrentFilename();
m_pClient->Storage()->RemoveFile(pFilename, IStorage::TYPE_SAVE);
// And we restart the recorder
m_pClient->DemoRecorder_StartReplayRecorder();
}

View file

@ -55,7 +55,6 @@ public:
void Update(CGraph *pGraph, int64 Target, int TimeLeft, int AdjustDirection);
};
class CClient : public IClient, public CDemoPlayer::IListener
{
// needed interfaces
@ -425,4 +424,20 @@ public:
void GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float MixAmount);
};
class CDemoEdit : public IJob
{
CClient *m_pClient;
IConsole *m_pConsole;
CDemoEditor *m_pDemoEditor;
char m_pDemo[256];
char m_pDst[256];
int m_StartTick;
int m_EndTick;
public:
CDemoEdit(CClient *pClient, IConsole *pConsole, CDemoEditor *pDemoEditor, const char *pDemo, const char *pDst, int StartTick, int EndTick);
void Run();
};
#endif

View file

@ -81,6 +81,7 @@ public:
virtual bool IsRecording() const = 0;
virtual int Stop() = 0;
virtual int Length() const = 0;
virtual char *GetCurrentFilename() = 0;
};
class IDemoEditor : public IInterface

View file

@ -40,6 +40,7 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
m_MapSize = MapSize;
m_pMapData = pMapData;
m_pConsole = pConsole;
IOHANDLE DemoFile = pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
if(!DemoFile)
@ -57,8 +58,6 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
return -1;
}
m_pConsole = pConsole;
bool CloseMapFile = false;
if(MapFile)