/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef ENGINE_SHARED_SNAPSHOT_H #define ENGINE_SHARED_SNAPSHOT_H #include // CSnapshot class CSnapshotItem { public: int m_TypeAndID; int *Data() { return (int *)(this + 1); } int Type() const { return m_TypeAndID >> 16; } int ID() const { return m_TypeAndID & 0xffff; } int Key() const { return m_TypeAndID; } }; class CSnapshot { friend class CSnapshotBuilder; int m_DataSize; int m_NumItems; int *Offsets() const { return (int *)(this + 1); } char *DataStart() const { return (char *)(Offsets() + m_NumItems); } public: enum { OFFSET_UUID_TYPE = 0x4000, MAX_TYPE = 0x7fff, MAX_PARTS = 64, MAX_SIZE = MAX_PARTS * 1024 }; void Clear() { m_DataSize = 0; m_NumItems = 0; } int NumItems() const { return m_NumItems; } CSnapshotItem *GetItem(int Index) const; int GetItemSize(int Index) const; int GetItemIndex(int Key) const; int GetItemType(int Index) const; unsigned Crc(); void DebugDump(); static void RemoveExtraInfo(unsigned char *pData); }; // CSnapshotDelta class CSnapshotDelta { public: class CData { public: int m_NumDeletedItems; int m_NumUpdateItems; int m_NumTempItems; // needed? int m_aData[1]; }; private: enum { MAX_NETOBJSIZES = 64 }; short m_aItemSizes[MAX_NETOBJSIZES]; int m_aSnapshotDataRate[0xffff]; int m_aSnapshotDataUpdates[0xffff]; int m_SnapshotCurrent; CData m_Empty; void UndiffItem(int *pPast, int *pDiff, int *pOut, int Size); public: static int DiffItem(int *pPast, int *pCurrent, int *pOut, int Size); CSnapshotDelta(); CSnapshotDelta(const CSnapshotDelta &Old); int GetDataRate(int Index) { return m_aSnapshotDataRate[Index]; } int GetDataUpdates(int Index) { return m_aSnapshotDataUpdates[Index]; } void SetStaticsize(int ItemType, int Size); CData *EmptyDelta(); int CreateDelta(class CSnapshot *pFrom, class CSnapshot *pTo, void *pData); int UnpackDelta(class CSnapshot *pFrom, class CSnapshot *pTo, void *pData, int DataSize); }; // CSnapshotStorage class CSnapshotStorage { public: class CHolder { public: CHolder *m_pPrev; CHolder *m_pNext; int64 m_Tagtime; int m_Tick; int m_SnapSize; CSnapshot *m_pSnap; CSnapshot *m_pAltSnap; }; CHolder *m_pFirst; CHolder *m_pLast; CSnapshotStorage() { Init(); }; ~CSnapshotStorage() { PurgeAll(); }; void Init(); void PurgeAll(); void PurgeUntil(int Tick); void Add(int Tick, int64 Tagtime, int DataSize, void *pData, int CreateAlt); int Get(int Tick, int64 *pTagtime, CSnapshot **ppData, CSnapshot **ppAltData); }; class CSnapshotBuilder { enum { MAX_ITEMS = 1024, MAX_EXTENDED_ITEM_TYPES = 64, }; char m_aData[CSnapshot::MAX_SIZE]; int m_DataSize; int m_aOffsets[MAX_ITEMS]; int m_NumItems; int m_aExtendedItemTypes[MAX_EXTENDED_ITEM_TYPES]; int m_NumExtendedItemTypes; void AddExtendedItemType(int Index); int GetExtendedItemTypeIndex(int TypeID); bool m_Sixup; public: CSnapshotBuilder(); void Init(bool Sixup = false); void *NewItem(int Type, int ID, int Size); CSnapshotItem *GetItem(int Index); int *GetItemData(int Key); int Finish(void *pSnapdata); }; #endif // ENGINE_SNAPSHOT_H