Files
libsst/Include/ZSimulation/ZPropertyBuffer.hpp
2026-04-03 00:22:39 -05:00

134 lines
4.2 KiB
C++

/*
ZPropertyBuffer.hpp
Author: author_name <author_email@762studios.com>
Created: 8/30/2015
Purpose:
The property buffer system is an allocator which holds entity property data in
contiguous blocks of memory that can then be synchronized across the network when
properties change, though properties can be kept in non-synchronized buffers for
local use.
The buffer keeps both a read and write copy of the properties which can be updated
on call.
This allocator does not lock, so any locking that would be required must be handled
by the caller.
In order to have proper synchronization, each entity that has properties allocated
should have it's synchronized variables created in the same order on all machines.
This will ensure that the data layouts are identical and proper synchronization can
occur.
License:
TODO
*/
#pragma once
#ifndef _ZPROPERTYBUFFER_HPP
#define _ZPROPERTYBUFFER_HPP
#include "ZSimulationDefs.hpp"
#include "ZPropertyBufferUpdate.hpp"
// forward decl
struct PropertyPage;
class ZNetworkUpdateStream;
// class decl
class ZPropertyBuffer
{
public:
// key used to look up allocated data in the property buffer
typedef uint64_t PropertyKey;
// used to flag synchronization type (none, send, or receive)
enum SyncMode {
SYNC_NONE = 0,
SYNC_SEND = 1,
SYNC_RECV = 2,
SYNC_ENUM_SIZE
};
// data struct for property data
struct Property {
void* Read; // pointer to the read property
void* Write; // pointer to the write property
size_t Size; // size of the property
PropertyKey Key; // the property key
};
// c'tor
ZPropertyBuffer();
// d'tor
~ZPropertyBuffer();
/*
Allocates a chunk of memory in the property buffer given the entity id, the entity size,
and whether or not the property should be synchronized. The read buffer for the property
is returned.
Allocations from these methods return static sized properties - they will not ever be able
to increase in size - alloc a new property and remove the old one in order to increase
size. The size limit on a synchronized property is 1024 bytes.
In order to have proper synchronization, each entity that has properties allocated
should have its synchronized variables created in the same order on all machines.
This will ensure that the data layouts are identical and proper synchronization can
occur.
*/
Property AllocProperty(eID id, size_t size, SyncMode mode = SYNC_NONE );
/*
Deallocation methods, which deallocate previously allocated property data. The version
which takes an entity id deallocates all data associated with that entity id. The
version which takes a property key merely deallocates that particular property.
Deallocating individual properties is not terribly fast, so avoid it where possible.
*/
void DeallocEntity(eID id);
void DeallocProperty(PropertyKey key, size_t size);
/*
Flags a previously allocated property as modified. The size (in bytes) of the property
is required.
*/
void FlagModified(PropertyKey key, size_t size);
/*
Updates the read properties from the write properties where modifications have happened.
The version which takes an entity id will update a single entities properties.
If told to synchronize, the buffer will queue up the network updates needed to sync
the buffer state.
*/
void UpdateModified(bool sync, ZNetworkUpdateStream& stream);
void UpdateModified(eID id, bool sync, ZNetworkUpdateStream& stream);
/*
Applies buffer updates that have been read from the network. These are applied directly
to the read value of the property.
*/
void ApplyBufferUpdates(const ZArray<ZPropertyBufferUpdate*>& updates);
private:
/* synchronized and non-synchronized data storage */
ZArray<PropertyPage*> Pages[2]; // the individual buffer pages (synchronized and local)
ZHashMap<eID, uint32_t> IdPageMap; // maps the entity id to its page number
ZArray<uint32_t> Avail; // available indices from dealloc'd entities
// given the property key will get the data, page, and synchronization flag
void* GetData(PropertyKey key, int rw, PropertyPage** page_out = NULL, SyncMode* mode_out = NULL);
// will alloc data for the property (searches page, otherwise makes new pages)
Property AllocData(PropertyPage* page, eID id, uint32_t page_idx, size_t size, SyncMode mode);
};
#endif