-remove update() function from entity -currently max supported components count is 64 per type
76 lines
3.4 KiB
D
76 lines
3.4 KiB
D
/************************************************************************************************************************
|
|
*Entity module.
|
|
*/
|
|
module ecs.entity;
|
|
|
|
import ecs.system;
|
|
import ecs.manager;
|
|
|
|
/************************************************************************************************************************
|
|
*Entity ID structure. Used as reference to Entity. Pointer to entity should be ever used to store entity reference!
|
|
*/
|
|
struct EntityID
|
|
{
|
|
///Index to entity in IDManager.
|
|
uint id;
|
|
///Counter required for reusing ID.
|
|
uint counter;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
*Structure of Entity. It's have only ID, but have full konwlege to get to components memory (If pointer to it is proper).
|
|
*/
|
|
struct Entity
|
|
{
|
|
///Entity ID.
|
|
EntityID id;
|
|
|
|
/************************************************************************************************************************
|
|
*Get specified component. If component doesn't exist function retun null. Pointer is valid only before next "commit()", "begin()" or "end()"
|
|
*function is called. Returned pointer shouldn't be used to store reference to entity data.
|
|
*/
|
|
T* getComponent(T)() const
|
|
{
|
|
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
|
EntityManager.EntityInfo* info = block.type_info;
|
|
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
|
return null;
|
|
|
|
static if (EntityID.sizeof == 8)
|
|
uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3);
|
|
else
|
|
uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof());
|
|
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof);
|
|
}
|
|
|
|
/*package void updateID() nothrow @nogc
|
|
{
|
|
EntityManager.instance.id_manager.update(this);
|
|
}*/
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
*Entity template structure.
|
|
*Entity contain whole information needed to create new entity. Allocating EntityTemplate is considered as more expensive operation
|
|
*than adding entity. Whole components memory is stored in EntityTemplate and is copyied to newly added entity.
|
|
*If you want to place several entity with small difference in data then you should take pointer to component and change it before every
|
|
*entity addition.
|
|
*There is no restriction about number of allocated templates. Single template can be used from multiple threads, but if you
|
|
*want to changes some components data before add entity (entity position for example) it's better to use multiple templates.
|
|
*/
|
|
export struct EntityTemplate
|
|
{
|
|
///Entity components data
|
|
ubyte[] entity_data;
|
|
///Pointer to entity type info.
|
|
EntityManager.EntityInfo* info;
|
|
|
|
/************************************************************************************************************************
|
|
*Get specified component. If component doesn't exist function return null. Returned pointer is valid during EntityTemplate lifetime.
|
|
*/
|
|
T* getComponent(T)() nothrow @nogc
|
|
{
|
|
if(T.component_id >= info.tmpl_deltas.length || info.tmpl_deltas[T.component_id] == ushort.max)return null;
|
|
return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]);
|
|
}
|
|
}
|