/******************************************************************************** * ReactPhysics3D physics library, http://www.reactphysics3d.com * * Copyright (c) 2010-2018 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * * In no event will the authors be held liable for any damages arising from the * * use of this software. * * * * Permission is granted to anyone to use this software for any purpose, * * including commercial applications, and to alter it and redistribute it * * freely, subject to the following restrictions: * * * * 1. The origin of this software must not be misrepresented; you must not claim * * that you wrote the original software. If you use this software in a * * product, an acknowledgment in the product documentation would be * * appreciated but is not required. * * * * 2. Altered source versions must be plainly marked as such, and must not be * * misrepresented as being the original software. * * * * 3. This notice may not be removed or altered from any source distribution. * * * ********************************************************************************/ #ifndef REACTPHYSICS3D_ENTITY_H #define REACTPHYSICS3D_ENTITY_H // Libraries #include "configuration.h" /// Namespace reactphysics3d namespace reactphysics3d { // Structure Entity /** * This class is used to identify an entity in the Entity-Component-System. * Entities are used for bodies in the physics engine. The id of an entity is * a 32 bits integer that is separated in two parts. The index and the generation * parts. The idea is that the index part directly gives us the index of the entity * in a lookup array. However, we want to support deletion of the entities. That's why * we have the generation part. This number is used to distinguish the entities created * at the same index in the array. If it is the case, we will increase the generation number * each time. * * We use 24 bits for the index. Therefore, we support 16 millions simultaneous entries. * We use 8 bits for the generation. Therefore, we support 256 entries created at the same index. * To prevent reaching the 256 entries too fast, we make sure that we do not reuse the same index * slot too ofen. To do that, we put recycled indices in a queue and only reuse values from that * queue when it contains at least MINIMUM_FREE_INDICES values. It means, an id will reappear until * its index has run 256 laps through the queue. It means that we must create and destroy at least * 256 * MINIMUM_FREE_INDICES entities until an id can reappear. This seems reasonably safe. * * This implementation is based on the following article: * http://bitsquid.blogspot.com/2014/08/building-data-oriented-entity-system.html */ struct Entity { private: /// Number of bits reserved for the index static const uint32 ENTITY_INDEX_BITS; /// Mask for the index part of the id static const uint32 ENTITY_INDEX_MASK; /// Number of bits reserved for the generation number static const uint32 ENTITY_GENERATION_BITS; /// Mask for the generation part of the id static const uint32 ENTITY_GENERATION_MASK; /// Minimum of free indices in the queue before we reuse one from the queue static const uint32 MINIMUM_FREE_INDICES; public: // -------------------- Attributes -------------------- // /// Id of the entity uint32 id; // -------------------- Methods -------------------- // /// Constructor Entity(uint32 index, uint32 generation); /// Return the lookup index of the entity in a array uint32 getIndex() const; /// Return the generation number of the entity uint32 getGeneration() const; /// Assignment operator Entity& operator=(const Entity& entity); /// Equality operator bool operator==(const Entity& entity) const; /// Inequality operator bool operator!=(const Entity& entity) const; // -------------------- Friendship -------------------- // friend class EntityManager; }; // Return the lookup index of the entity in a array inline uint32 Entity::getIndex() const { return id & ENTITY_INDEX_MASK; } // Return the generation number of the entity inline uint32 Entity::getGeneration() const { return (id >> ENTITY_INDEX_BITS) & ENTITY_GENERATION_MASK; } // Equality operator inline bool Entity::operator==(const Entity& entity) const { return entity.id == id; } // Inequality operator inline bool Entity::operator!=(const Entity& entity) const { return entity.id != id; } } // Hash function for a reactphysics3d Entity namespace std { template <> struct hash { size_t operator()(const reactphysics3d::Entity& entity) const { return entity.id; } }; } #endif