0ad/source/simulation/EntityHandles.h
janwas c0ed950657 had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).

it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.

after several hours, the code now requires fewer casts and less
guesswork.

other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.

This was SVN commit r5942.
2008-05-11 18:48:32 +00:00

119 lines
3.4 KiB
C++

// EntityHandles.h
//
// Entity smart pointer definitions.
//
// Usage: Use in place of a standard CEntity pointer.
// Handles dereference and pointer-to-member as a standard smart pointer.
// Reference counted. Handles are freed and entity classes released when refcount hits 0.
// For this reason, be careful where and how long you store these.
//
// Entities maintain their own handles via their HEntity me member.
// To release an entity, scramble this handle. The memory will be freed when the last reference to it expires.
//
// Standard CEntity pointers must not be used for a) anything that could be sent over the network.
// b) anything that will be kept between simulation steps.
// CEntity pointers will be faster for passing to the graphics subsytem, etc. where they won't be stored.
// And yes, most of this /is/ obvious. But it should be said anyway.
#ifndef INCLUDED_ENTITYHANDLES
#define INCLUDED_ENTITYHANDLES
#define INVALID_HANDLE 65535
// The maximum numerical value of an entity handle sent over the network
#define MAX_HANDLE 0x7fff
// If (handle & PS_ENTITY_SENTINEL_BIT) is non-zero, this is a terminating
// entity id. Reset the sentinel bit to get the original handle.
#define HANDLE_SENTINEL_BIT 0x8000
class CEntity;
class CEntityManager;
struct CEntityList;
class CStr8;
class CHandle
{
public:
CEntity* m_entity;
i16 m_refcount;
CHandle();
};
class HEntity
{
friend class CEntity;
friend class CEntityManager;
friend struct CEntityList;
u16 m_handle;
private:
void AddRef();
void DecRef();
HEntity( u16 index );
public:
HEntity();
HEntity( const HEntity& copy );
~HEntity();
void operator=( const HEntity& copy );
CEntity& operator*() const;
CEntity* operator->() const;
bool operator==( const HEntity& test ) const;
bool operator!=( const HEntity& test ) const { return( !operator==( test ) ); }
operator CEntity*() const;
// Returns true iff we are a valid handle, i.e. one to a non-deleted (but possibly destroyed) entity
bool IsValid() const;
// Returns true iff we are a valid handle to an entity that is not destroyed
bool IsAlive() const;
// Same as IsValid(); maybe this should be removed altogether to prevent confusion?
operator bool() const { return IsValid(); }
// Same as !IsValid()
bool operator!() const { return !IsValid(); };
size_t GetSerializedLength() const;
u8 *Serialize(u8 *buffer) const;
const u8 *Deserialize(const u8 *buffer, const u8 *end);
operator CStr8() const;
};
/*
CEntityList
DESCRIPTION: Represents a group of entities that is the target/subject of
a network command. Use for easy serialization of one or more entity IDs.
SERIALIZED FORMAT: The entities are stored as a sequence of 16-bit ints, the
termination of the list marked by an integer with HANDLE_SENTINEL_BIT
set. The length is thus 2*(number of entities)
*/
struct CEntityList: public std::vector<HEntity>
{
// Create an empty list
inline CEntityList()
{}
// Create a list from an existing entity vector
inline CEntityList(const std::vector<HEntity> &vect):
std::vector<HEntity>(vect)
{}
// Create a list containing one entity
inline CEntityList(HEntity oneEntity)
{
push_back(oneEntity);
}
size_t GetSerializedLength() const;
u8 *Serialize(u8 *buffer) const;
const u8 *Deserialize(const u8 *buffer, const u8 *end);
operator CStr8() const;
};
typedef CEntityList::iterator CEntityIt;
typedef CEntityList::const_iterator CEntityCIt;
#endif