mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Use std::vector
for demo player keyframes
Using an `std::vector` is simpler and more readable than first allocating a linked list on a heap and later copying the list to an array. The variable `m_SeekablePoints` is removed from `CPlaybackInfo`, as it does not need to be exposed outside of `CDemoPlayer` and can be replaced with the size of the vector.
This commit is contained in:
parent
cd4a13e74c
commit
c3b8c94212
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "compression.h"
|
||||
#include "demo.h"
|
||||
#include "memheap.h"
|
||||
#include "network.h"
|
||||
#include "snapshot.h"
|
||||
|
||||
|
@ -416,7 +415,6 @@ CDemoPlayer::~CDemoPlayer()
|
|||
void CDemoPlayer::Construct(class CSnapshotDelta *pSnapshotDelta, bool UseVideo)
|
||||
{
|
||||
m_File = 0;
|
||||
m_pKeyFrames = 0;
|
||||
m_SpeedIndex = 4;
|
||||
|
||||
m_pSnapshotDelta = pSnapshotDelta;
|
||||
|
@ -489,40 +487,23 @@ int CDemoPlayer::ReadChunkHeader(int *pType, int *pSize, int *pTick)
|
|||
|
||||
void CDemoPlayer::ScanFile()
|
||||
{
|
||||
CHeap Heap;
|
||||
CKeyFrameSearch *pFirstKey = 0;
|
||||
CKeyFrameSearch *pCurrentKey = 0;
|
||||
const long StartPos = io_tell(m_File);
|
||||
m_vKeyFrames.clear();
|
||||
|
||||
int ChunkTick = 0;
|
||||
|
||||
long StartPos = io_tell(m_File);
|
||||
m_Info.m_SeekablePoints = 0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
long CurrentPos = io_tell(m_File);
|
||||
const long CurrentPos = io_tell(m_File);
|
||||
|
||||
int ChunkSize, ChunkType;
|
||||
int ChunkType, ChunkSize;
|
||||
if(ReadChunkHeader(&ChunkType, &ChunkSize, &ChunkTick))
|
||||
break;
|
||||
|
||||
// read the chunk
|
||||
if(ChunkType & CHUNKTYPEFLAG_TICKMARKER)
|
||||
{
|
||||
if(ChunkType & CHUNKTICKFLAG_KEYFRAME)
|
||||
{
|
||||
CKeyFrameSearch *pKey;
|
||||
|
||||
// save the position
|
||||
pKey = (CKeyFrameSearch *)Heap.Allocate(sizeof(CKeyFrameSearch));
|
||||
pKey->m_Frame.m_Filepos = CurrentPos;
|
||||
pKey->m_Frame.m_Tick = ChunkTick;
|
||||
pKey->m_pNext = 0;
|
||||
if(pCurrentKey)
|
||||
pCurrentKey->m_pNext = pKey;
|
||||
if(!pFirstKey)
|
||||
pFirstKey = pKey;
|
||||
pCurrentKey = pKey;
|
||||
m_Info.m_SeekablePoints++;
|
||||
m_vKeyFrames.emplace_back(CurrentPos, ChunkTick);
|
||||
}
|
||||
|
||||
if(m_Info.m_Info.m_FirstTick == -1)
|
||||
|
@ -533,13 +514,6 @@ void CDemoPlayer::ScanFile()
|
|||
io_skip(m_File, ChunkSize);
|
||||
}
|
||||
|
||||
// copy all the frames to an array instead for fast access
|
||||
int i;
|
||||
m_pKeyFrames = (CKeyFrame *)calloc(maximum(m_Info.m_SeekablePoints, 1), sizeof(CKeyFrame));
|
||||
for(pCurrentKey = pFirstKey, i = 0; pCurrentKey; pCurrentKey = pCurrentKey->m_pNext, i++)
|
||||
m_pKeyFrames[i] = pCurrentKey->m_Frame;
|
||||
|
||||
// destroy the temporary heap and seek back to the start
|
||||
io_seek(m_File, StartPos, IOSEEK_START);
|
||||
}
|
||||
|
||||
|
@ -980,14 +954,14 @@ int CDemoPlayer::SetPos(int WantedTick)
|
|||
const float Percent = (KeyFrameWantedTick - m_Info.m_Info.m_FirstTick) / (float)(m_Info.m_Info.m_LastTick - m_Info.m_Info.m_FirstTick);
|
||||
|
||||
// get correct key frame
|
||||
int KeyFrame = clamp((int)(m_Info.m_SeekablePoints * Percent), 0, m_Info.m_SeekablePoints - 1);
|
||||
while(KeyFrame < m_Info.m_SeekablePoints - 1 && m_pKeyFrames[KeyFrame].m_Tick < KeyFrameWantedTick)
|
||||
size_t KeyFrame = clamp<size_t>(m_vKeyFrames.size() * Percent, 0, m_vKeyFrames.size() - 1);
|
||||
while(KeyFrame < m_vKeyFrames.size() - 1 && m_vKeyFrames[KeyFrame].m_Tick < KeyFrameWantedTick)
|
||||
KeyFrame++;
|
||||
while(KeyFrame > 0 && m_pKeyFrames[KeyFrame].m_Tick > KeyFrameWantedTick)
|
||||
while(KeyFrame > 0 && m_vKeyFrames[KeyFrame].m_Tick > KeyFrameWantedTick)
|
||||
KeyFrame--;
|
||||
|
||||
// seek to the correct key frame
|
||||
io_seek(m_File, m_pKeyFrames[KeyFrame].m_Filepos, IOSEEK_START);
|
||||
io_seek(m_File, m_vKeyFrames[KeyFrame].m_Filepos, IOSEEK_START);
|
||||
|
||||
m_Info.m_NextTick = -1;
|
||||
m_Info.m_Info.m_CurrentTick = -1;
|
||||
|
@ -1085,8 +1059,7 @@ int CDemoPlayer::Stop()
|
|||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_player", "Stopped playback");
|
||||
io_close(m_File);
|
||||
m_File = 0;
|
||||
free(m_pKeyFrames);
|
||||
m_pKeyFrames = 0;
|
||||
m_vKeyFrames.clear();
|
||||
str_copy(m_aFilename, "");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
#include <engine/demo.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "snapshot.h"
|
||||
|
||||
|
@ -76,8 +78,6 @@ public:
|
|||
int64_t m_LastUpdate;
|
||||
int64_t m_CurrentTime;
|
||||
|
||||
int m_SeekablePoints;
|
||||
|
||||
int m_NextTick;
|
||||
int m_PreviousTick;
|
||||
|
||||
|
@ -92,23 +92,22 @@ private:
|
|||
TUpdateIntraTimesFunc m_UpdateIntraTimesFunc;
|
||||
|
||||
// Playback
|
||||
struct CKeyFrame
|
||||
struct SKeyFrame
|
||||
{
|
||||
long m_Filepos;
|
||||
int m_Tick;
|
||||
};
|
||||
|
||||
struct CKeyFrameSearch
|
||||
{
|
||||
CKeyFrame m_Frame;
|
||||
CKeyFrameSearch *m_pNext;
|
||||
SKeyFrame(long Filepos, int Tick) :
|
||||
m_Filepos(Filepos), m_Tick(Tick)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class IConsole *m_pConsole;
|
||||
IOHANDLE m_File;
|
||||
long m_MapOffset;
|
||||
char m_aFilename[IO_MAX_PATH_LENGTH];
|
||||
CKeyFrame *m_pKeyFrames;
|
||||
std::vector<SKeyFrame> m_vKeyFrames;
|
||||
CMapInfo m_MapInfo;
|
||||
int m_SpeedIndex;
|
||||
|
||||
|
|
Loading…
Reference in a new issue