134 lines
4.2 KiB
C++
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 |