bubel-ecs/source/ecs/entity.d
Dawid Masiukiewicz 54a6d5dec2 CI and common update:
-added webpage deploymnet stage
-added separate build stage which build all binaries and generate documentation
-added Emscripten build stage for merge to master only
-added VBO batch rendering (current default, no render mode switch yet)
-fixed camera positioning calculation
-fixed buffer issue with WebGL
-added viewport scalling (at least 300 pixels height). Pixels are scalled if screen is bigger.
-center demos gameplay area
-added fullpage html template for Emscripten build
2020-05-01 19:26:21 +00:00

76 lines
3.4 KiB
D

/************************************************************************************************************************
Entity module.
Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz
License: BSD 3-clause, see LICENSE file in project root folder.
*/
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);
}
}
/************************************************************************************************************************
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]);
}
}