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
This commit is contained in:
Dawid Masiukiewicz 2020-05-01 19:26:21 +00:00
parent f67eb452cc
commit 54a6d5dec2
29 changed files with 1167 additions and 322 deletions

View file

@ -1,5 +1,8 @@
/************************************************************************************************************************
*Most important module. Almost every function is called from EntityManager.
Most important module. Almost every function is called from EntityManager.
Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz
License: BSD 3-clause, see LICENSE file in project root folder.
*/
module ecs.manager;
@ -28,37 +31,38 @@ export alias gEntityManager = EntityManager.instance;
alias SerializeVector = ecs.vector.Vector!ubyte;
/************************************************************************************************************************
*Entity manager is responsible for everything.
*
*Entity manager can be in three states:
* - registration: time between beginRegister() and endRegister() calls.
* - update: time between being() and end() calls.
* - default: when it's not in registration or update time
*
*Manager can be only in one state simultaneously.
*
*Manager must be initialized before use. There is global instance of EntityManager: EntityManager.instance or gEM as alias.
*
*Registration process consist of registration of passes, systems, entities and events.
*
*Pass is group of system which should be used inside one update() call. Passes are added as name (string) and can be referenced by name or id.<br/>
*System is structure responsible for update of specified group of entities. System consist of EntitiesData structure which contain components used
*by system and some callback. Main callback is onUpdate() which is called by update() entity manager function. Other callbacks are used as listeners for
*adding entites, tracking system lifetime and events handling.<br/>
*Component is basicly small fraction of data which is considered to be used as whole. In best scenario every byte of component is used when it's refered to.
*In practice sometimes it's better to join data into one component even if it's can be accessed separetly.<br/>
*Events are structures with data used to handle events. Event can contain for exmaple one floating point number used as damage dealt to entity.<br/>
*Entity is group of components. In memory entity is only ID which makes it's possible to take it's components. Components are grouped into chunks, and
*grouped by component type so entity can be fracted in big memory chunk.<br/>
*
*There is two types of update:
*<br/> - update(): function used to call update pass.
*<br/> - updateMT(): function used to call update pass multithreaded. This call only generates jobs which must be called by user.
Entity manager is responsible for everything.
Entity manager can be in three states:
- registration: time between beginRegister() and endRegister() calls.
- update: time between being() and end() calls.
- default: when it's not in registration or update time
Manager can be only in one state simultaneously.
Manager must be initialized before use. There is global instance of EntityManager: EntityManager.instance or gEM as alias.
Registration process consist of registration of passes, systems, entities and events.
Pass is group of system which should be used inside one update() call. Passes are added as name (string) and can be referenced by name or id.
System is structure responsible for update of specified group of entities. System consist of EntitiesData structure which contain components used
by system and some callback. Main callback is onUpdate() which is called by update() entity manager function. Other callbacks are used as listeners for
adding entites, tracking system lifetime and events handling.
Component is basicly small fraction of data which is considered to be used as whole. In best scenario every byte of component is used when it's refered to.
In practice sometimes it's better to join data into one component even if it's can be accessed separetly.
Events are structures with data used to handle events. Event can contain for exmaple one floating point number used as damage dealt to entity.
Entity is group of components. In memory entity is only ID which makes it's possible to take it's components. Components are grouped into chunks, and
grouped by component type so entity can be fracted in big memory chunk.
There is two types of update:
- update(): function used to call update pass.
- updateMT(): function used to call update pass multithreaded. This call only generates jobs which must be called by user.
*/
export struct EntityManager
{
/************************************************************************************************************************
*Initialize ECS.
Initialize ECS.
*/
export static void initialize(uint threads_count, uint page_size = 32768,
uint block_pages_count = 128)
@ -81,7 +85,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Deinitialize and destroy ECS. This function release whole memory.
Deinitialize and destroy ECS. This function release whole memory.
*/
export static void destroy()
{
@ -154,7 +158,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Begin registering process. Every register function should be called between beginRegister() and endRegister().
Begin registering process. Every register function should be called between beginRegister() and endRegister().
*/
export void beginRegister() nothrow @nogc
{
@ -172,7 +176,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*End registering process. Every register function should be called between beginRegister() and endRegister().
End registering process. Every register function should be called between beginRegister() and endRegister().
*/
export void endRegister()
{
@ -346,7 +350,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Same as "void registerSystem(Sys)(int priority, int pass = 0)" but use pass name instead of id.
Same as "void registerSystem(Sys)(int priority, int pass = 0)" but use pass name instead of id.
*/
void registerSystem(Sys)(int priority, const(char)[] pass_name)
{
@ -359,13 +363,13 @@ export struct EntityManager
}
/************************************************************************************************************************
*Register new System into EntityManager. This funcion generate glue between EntityManager and System.
*Systems can be registered from external dynamic library, and can be registered after adding entities too.
*System mustn't be registered before components which system want to use, in this case functions call assertion.
*
*Params:
*priority = system priority. Priority determines order of execution of systems updates
*pass = index of UpdatePass which sholud call system update
Register new System into EntityManager. This funcion generate glue between EntityManager and System.
Systems can be registered from external dynamic library, and can be registered after adding entities too.
System mustn't be registered before components which system want to use, in this case functions call assertion.
Params:
priority = system priority. Priority determines order of execution of systems updates
pass = index of UpdatePass which sholud call system update
*/
void registerSystem(Sys)(int priority, ushort pass = 0)
{
@ -1084,7 +1088,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Return system ECS api by id
Return system ECS api by id
*/
export System* getSystem(ushort id) nothrow @nogc
{
@ -1094,7 +1098,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Return pointer to system registered in manager
Return pointer to system registered in manager
*/
Sys* getSystem(Sys)() nothrow @nogc
{
@ -1115,7 +1119,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Register component into EntityManager.
Register component into EntityManager.
*/
void registerComponent(Comp)()
{
@ -1230,7 +1234,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Same as "void update(int pass = 0)" but use pass name instead of id.
Same as "void update(int pass = 0)" but use pass name instead of id.
*/
export void update(const(char)[] pass_name) nothrow @nogc
{
@ -1240,7 +1244,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Update systems. Should be called only between begin() and end().
Update systems. Should be called only between begin() and end().
*/
export void update(ushort pass = 0) nothrow @nogc
{
@ -1268,7 +1272,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Same as "void updateMT(int pass = 0)" but use pass name instead of id.
Same as "void updateMT(int pass = 0)" but use pass name instead of id.
*/
export void updateMT(const(char)[] pass_name) nothrow @nogc
{
@ -1431,7 +1435,7 @@ export struct EntityManager
}*/
/************************************************************************************************************************
*Return size of single page (block). Every entity data block has size of page.
Return size of single page (block). Every entity data block has size of page.
*/
uint pageSize()
{
@ -1439,8 +1443,8 @@ export struct EntityManager
}
/************************************************************************************************************************
*Return number of pages in single block allocation. Library allocate defined number of pages at once and assign it's
*for entities.
Return number of pages in single block allocation. Library allocate defined number of pages at once and assign it's
for entities.
*/
uint pagesInBlock()
{
@ -1465,11 +1469,11 @@ export struct EntityManager
}
/************************************************************************************************************************
*Allocate EntityTemplate with all components from entity witch it's data and returns pointer to it.
*
*Params:
*entity_id = ID of entity from which should be created template
*fill_default = if true, components will be filled with default data, instead entity data will be taken
Allocate EntityTemplate with all components from entity witch it's data and returns pointer to it.
Params:
entity_id = ID of entity from which should be created template
fill_default = if true, components will be filled with default data, instead entity data will be taken
*/
export EntityTemplate* allocateTemplate(EntityID entity_id, bool fill_default = false)
{
@ -1505,10 +1509,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*Allocate EntityTemplate with specifed components and returns pointer to it.
*
*Params:
*components_ids = array of components allocated with template
Allocate EntityTemplate with specifed components and returns pointer to it.
Params:
components_ids = array of components allocated with template
*/
export EntityTemplate* allocateTemplate(ushort[] components_ids)
{
@ -1551,10 +1555,13 @@ export struct EntityManager
}
/************************************************************************************************************************
*Allocate EntityTemplate with specifed components and returns pointer to it.
*
*Params:
*components_ids = array of components allocated with template
Allocate EntityTemplate from basic Template with modifications by adding and removing some components and returns pointer to it.
Arrays of components needen't to be checked for repeated components, as function itself check if components exist in base template.
Params:
base_tmpl = template from which components sould be copied
components_ids = array of new components to add
remove_components_ids = array of components to remove from base template
*/
export EntityTemplate* allocateTemplate(EntityTemplate* base_tmpl,
ushort[] components_ids, ushort[] remove_components_ids = null)
@ -1624,10 +1631,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*Returns entity type info.
*
*Params:
*ids = array of components
Returns entity type info.
Params:
ids = array of components
*/
export EntityInfo* getEntityInfo(ushort[] ids)
{
@ -1930,10 +1937,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*Returns pointer to entity.
*
*Params:
*id = ID of entity
Returns pointer to entity.
Params:
id = ID of entity
*/
export Entity* getEntity(EntityID id) nothrow @nogc
{
@ -1941,11 +1948,11 @@ export struct EntityManager
}
/************************************************************************************************************************
*Remove components from entity by IDs. Components will be removed on end of frame.
*
*Params:
*entity_id = ID of entity
*del_ids = array of components IDs
Remove components from entity by IDs. Components will be removed on end of frame.
Params:
entity_id = ID of entity
del_ids = array of components IDs
*/
export void removeComponents(EntityID entity_id, ushort[] del_ids) nothrow @nogc
{
@ -2051,11 +2058,11 @@ export struct EntityManager
}
/************************************************************************************************************************
*Remove coponents from entity.
*
*Params:
*Components = components types to remove
*entity_id = ID of entity
Remove coponents from entity.
Params:
Components = components types to remove
entity_id = ID of entity
*/
void removeComponents(Components...)(EntityID entity_id)
{
@ -2204,11 +2211,11 @@ export struct EntityManager
}
/************************************************************************************************************************
*Add components to entity. Components will be added on end of frame.
*
*Params:
*entity_id = ID of entity to remove
*comps = components to add
Add components to entity. Components will be added on end of frame.
Params:
entity_id = ID of entity to remove
comps = components to add
*/
void addComponents(Components...)(const EntityID entity_id, Components comps) nothrow @nogc
{
@ -2239,10 +2246,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*Free template memory.
*
*Params:
*template_ = pointer entity template allocated by EntityManager.
Free template memory.
Params:
template_ = pointer entity template allocated by EntityManager.
*/
export void freeTemplate(EntityTemplate* template_)
{
@ -2251,9 +2258,9 @@ export struct EntityManager
}
/************************************************************************************************************************
*Add copy of entity to system and returns pointer to it. Added copy has same data as copied entity. Returen pointer is
*valid only before one from commit(), begin() or end() will be called. To save entity to further use you should save ID
*instead of pointer.
Add copy of entity to system and returns pointer to it. Added copy has same data as copied entity. Returen pointer is
valid only before one from commit(), begin() or end() will be called. To save entity to further use you should save ID
instead of pointer.
*
*Params:
*id = ID of entity to be copyied.
@ -2305,11 +2312,11 @@ export struct EntityManager
}
/************************************************************************************************************************
*Add entity to system. Returen pointer is valid only before one from commit(), begin() or end() will be called. To save entity to further
*use you should save ID instead of pointer.
*
*Params:
*tmpl = pointer entity template allocated by EntityManager.
Add entity to system. Returen pointer is valid only before one from commit(), begin() or end() will be called. To save entity to further
use you should save ID instead of pointer.
Params:
tmpl = pointer entity template allocated by EntityManager.
*/
export Entity* addEntity(EntityTemplate* tmpl)
{
@ -2355,7 +2362,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Return block with free space for selected EntityInfo.
Return block with free space for selected EntityInfo.
*/
private EntitiesBlock* findBlockWithFreeSpace(EntityInfo* info) nothrow @nogc
{
@ -2383,7 +2390,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Return block with free space for selected EntityInfo. Additional this function is multithread safe.
Return block with free space for selected EntityInfo. Additional this function is multithread safe.
*/
private EntitiesBlock* findBlockWithFreeSpaceMT(EntityInfo* info)
{
@ -2427,10 +2434,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*Remove entity by ID. Entity will be removed on frame end.
*
*Params:
*id = id of entity to remove
Remove entity by ID. Entity will be removed on frame end.
Params:
id = id of entity to remove
*/
export void removeEntity(EntityID id)
{
@ -2513,10 +2520,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*functions return MetaData of page.
*
*Params:
*pointer = pointer to any data of entity (i.e. component data pointer)
functions return MetaData of page.
Params:
pointer = pointer to any data of entity (i.e. component data pointer)
*/
export EntitiesBlock* getMetaData(const void* pointer) nothrow @nogc
{
@ -2750,7 +2757,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Begin of update process. Should be called before any update is called.
Begin of update process. Should be called before any update is called.
*/
export void begin()
{
@ -2767,7 +2774,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*End of update process. Should be called after every update function.
End of update process. Should be called after every update function.
*/
export void end()
{
@ -2917,7 +2924,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Component info;
Component info;
*/
struct ComponentInfo
{
@ -2961,7 +2968,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Entity type info.
Entity type info.
*/
struct EntityInfo
{
@ -3133,7 +3140,7 @@ export struct EntityManager
}
/************************************************************************************************************************
*Meta data of every block of entities (contained at the begining of block).
Meta data of every block of entities (contained at the begining of block).
*/
struct EntitiesBlock
{
@ -3180,10 +3187,10 @@ export struct EntityManager
}
/************************************************************************************************************************
*Structure with data used to calling System calls.
*
*<i>first_block</i>, <i>begin</i>, <i>end</i>, <i>blocks</i> parameters are used
*to call partial info update
Structure with data used to calling System calls.
<i>first_block</i>, <i>begin</i>, <i>end</i>, <i>blocks</i> parameters are used
to call partial info update
*/
struct CallData
{