Merge branch 'master' into wasm_demos
# Conflicts: # demos/external/sources/mmutils/thread_pool.d # tests/meson.build
This commit is contained in:
commit
84a5cbef13
32 changed files with 1568 additions and 1535 deletions
|
|
@ -6,6 +6,7 @@ stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
- testcov
|
- testcov
|
||||||
|
- build_wasm
|
||||||
- build_emscripten
|
- build_emscripten
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
|
|
@ -40,7 +41,7 @@ test_dmd_betterC:
|
||||||
stage: test
|
stage: test
|
||||||
image: frolvlad/alpine-glibc
|
image: frolvlad/alpine-glibc
|
||||||
script:
|
script:
|
||||||
- binaries/dmd_release_unittest_bc
|
- binaries/dmd_debug_unittest_bc
|
||||||
artifacts:
|
artifacts:
|
||||||
reports:
|
reports:
|
||||||
junit: test_report.xml
|
junit: test_report.xml
|
||||||
|
|
@ -57,8 +58,8 @@ coverage_test_dmd:
|
||||||
after_script:
|
after_script:
|
||||||
- bash <(curl -s https://codecov.io/bash) -s reports -t 1a0c0169-a721-4085-8252-fed4755dcd8c
|
- bash <(curl -s https://codecov.io/bash) -s reports -t 1a0c0169-a721-4085-8252-fed4755dcd8c
|
||||||
|
|
||||||
build_wasm:
|
wasm:
|
||||||
stage: build
|
stage: build_wasm
|
||||||
image: "registry.gitlab.com/mergul/bubel-ecs:latest"
|
image: "registry.gitlab.com/mergul/bubel-ecs:latest"
|
||||||
script:
|
script:
|
||||||
- /bin/bash /compile_wasm.sh
|
- /bin/bash /compile_wasm.sh
|
||||||
|
|
@ -68,7 +69,7 @@ build_wasm:
|
||||||
paths:
|
paths:
|
||||||
- build
|
- build
|
||||||
rules:
|
rules:
|
||||||
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
|
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_BRANCH == "master"'
|
||||||
when: always
|
when: always
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
|
@ -76,11 +77,11 @@ emscripten:
|
||||||
stage: build_emscripten
|
stage: build_emscripten
|
||||||
image: "registry.gitlab.com/mergul/bubel-ecs/emscripten:latest"
|
image: "registry.gitlab.com/mergul/bubel-ecs/emscripten:latest"
|
||||||
dependencies:
|
dependencies:
|
||||||
- build_wasm
|
- wasm
|
||||||
script:
|
script:
|
||||||
- /bin/bash /build.sh
|
- /bin/bash /build.sh
|
||||||
rules:
|
rules:
|
||||||
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
|
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_BRANCH == "master"'
|
||||||
when: always
|
when: always
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1h
|
expire_in: 1h
|
||||||
|
|
@ -90,12 +91,15 @@ emscripten:
|
||||||
pages:
|
pages:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
image: frolvlad/alpine-glibc
|
image: frolvlad/alpine-glibc
|
||||||
|
dependencies:
|
||||||
|
- wasm
|
||||||
|
- emscripten
|
||||||
script:
|
script:
|
||||||
- mkdir public
|
- mkdir public
|
||||||
- cp -r wasm/* public/
|
- cp -r wasm/* public/
|
||||||
- cp -r build/public/* public/
|
- cp -r build/public/* public/
|
||||||
rules:
|
rules:
|
||||||
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
|
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||||
when: always
|
when: always
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1h
|
expire_in: 1h
|
||||||
|
|
|
||||||
95
README.md
95
README.md
|
|
@ -2,11 +2,11 @@
|
||||||
[](https://gitlab.com/Mergul/bubel-ecs/-/commits/master)
|
[](https://gitlab.com/Mergul/bubel-ecs/-/commits/master)
|
||||||
[](https://codecov.io/gl/Mergul/bubel-ecs)
|
[](https://codecov.io/gl/Mergul/bubel-ecs)
|
||||||
|
|
||||||
BubelECS is Entity-Component-System architectural pattern implementation in D language.
|
**Bubel ECS** is Entity-Component-System architectural pattern implementation in D language.
|
||||||
Library aims to delivery fast and flexible architecture for developing games. Library is **@nogc** and **betterC** compatible. WASM is supported thorugh Emscripten.
|
Library aims to delivery fast and flexible architecture for developing games. Library is **@nogc** and **betterC** compatible. WASM is supported thorugh Emscripten.
|
||||||
Project haven't any external dependencies.
|
Project haven't any external dependencies.
|
||||||
|
|
||||||
BubelECS was tested on Linux, Windows, Android and WASM.
|
Bubel ECS was tested on Linux, Windows, Android and WASM.
|
||||||
|
|
||||||
**Currently library is in beta stage so some significant API changes can appear.**
|
**Currently library is in beta stage so some significant API changes can appear.**
|
||||||
|
|
||||||
|
|
@ -16,21 +16,21 @@ For core information about Entity-Component-System architectural pattern please
|
||||||
|
|
||||||
Main design principles are:
|
Main design principles are:
|
||||||
|
|
||||||
* **Data oriented design** - components memory is packed into tight block so iterating over entity components is cache friendly
|
* **Data oriented design** - components memory is packed into tight blocks so iterating over entity components is cache friendly
|
||||||
* **Fast and safe EntityID** - every entity is referenced by its unique ID. Accessing by ID is safe even if entity don'y exist. Access by ID is constant time operation.
|
* **Fast and safe EntityID** - every entity is referenced by its unique ID. Accessing by ID is safe even if entity doesn't exists. Accessing by ID is constant time operation.
|
||||||
* **Multithreading support** - whole library was developed with multithreading in mind. Adding components is thread-friendly so you get usable EntityID as early as possible. Operations like adding or removing components are deferred to end of frame. Dependencies between systems parallel execution are generated automatically.
|
* **Multithreading support** - whole library was developed with multithreading in mind. Adding components is thread-friendly so you get usable EntityID as early as possible. Operations like adding or removing components are deferred to end of frame. Dependencies between systems parallel execution are generated automatically.
|
||||||
* **Good logic separation** - system needs information only about components which it's use, there is no relation between systems. Systems can be compiled as multiple separate libraries and used together.
|
* **Good logic separation** - system needs information only about components which it uses, there is no relation between systems. Systems can be compiled as multiple separate libraries and used together.
|
||||||
* **Flexible execution model** - system iterate over entities which meet specified conditions. Components can be marked as required, optional or excluded. Systems are exectued in specific order determined by system priority.
|
* **Flexible execution model** - system iterate over entities which meet specified conditions. Components can be marked as required, optional or excluded. Systems are exectued in specific order determined by system priority.
|
||||||
* **Builtin events handling** - library has builtin support for event handlig to makes easier communication between different entities.
|
* **Builtin events handling** - library has builtin support for event handlig to makes easier communication between different entities.
|
||||||
* **Hot-reload** - hot-reloading for systems should be as easy as possible. In other words library should give functionality to support hot-reload of systems and components with minimal work. **(WIP!)**.
|
* **Hot-reload** - hot-reloading for systems should be as easy as possible. In other words library should give functionality to support hot-reload of systems and components with minimal work. **(WIP!)**.
|
||||||
|
|
||||||
There are some assumptions that should be considered when developing application:
|
There are some assumptions that should be considered when developing application:
|
||||||
|
|
||||||
* Iterating over components is fastest way of access data so it's should be main way of making calculations.
|
* Iterating over components throught system ```onUpdate()``` callback is fastest way of access data so it's should be main way of making calculations.
|
||||||
* Using of direct access and events should be used very wisely and minimized.
|
* Using direct access and events should be used very wisely and minimized.
|
||||||
* Direct component access is faster than events, because events must buffer memory and call multiple system handler callbacks.
|
* Direct component access is faster than events, because events must buffer memory and call multiple system handler callbacks.
|
||||||
* Components can be used to marking entities, assingment to systems and changing logic of entity in runtime. Using too much component based marking can lead to memory fragmentation and performence drop.
|
* Components can be used to marking entities, assingment to systems and changing logic of entity in runtime. Using too much component based marking can lead to memory fragmentation and performence drop.
|
||||||
* Systems give great opporunity to separate game logic. Systems can be enabled and disabled easly in runtime. It's can be used to enabling some debug systems if needed. Additionaly this concept makes game logic changes easier to deal with. If you develop your application wisely it should be trivial to change some core logic by changing only several systems or adding some new systems. Every entity can easily takes some behaviour from different entity type by adding several components.
|
* Systems give great opporunity to separate game logic. Systems can be enabled and disabled easly in runtime. It's can be used to enabling some debug systems if needed. Additionaly this concept makes game logic changes easier to deal with. If you develop your application wisely it should be trivial to change some core logic by changing only several systems or adding some new. Every entity can easily takes some behaviour from different entity type by adding several components.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
|
@ -40,26 +40,27 @@ There are some assumptions that should be considered when developing application
|
||||||
* EntityTemplates
|
* EntityTemplates
|
||||||
* Basic events handling
|
* Basic events handling
|
||||||
* Easy systems ordering
|
* Easy systems ordering
|
||||||
* Automatic multithreaded jobs generating
|
|
||||||
* Runtime and fast components adding and removing
|
* Runtime and fast components adding and removing
|
||||||
* Listeners for adding and removing entity components inside systems
|
* Listeners for adding and removing entity components inside systems
|
||||||
* Update passes
|
* Update passes
|
||||||
* Calling custom callbacks for system entity groups
|
* Calling custom callbacks for system entity groups
|
||||||
* betterC compatibility
|
* betterC compatibility
|
||||||
* Emscripten compatibility
|
* Emscripten compatibility
|
||||||
|
* Automatic multithreaded jobs generation
|
||||||
|
* External dependencies - ability to provide dependencies between systems which aren't related to components
|
||||||
|
* Compatibility with all big compilers: DMD, LDC, GDC.
|
||||||
|
|
||||||
### Planned
|
### Planned
|
||||||
|
|
||||||
* Worlds - every world works as separate environment. Entities don't with entities from different world. Systems and components should be registered for every world separately.
|
* Worlds - every world works as separate environment. Entities don't interact with entities from different world. Systems and components should be registered for every world separately.
|
||||||
* Hot-reload support - currently only reloading systems (their functions) works. There is possibility to serialize every entity and system, but it's should be provided by library itself with special callbacks and helpers. Additionaly planned is system which helps with taking new EntityID from serialized identifiers.
|
* Hot-reload support - currently only reloading systems (their functions) works. There is possibility to serialize every entity and system, but it's should be provided by library itself with special callbacks and helpers. Additionaly planned is system which helps with taking new EntityID from serialized identifiers.
|
||||||
* External dependencies - ability to provide dependencies between system which isn't related to components.
|
|
||||||
* Static components - this components will have different memory model and can be accessed only directly. It will be slower to access but won't trigger memory copy when component is added. It should fix problem with big components which isn't needed by systems iteration callbacks or is required rarely.
|
* Static components - this components will have different memory model and can be accessed only directly. It will be slower to access but won't trigger memory copy when component is added. It should fix problem with big components which isn't needed by systems iteration callbacks or is required rarely.
|
||||||
* Better EventManager - there are several optimization and improvements that can be added in the future.
|
* Better EventManager - there are several optimization and improvements that can be added in the future (e.g. multithreading).
|
||||||
* More demos and examples - demo appliaction is very basic now, but in future more minigames and sanbox mode (opportunity to mix many components and systems) are planned.
|
* More demos and examples - demo appliaction is very basic now, but in future more minigames and sanbox mode (opportunity to mix many components and systems) are planned.
|
||||||
* C API - in highly depends on amount of work required. Makes possible to use library from different languages.
|
* C API - it's highly depends on amount of work required. Makes it possible to use library from different languages.
|
||||||
* More smaller improvements...
|
* More smaller improvements...
|
||||||
|
|
||||||
For more information about design and usage feel free to read [documentation](https://mergul.gitlab.io/bubel-ecs/ecs.html)**(WIP)** and [WIKI](https://gitlab.com/Mergul/bubel-ecs/-/wikis/home).
|
For more information about design and usage feel free to read [documentation](https://mergul.gitlab.io/bubel-ecs/ecs.html) and [WIKI](https://gitlab.com/Mergul/bubel-ecs/-/wikis/home)**(WIP)**.
|
||||||
|
|
||||||
## Build Instructions
|
## Build Instructions
|
||||||
|
|
||||||
|
|
@ -68,7 +69,7 @@ Supported build systems are DUB and Meson.
|
||||||
|
|
||||||
##### DUB
|
##### DUB
|
||||||
```shell
|
```shell
|
||||||
#available configurations: library, dynlib, library-betterC, dynlib-betterC
|
#available configurations: library, dynlib, library-betterC, dynlib-betterC, unittest-runner, unittest-runner-betterC
|
||||||
dub build -c library -b release
|
dub build -c library -b release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -90,17 +91,32 @@ python compile_wasm.py -opt
|
||||||
adrdox -i source/bubel/ecs/ -o docs/ -s skeleton.html
|
adrdox -i source/bubel/ecs/ -o docs/ -s skeleton.html
|
||||||
```
|
```
|
||||||
|
|
||||||
For more detailed build options please check documentation for used build system.
|
|
||||||
|
|
||||||
## Demos
|
## Demos
|
||||||
|
|
||||||
Repository contain demo application. You can check demo [online](https://mergul.gitlab.io/bubel-ecs/ecs_demo.html) or build it form source code using DUB. \
|
Repository contain demo application. You can check demo [online](https://mergul.gitlab.io/bubel-ecs/ecs_demo.html) or build it form source code using Meson. \
|
||||||
Online demo support multithreading and page tries to check if client support WASM multithreading or not and loads properly JS and WASM code. It was tested on Chrome, Firefox, Opera, Brave on Linux and Android. On firefox there is problem with multithreaded version so if demo don't works please try to disable shared_memory in browser flags.
|
Online demo support multithreading and page tries to check if client support WASM multithreading or not and loads proper JS and WASM code. It was tested on Chrome, Firefox, Opera, Brave on Linux, Windows and Android. On firefox there is problem with multithreaded version so if demo doesn't work please try to disable shared_memory in browser flags.
|
||||||
|
|
||||||
|
Demos uses these libraries: SDL2, SDL2_Image, bindbc-loader, bindbc-sdl, cimgui, glad, mmutils. \
|
||||||
|
C++ compiler is required for building dependencies.
|
||||||
|
|
||||||
|
Meson is preferred way of building demos. It will download and compile dependencies automatically. DUB version is used only for library development. Build instructions:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
#use '-DbetterC=true ' to build betterC code
|
||||||
|
meson build . -DBuildDemos=true #add '--buildtype=release' to build release code
|
||||||
|
cd build
|
||||||
|
ninja
|
||||||
|
```
|
||||||
|
|
||||||
## Code example
|
## Code example
|
||||||
|
|
||||||
```d
|
```d
|
||||||
|
|
||||||
|
import bubel.ecs.core;
|
||||||
|
import bubel.ecs.manager;
|
||||||
|
import bubel.ecs.attributes;
|
||||||
|
import std.array : staticArray;
|
||||||
|
|
||||||
struct Position
|
struct Position
|
||||||
{
|
{
|
||||||
float x;
|
float x;
|
||||||
|
|
@ -122,7 +138,7 @@ struct UpdateSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System; //makes struct system
|
mixin ECS.System; //makes struct system
|
||||||
|
|
||||||
ECS.ExcludedComponents!(StaticFlag); //prevents static entities from update
|
mixin ECS.ExcludedComponents!(StaticFlag); //prevents static entities from update
|
||||||
|
|
||||||
struct EntitiesData
|
struct EntitiesData
|
||||||
{
|
{
|
||||||
|
|
@ -136,26 +152,31 @@ struct UpdateSystem
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length) //iterate over entities
|
foreach(i; 0..data.length) //iterate over entities
|
||||||
{
|
{
|
||||||
data.positions[i].x += data.velocities[i].x * dt;
|
data.positions[i].x += data.velocities[i].x;
|
||||||
data.positions[i].y += data.velocities[i].y * dt;
|
data.positions[i].y += data.velocities[i].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
manager.beginRegister();
|
//initialize ECS
|
||||||
|
EntityManager.initialize();
|
||||||
|
|
||||||
|
//begin registering process
|
||||||
|
gEntityManager.beginRegister();
|
||||||
//register components
|
//register components
|
||||||
manager.registerComponent!Position;
|
gEntityManager.registerComponent!Position;
|
||||||
manager.registerComponent!Velocity;
|
gEntityManager.registerComponent!Velocity;
|
||||||
manager.registerComponent!StaticFlag;
|
gEntityManager.registerComponent!StaticFlag;
|
||||||
//register system with priority 0
|
//register system with priority 0
|
||||||
manager.registerSystem!UpdateSystem(0);
|
gEntityManager.registerSystem!UpdateSystem(0);
|
||||||
manager.endRegister();
|
//end registering process
|
||||||
|
gEntityManager.endRegister();
|
||||||
|
|
||||||
//allocate template
|
//allocate template
|
||||||
EntityTemplate* tmpl = manager.allocateEmplate([becsID!Velocity, becsID!Position].staticArray);
|
EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!Velocity, becsID!Position].staticArray);
|
||||||
scope (exit) manager.freeTemplate(tmpl);
|
scope (exit) gEntityManager.freeTemplate(tmpl);
|
||||||
|
|
||||||
//gets pointer to template component data
|
//gets pointer to template component data
|
||||||
Position* position = tmpl.getComponent!Position;
|
Position* position = tmpl.getComponent!Position;
|
||||||
|
|
@ -163,12 +184,15 @@ void main()
|
||||||
{
|
{
|
||||||
position.x = i % 10;
|
position.x = i % 10;
|
||||||
position.y = i / 10;
|
position.y = i / 10;
|
||||||
manager.addEntity(tmpl);
|
gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.begin(); //start frame, inside system onBegin callbacks are called
|
gEntityManager.begin(); //start frame, inside system onBegin callbacks are called
|
||||||
manager.update(); //update all systems, there onUpdate callbacks are called
|
gEntityManager.update(); //update all systems, there onUpdate callbacks are called
|
||||||
manager.end(); //end frame, inside system onEnd callbacks are called
|
gEntityManager.end(); //end frame, inside system onEnd callbacks are called*/
|
||||||
|
|
||||||
|
//free ECS data
|
||||||
|
EntityManager.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -176,4 +200,5 @@ void main()
|
||||||
## Links
|
## Links
|
||||||
|
|
||||||
Documentation: https://mergul.gitlab.io/bubel-ecs/ecs.html \
|
Documentation: https://mergul.gitlab.io/bubel-ecs/ecs.html \
|
||||||
|
Wiki: https://gitlab.com/Mergul/bubel-ecs/-/wikis/home \
|
||||||
Online demo: https://mergul.gitlab.io/bubel-ecs/ecs_demo.html
|
Online demo: https://mergul.gitlab.io/bubel-ecs/ecs_demo.html
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,7 @@
|
||||||
"libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"],
|
"libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"],
|
||||||
"lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"],
|
"lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"],
|
||||||
"dflags-ldc" : [
|
"dflags-ldc" : [
|
||||||
"--ffast-math",
|
"--ffast-math"
|
||||||
"-enable-cross-module-inlining"
|
|
||||||
],
|
],
|
||||||
"configurations" : [
|
"configurations" : [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
278
demos/external/sources/mmutils/thread_pool.d
vendored
278
demos/external/sources/mmutils/thread_pool.d
vendored
|
|
@ -1,19 +1,10 @@
|
||||||
module mmutils.thread_pool;
|
module mmutils.thread_pool;
|
||||||
|
|
||||||
import bubel.ecs.atomic;
|
|
||||||
|
|
||||||
//import core.stdc.stdio;
|
|
||||||
//import core.stdc.stdlib : free, malloc, realloc;
|
|
||||||
//import core.stdc.string : memcpy;
|
|
||||||
|
|
||||||
//import std.stdio;
|
|
||||||
import std.algorithm : map;
|
import std.algorithm : map;
|
||||||
|
|
||||||
version = MM_NO_LOGS; // Disable log creation
|
version = MM_NO_LOGS; // Disable log creation
|
||||||
//version = MM_USE_POSIX_THREADS; // Use posix threads insted of standard library, required for betterC
|
//version = MM_USE_POSIX_THREADS; // Use posix threads insted of standard library, required for betterC
|
||||||
|
|
||||||
version (Posix)version = MM_USE_POSIX_THREADS;
|
|
||||||
|
|
||||||
version (WebAssembly)
|
version (WebAssembly)
|
||||||
{
|
{
|
||||||
version = MM_NO_LOGS;
|
version = MM_NO_LOGS;
|
||||||
|
|
@ -31,8 +22,15 @@ else
|
||||||
|
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
{
|
{
|
||||||
import bubel.ecs.std;
|
version (Posix) version = MM_USE_POSIX_THREADS;
|
||||||
extern (C) __gshared int _d_eh_personality(int, int, size_t, void*, void*)
|
|
||||||
|
extern (C) void free(void*) @nogc nothrow @system;
|
||||||
|
extern (C) void* malloc(size_t size) @nogc nothrow @system;
|
||||||
|
extern (C) void* realloc(void*, size_t size) @nogc nothrow @system;
|
||||||
|
extern (C) void* memcpy(return void*, scope const void*, size_t size) @nogc nothrow @system;
|
||||||
|
|
||||||
|
//hacks for LDC
|
||||||
|
/*extern (C) __gshared int _d_eh_personality(int, int, size_t, void*, void*)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +43,7 @@ version (D_BetterC)
|
||||||
extern (C) void* _d_allocmemory(size_t sz)
|
extern (C) void* _d_allocmemory(size_t sz)
|
||||||
{
|
{
|
||||||
return malloc(sz);
|
return malloc(sz);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -54,8 +52,132 @@ else
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
//////////////////// Alloc ///////////////////
|
/////////////// Atomics //////////////////////
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
version (ECSEmscripten)
|
||||||
|
{
|
||||||
|
import std.traits;
|
||||||
|
|
||||||
|
enum MemoryOrder
|
||||||
|
{
|
||||||
|
acq,
|
||||||
|
acq_rel,
|
||||||
|
raw,
|
||||||
|
rel,
|
||||||
|
seq
|
||||||
|
}
|
||||||
|
|
||||||
|
extern (C) ubyte emscripten_atomic_cas_u8(void* addr, ubyte oldVal, ubyte newVal) @nogc nothrow pure;
|
||||||
|
extern (C) ushort emscripten_atomic_cas_u16(void* addr, ushort oldVal, ushort newVal) @nogc nothrow pure;
|
||||||
|
extern (C) uint emscripten_atomic_cas_u32(void* addr, uint oldVal, uint newVal) @nogc nothrow pure;
|
||||||
|
|
||||||
|
extern (C) ubyte emscripten_atomic_load_u8(const void* addr) @nogc nothrow pure;
|
||||||
|
extern (C) ushort emscripten_atomic_load_u16(const void* addr) @nogc nothrow pure;
|
||||||
|
extern (C) uint emscripten_atomic_load_u32(const void* addr) @nogc nothrow pure;
|
||||||
|
|
||||||
|
extern (C) ubyte emscripten_atomic_store_u8(void* addr, ubyte val) @nogc nothrow pure;
|
||||||
|
extern (C) ushort emscripten_atomic_store_u16(void* addr, ushort val) @nogc nothrow pure;
|
||||||
|
extern (C) uint emscripten_atomic_store_u32(void* addr, uint val) @nogc nothrow pure;
|
||||||
|
|
||||||
|
extern (C) ubyte emscripten_atomic_add_u8(void* addr, ubyte val) @nogc nothrow pure;
|
||||||
|
extern (C) ushort emscripten_atomic_add_u16(void* addr, ushort val) @nogc nothrow pure;
|
||||||
|
extern (C) uint emscripten_atomic_add_u32(void* addr, uint val) @nogc nothrow pure;
|
||||||
|
|
||||||
|
extern (C) ubyte emscripten_atomic_sub_u8(void* addr, ubyte val) @nogc nothrow pure;
|
||||||
|
extern (C) ushort emscripten_atomic_sub_u16(void* addr, ushort val) @nogc nothrow pure;
|
||||||
|
extern (C) uint emscripten_atomic_sub_u32(void* addr, uint val) @nogc nothrow pure;
|
||||||
|
|
||||||
|
public pure nothrow @nogc Unqual!T atomicOp(string op, T, V1)(ref shared T val, V1 mod)
|
||||||
|
{
|
||||||
|
static if (op == "+=")
|
||||||
|
{
|
||||||
|
static if (is(T == byte) || is(T == ubyte))
|
||||||
|
return cast(Unqual!T)(emscripten_atomic_add_u8(cast(void*)&val,
|
||||||
|
cast(Unqual!T) mod) + 1);
|
||||||
|
else static if (is(T == short) || is(T == ushort))
|
||||||
|
return cast(Unqual!T)(emscripten_atomic_add_u16(cast(void*)&val,
|
||||||
|
cast(Unqual!T) mod) + 1);
|
||||||
|
else static if (is(T == int) || is(T == uint))
|
||||||
|
return cast(Unqual!T)(emscripten_atomic_add_u32(cast(void*)&val,
|
||||||
|
cast(Unqual!T) mod) + 1);
|
||||||
|
else
|
||||||
|
static assert(0);
|
||||||
|
}
|
||||||
|
else static if (op == "-=")
|
||||||
|
{
|
||||||
|
static if (is(T == byte) || is(T == ubyte))
|
||||||
|
return cast(Unqual!T)(emscripten_atomic_sub_u8(cast(void*)&val,
|
||||||
|
cast(Unqual!T) mod) - 1);
|
||||||
|
else static if (is(T == short) || is(T == ushort))
|
||||||
|
return cast(Unqual!T)(emscripten_atomic_sub_u16(cast(void*)&val,
|
||||||
|
cast(Unqual!T) mod) - 1);
|
||||||
|
else static if (is(T == int) || is(T == uint))
|
||||||
|
return cast(Unqual!T)(emscripten_atomic_sub_u32(cast(void*)&val,
|
||||||
|
cast(Unqual!T) mod) - 1);
|
||||||
|
else
|
||||||
|
static assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public pure nothrow @nogc @trusted void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref T val,
|
||||||
|
V newval)
|
||||||
|
{
|
||||||
|
alias UT = Unqual!T;
|
||||||
|
static if (is(UT == bool) || is(UT == byte) || is(UT == ubyte))
|
||||||
|
emscripten_atomic_store_u8(cast(void*)&val, cast(UT) newval);
|
||||||
|
else static if (is(UT == short) || is(UT == ushort))
|
||||||
|
emscripten_atomic_store_u16(cast(void*)&val, cast(UT) newval);
|
||||||
|
else static if (is(UT == int) || is(UT == uint))
|
||||||
|
emscripten_atomic_store_u32(cast(void*)&val, cast(UT) newval);
|
||||||
|
else
|
||||||
|
static assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public pure nothrow @nogc @trusted T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(
|
||||||
|
ref const T val)
|
||||||
|
{
|
||||||
|
alias UT = Unqual!T;
|
||||||
|
static if (is(UT == bool))
|
||||||
|
return emscripten_atomic_load_u8(cast(const void*)&val) != 0;
|
||||||
|
else static if (is(UT == byte) || is(UT == ubyte))
|
||||||
|
return emscripten_atomic_load_u8(cast(const void*)&val);
|
||||||
|
else static if (is(UT == short) || is(UT == ushort))
|
||||||
|
return emscripten_atomic_load_u16(cast(const void*)&val);
|
||||||
|
else static if (is(UT == int) || is(UT == uint))
|
||||||
|
return emscripten_atomic_load_u32(cast(const void*)&val);
|
||||||
|
else
|
||||||
|
static assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public pure nothrow @nogc @trusted bool cas(MemoryOrder succ = MemoryOrder.seq,
|
||||||
|
MemoryOrder fail = MemoryOrder.seq, T, V1, V2)(T* here, V1 ifThis, V2 writeThis)
|
||||||
|
{
|
||||||
|
alias UT = Unqual!T;
|
||||||
|
static if (is(UT == bool))
|
||||||
|
return emscripten_atomic_cas_u8(cast(void*) here,
|
||||||
|
cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis;
|
||||||
|
else static if (is(UT == byte) || is(UT == ubyte))
|
||||||
|
return emscripten_atomic_cas_u8(cast(void*) here,
|
||||||
|
cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis;
|
||||||
|
else static if (is(UT == short) || is(UT == ushort))
|
||||||
|
return emscripten_atomic_cas_u16(cast(void*) here,
|
||||||
|
cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis;
|
||||||
|
else static if (is(UT == int) || is(UT == uint))
|
||||||
|
return emscripten_atomic_cas_u32(cast(void*) here,
|
||||||
|
cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis;
|
||||||
|
else
|
||||||
|
static assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
public import core.atomic;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
//////////////////// Allocator ///////////////////
|
||||||
|
//////////////////////////////////////////////////
|
||||||
T* makeVar(T)(T init)
|
T* makeVar(T)(T init)
|
||||||
{
|
{
|
||||||
T* el = cast(T*) malloc(T.sizeof);
|
T* el = cast(T*) malloc(T.sizeof);
|
||||||
|
|
@ -118,21 +240,7 @@ long useconds()
|
||||||
{
|
{
|
||||||
version (WebAssembly)
|
version (WebAssembly)
|
||||||
{
|
{
|
||||||
//import core.sys.posix.sys.time : gettimeofday, timeval;
|
|
||||||
|
|
||||||
/*timeval t;
|
|
||||||
gettimeofday(&t, null);
|
|
||||||
|
|
||||||
return t.tv_sec * 1_000_000 + t.tv_usec;*/
|
|
||||||
|
|
||||||
//time_t time;
|
|
||||||
//timespec spec;
|
|
||||||
|
|
||||||
//lock_gettime(CLOCK_REALTIME, &spec);
|
|
||||||
return cast(long)(emscripten_get_now() * 1000.0);
|
return cast(long)(emscripten_get_now() * 1000.0);
|
||||||
|
|
||||||
//time = spec.tv_sec;
|
|
||||||
//return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;
|
|
||||||
}
|
}
|
||||||
else version (Posix)
|
else version (Posix)
|
||||||
{
|
{
|
||||||
|
|
@ -144,6 +252,7 @@ long useconds()
|
||||||
}
|
}
|
||||||
else version (Windows)
|
else version (Windows)
|
||||||
{
|
{
|
||||||
|
//TODO: implement timer on windows
|
||||||
/*import core.sys.windows.windows : QueryPerformanceFrequency;
|
/*import core.sys.windows.windows : QueryPerformanceFrequency;
|
||||||
|
|
||||||
__gshared double mul = -1;
|
__gshared double mul = -1;
|
||||||
|
|
@ -241,7 +350,7 @@ version (MM_USE_POSIX_THREADS)
|
||||||
version (WebAssembly)
|
version (WebAssembly)
|
||||||
{
|
{
|
||||||
extern(C):
|
extern(C):
|
||||||
//alias uint time_t;
|
|
||||||
struct pthread_attr_t
|
struct pthread_attr_t
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
|
@ -257,19 +366,11 @@ version (MM_USE_POSIX_THREADS)
|
||||||
uint x;
|
uint x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*struct timespec
|
|
||||||
{
|
|
||||||
time_t tv_sec;
|
|
||||||
int tv_nsec;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// pthread
|
// pthread
|
||||||
int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
|
int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
|
||||||
int pthread_join(pthread_t, void**);
|
int pthread_join(pthread_t, void**);
|
||||||
void pthread_exit(void *retval);
|
void pthread_exit(void *retval);
|
||||||
|
|
||||||
// semaphore.h
|
|
||||||
//alias sem_t = void*;
|
|
||||||
struct sem_t
|
struct sem_t
|
||||||
{
|
{
|
||||||
shared int[4] __val;
|
shared int[4] __val;
|
||||||
|
|
@ -280,8 +381,6 @@ version (MM_USE_POSIX_THREADS)
|
||||||
int sem_post(sem_t*);
|
int sem_post(sem_t*);
|
||||||
int sem_destroy(sem_t*);
|
int sem_destroy(sem_t*);
|
||||||
int sem_timedwait(sem_t* sem, const timespec* abstime);
|
int sem_timedwait(sem_t* sem, const timespec* abstime);
|
||||||
//import core.sys.posix.pthread;
|
|
||||||
//import core.sys.posix.semaphore;
|
|
||||||
}
|
}
|
||||||
else version (Posix)
|
else version (Posix)
|
||||||
{
|
{
|
||||||
|
|
@ -345,7 +444,6 @@ version (MM_USE_POSIX_THREADS)
|
||||||
|
|
||||||
bool tryWait()
|
bool tryWait()
|
||||||
{
|
{
|
||||||
//return true;
|
|
||||||
int ret = sem_trywait(&mutex);
|
int ret = sem_trywait(&mutex);
|
||||||
return (ret == 0);
|
return (ret == 0);
|
||||||
}
|
}
|
||||||
|
|
@ -409,91 +507,7 @@ version (MM_USE_POSIX_THREADS)
|
||||||
}
|
}
|
||||||
else version(D_BetterC)
|
else version(D_BetterC)
|
||||||
{
|
{
|
||||||
version(Posix)
|
version(Windows)
|
||||||
{
|
|
||||||
import core.sys.posix.pthread;
|
|
||||||
import core.sys.posix.semaphore;
|
|
||||||
|
|
||||||
struct Semaphore
|
|
||||||
{
|
|
||||||
sem_t mutex;
|
|
||||||
|
|
||||||
void initialize()
|
|
||||||
{
|
|
||||||
sem_init(&mutex, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait()
|
|
||||||
{
|
|
||||||
int ret = sem_wait(&mutex);
|
|
||||||
assert(ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tryWait()
|
|
||||||
{
|
|
||||||
//return true;
|
|
||||||
int ret = sem_trywait(&mutex);
|
|
||||||
return (ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool timedWait(int usecs)
|
|
||||||
{
|
|
||||||
timespec tv;
|
|
||||||
// if there is no such a function look at it: https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
|
|
||||||
clock_gettime(CLOCK_REALTIME, &tv);
|
|
||||||
tv.tv_sec += usecs / 1_000_000;
|
|
||||||
tv.tv_nsec += (usecs % 1_000_000) * 1_000;
|
|
||||||
|
|
||||||
int ret = sem_timedwait(&mutex, &tv);
|
|
||||||
return (ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void post()
|
|
||||||
{
|
|
||||||
int ret = sem_post(&mutex);
|
|
||||||
assert(ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
sem_destroy(&mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extern (C) void* threadRunFunc(void* threadVoid)
|
|
||||||
{
|
|
||||||
Thread* th = cast(Thread*) threadVoid;
|
|
||||||
|
|
||||||
th.threadStart();
|
|
||||||
|
|
||||||
pthread_exit(null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Thread
|
|
||||||
{
|
|
||||||
alias DG = void delegate();
|
|
||||||
|
|
||||||
DG threadStart;
|
|
||||||
pthread_t handle;
|
|
||||||
|
|
||||||
void start(DG dg)
|
|
||||||
{
|
|
||||||
threadStart = dg;
|
|
||||||
int ok = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this);
|
|
||||||
if(!ok)handle = pthread_t();
|
|
||||||
//assert(ok == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void join()
|
|
||||||
{
|
|
||||||
pthread_join(handle, null);
|
|
||||||
handle = handle.init;
|
|
||||||
threadStart = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else version(Windows)
|
|
||||||
{
|
{
|
||||||
import core.stdc.stdint : uintptr_t;
|
import core.stdc.stdint : uintptr_t;
|
||||||
import core.sys.windows.windows;
|
import core.sys.windows.windows;
|
||||||
|
|
@ -549,15 +563,13 @@ else version(D_BetterC)
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
assert(0);//throw new SyncError( "Unable to wait for semaphore" );
|
assert(0, "Unable to wait for semaphore" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void post()
|
void post()
|
||||||
{
|
{
|
||||||
assert(ReleaseSemaphore( handle, 1, null ));
|
assert(ReleaseSemaphore( handle, 1, null ));
|
||||||
//if ( !ReleaseSemaphore( m_hndl, 1, null ) )
|
|
||||||
//throw new SyncError( "Unable to notify semaphore" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy()
|
void destroy()
|
||||||
|
|
@ -573,7 +585,6 @@ else version(D_BetterC)
|
||||||
|
|
||||||
th.threadStart();
|
th.threadStart();
|
||||||
|
|
||||||
//(null);
|
|
||||||
ExitThread(0);
|
ExitThread(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -589,21 +600,22 @@ else version(D_BetterC)
|
||||||
{
|
{
|
||||||
threadStart = dg;
|
threadStart = dg;
|
||||||
handle = cast(HANDLE) _beginthreadex( null, 0, &threadRunFunc, cast(void*)&this, 0, null );
|
handle = cast(HANDLE) _beginthreadex( null, 0, &threadRunFunc, cast(void*)&this, 0, null );
|
||||||
//int ok = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this);
|
|
||||||
//assert(handle != null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void join()
|
void join()
|
||||||
{
|
{
|
||||||
if ( WaitForSingleObject( handle, INFINITE ) == WAIT_OBJECT_0 )assert(0);
|
if ( WaitForSingleObject( handle, INFINITE ) == WAIT_OBJECT_0 )assert(0);
|
||||||
CloseHandle( handle );
|
CloseHandle( handle );
|
||||||
//pthread_join(handle, null);
|
|
||||||
handle = handle.init;
|
handle = handle.init;
|
||||||
threadStart = null;
|
threadStart = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static assert(0, "Platform is unsupported in betterC mode!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -672,7 +684,7 @@ else
|
||||||
///////////////// ThreadPool /////////////////
|
///////////////// ThreadPool /////////////////
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
private enum gMaxThreadsNum = 32;
|
private enum gMaxThreadsNum = 64;
|
||||||
|
|
||||||
alias JobDelegate = void delegate(ThreadData*, JobData*);
|
alias JobDelegate = void delegate(ThreadData*, JobData*);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ struct Launcher
|
||||||
ImGuiContext* context;
|
ImGuiContext* context;
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_GLContext gl_context;
|
SDL_GLContext gl_context;
|
||||||
EntityManager* manager;
|
|
||||||
/*bool function() loop;
|
/*bool function() loop;
|
||||||
void function() end;
|
void function() end;
|
||||||
void function(SDL_Event*) event;*/
|
void function(SDL_Event*) event;*/
|
||||||
|
|
@ -126,19 +125,19 @@ struct Launcher
|
||||||
gui_manager.clear();
|
gui_manager.clear();
|
||||||
//launcher.ent
|
//launcher.ent
|
||||||
|
|
||||||
manager.begin();
|
gEntityManager.begin();
|
||||||
manager.update("clean");
|
gEntityManager.update("clean");
|
||||||
manager.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
if(this.demo.deinitialize)this.demo.deinitialize();
|
if(this.demo.deinitialize)this.demo.deinitialize();
|
||||||
|
|
||||||
foreach(ref system; manager.systems)
|
foreach(ref system; gEntityManager.systems)
|
||||||
{
|
{
|
||||||
if(system.id != becsID!CountSystem && system.id != becsID!CleanSystem)system.disable();
|
if(system.id != becsID!CountSystem && system.id != becsID!CleanSystem)system.disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*launcher.manager.getSystem(becsID!CountSystem).enable();
|
/*gEntityManager.getSystem(becsID!CountSystem).enable();
|
||||||
launcher.manager.getSystem(becsID!CleanSystem).enable();//*/
|
gEntityManager.getSystem(becsID!CleanSystem).enable();//*/
|
||||||
|
|
||||||
if(callbacks.register)callbacks.register();
|
if(callbacks.register)callbacks.register();
|
||||||
if(callbacks.initialize)callbacks.initialize();
|
if(callbacks.initialize)callbacks.initialize();
|
||||||
|
|
@ -192,7 +191,7 @@ struct Launcher
|
||||||
{
|
{
|
||||||
vec2 rel_vec = data.location[i] - position;
|
vec2 rel_vec = data.location[i] - position;
|
||||||
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
if(length < size2)gEM.removeEntity(data.entity[i].id);
|
if(length < size2)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,7 +202,7 @@ struct Launcher
|
||||||
{
|
{
|
||||||
vec2 rel_vec = data.location[i] - position;
|
vec2 rel_vec = data.location[i] - position;
|
||||||
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
if(length < size2)gEM.addComponents(data.entity[i].id, add_comps);
|
if(length < size2)gEntityManager.addComponents(data.entity[i].id, add_comps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,8 +215,8 @@ struct Launcher
|
||||||
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
if(length < size2)
|
if(length < size2)
|
||||||
{
|
{
|
||||||
gEM.removeComponents(data.entity[i].id, rem_comps);
|
gEntityManager.removeComponents(data.entity[i].id, rem_comps);
|
||||||
gEM.addComponents(data.entity[i].id, add_comps);
|
gEntityManager.addComponents(data.entity[i].id, add_comps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +228,7 @@ struct Launcher
|
||||||
{
|
{
|
||||||
vec2 rel_vec = data.location[i] - position;
|
vec2 rel_vec = data.location[i] - position;
|
||||||
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
if(length < size2)gEM.removeComponents(data.entity[i].id, rem_comps);
|
if(length < size2)gEntityManager.removeComponents(data.entity[i].id, rem_comps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,11 +270,11 @@ struct Launcher
|
||||||
//else if(position.y > 299)position.y = 299;
|
//else if(position.y > 299)position.y = 299;
|
||||||
*location = position;
|
*location = position;
|
||||||
}
|
}
|
||||||
manager.addEntity(tmpl);
|
gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
manager.callEntitiesFunction!IteratorSystem(&iterator.removeEntity);
|
gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.removeEntity);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Tool.component_manipulator:
|
case Tool.component_manipulator:
|
||||||
|
|
@ -289,21 +288,21 @@ struct Launcher
|
||||||
{
|
{
|
||||||
ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id];
|
ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id];
|
||||||
iterator.rem_comps = rcomps;
|
iterator.rem_comps = rcomps;
|
||||||
manager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent);
|
gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent);
|
||||||
}
|
}
|
||||||
else manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent);
|
else gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.addComponent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ushort[1] comps = [gui_manager.getSelectedComponent().component_id];
|
ushort[1] comps = [gui_manager.getSelectedComponent().component_id];
|
||||||
iterator.rem_comps = comps;
|
iterator.rem_comps = comps;
|
||||||
manager.callEntitiesFunction!IteratorSystem(&iterator.removeComponent);
|
gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.removeComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Tool.selector:
|
case Tool.selector:
|
||||||
iterator.distance = size2;
|
iterator.distance = size2;
|
||||||
manager.callEntitiesFunction!IteratorSystem(&iterator.selectEntity);
|
gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.selectEntity);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -369,7 +368,7 @@ struct CleanSystem
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
launcher.manager.removeEntity(data.entities[i].id);
|
gEntityManager.removeEntity(data.entities[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -878,9 +877,9 @@ void mainLoop(void* arg)
|
||||||
//igEndChildFrame();
|
//igEndChildFrame();
|
||||||
if(igButton("Clear",ImVec2(-1,0)))
|
if(igButton("Clear",ImVec2(-1,0)))
|
||||||
{
|
{
|
||||||
launcher.manager.begin();
|
gEntityManager.begin();
|
||||||
launcher.manager.update("clean");
|
gEntityManager.update("clean");
|
||||||
launcher.manager.end();
|
gEntityManager.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
igEnd();
|
igEnd();
|
||||||
|
|
@ -1016,10 +1015,11 @@ void mainLoop(void* arg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
launcher.manager.begin();
|
gEntityManager.begin();
|
||||||
import game_core.rendering;
|
import game_core.rendering;
|
||||||
launcher.manager.callEntitiesFunction!DrawSystem(&(launcher.manager.getSystem!DrawSystem).onUpdate);
|
DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem;
|
||||||
launcher.manager.end();
|
gEntityManager.callEntitiesFunction!DrawSystem(&draw_system.onUpdate);
|
||||||
|
gEntityManager.end();
|
||||||
}
|
}
|
||||||
launcher.job_updater.pool.tryWaitCount = 0;
|
launcher.job_updater.pool.tryWaitCount = 0;
|
||||||
|
|
||||||
|
|
@ -1104,8 +1104,8 @@ void quit()
|
||||||
|
|
||||||
if(launcher.demo.deinitialize)launcher.demo.deinitialize();
|
if(launcher.demo.deinitialize)launcher.demo.deinitialize();
|
||||||
|
|
||||||
launcher.manager.destroy();
|
gEntityManager.destroy();
|
||||||
launcher.manager = null;
|
gEntityManager = null;
|
||||||
|
|
||||||
TexCoordsManager.destroy();
|
TexCoordsManager.destroy();
|
||||||
|
|
||||||
|
|
@ -1231,23 +1231,23 @@ int app_main(int argc, char** argv)
|
||||||
//launcher.job_updater.onCreate();
|
//launcher.job_updater.onCreate();
|
||||||
|
|
||||||
EntityManager.initialize(32, 1<<16);
|
EntityManager.initialize(32, 1<<16);
|
||||||
launcher.manager = EntityManager.instance;
|
//gEntityManager = gEntityManager;
|
||||||
|
|
||||||
//launcher.manager.m_thread_id_func = &launcher.job_updater.getThreadID;
|
//gEntityManager.m_thread_id_func = &launcher.job_updater.getThreadID;
|
||||||
//launcher.manager.setJobDispachFunc(&launcher.job_updater.dispatch);
|
//gEntityManager.setJobDispachFunc(&launcher.job_updater.dispatch);
|
||||||
launcher.manager.setMultithreadingCallbacks(&launcher.job_updater.dispatch, &launcher.job_updater.getThreadID);
|
gEntityManager.setMultithreadingCallbacks(&launcher.job_updater.dispatch, &launcher.job_updater.getThreadID);
|
||||||
|
|
||||||
launcher.manager.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
launcher.manager.registerPass("clean");
|
gEntityManager.registerPass("clean");
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
gEntityManager.registerComponent!CLocation;
|
||||||
|
|
||||||
launcher.manager.registerSystem!CountSystem(10000);
|
gEntityManager.registerSystem!CountSystem(10000);
|
||||||
launcher.manager.registerSystem!CleanSystem(0,"clean");
|
gEntityManager.registerSystem!CleanSystem(0,"clean");
|
||||||
launcher.manager.registerSystem!IteratorSystem(0,"clean");
|
gEntityManager.registerSystem!IteratorSystem(0,"clean");
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
gEntityManager.endRegister();
|
||||||
|
|
||||||
loadGFX();
|
loadGFX();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ struct CBall
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
ubyte radius;
|
//ubyte radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CHitPoints
|
struct CHitPoints
|
||||||
|
|
@ -193,7 +193,7 @@ struct BallCollisionSystem
|
||||||
bool test(EntityID id)
|
bool test(EntityID id)
|
||||||
{
|
{
|
||||||
if(id == data.entity[i].id)return true;
|
if(id == data.entity[i].id)return true;
|
||||||
Entity* entity = launcher.manager.getEntity(id);
|
Entity* entity = gEntityManager.getEntity(id);
|
||||||
if(entity)
|
if(entity)
|
||||||
{
|
{
|
||||||
CLocation* location = entity.getComponent!CLocation;
|
CLocation* location = entity.getComponent!CLocation;
|
||||||
|
|
@ -224,7 +224,7 @@ struct BallCollisionSystem
|
||||||
{
|
{
|
||||||
vector = vector / sqrtf(pow_dist);
|
vector = vector / sqrtf(pow_dist);
|
||||||
data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i]));
|
data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i]));
|
||||||
launcher.manager.sendEvent(id,EDamage(1));
|
gEntityManager.sendEvent(id,EDamage(1));
|
||||||
return cast(bool)(hits--);
|
return cast(bool)(hits--);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -243,35 +243,20 @@ struct BallCollisionSystem
|
||||||
|
|
||||||
bool onBegin()
|
bool onBegin()
|
||||||
{
|
{
|
||||||
//grid = launcher.manager.getSystem!ShootGridManager().grid;
|
tree = gEntityManager.getSystem!BVHBuilder().tree;
|
||||||
tree = launcher.manager.getSystem!BVHBuilder().tree;
|
static_tree = gEntityManager.getSystem!StaticBVHBuilder().tree;
|
||||||
static_tree = launcher.manager.getSystem!StaticBVHBuilder().tree;
|
|
||||||
//if(grid is null)return false;
|
|
||||||
if(tree is null || static_tree is null)return false;
|
if(tree is null || static_tree is null)return false;
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
// State state;
|
|
||||||
// state.data = data;
|
|
||||||
// EntityID id;
|
|
||||||
// foreach(i; 0..data.length)
|
|
||||||
// {
|
|
||||||
// state.i = i;
|
|
||||||
// float radius = data.scale[i].x;
|
|
||||||
// if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max))
|
|
||||||
// {
|
|
||||||
// state.test(id);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
State state;
|
State state;
|
||||||
state.data = data;
|
state.data = data;
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
state.i = i;
|
state.i = i;
|
||||||
state.hits = 1;
|
state.hits = 1;
|
||||||
//float radius = data.scale[i].x;
|
|
||||||
AABB bounding = AABB(data.location[i]-data.scale[i], data.location[i]+data.scale[i]);
|
AABB bounding = AABB(data.location[i]-data.scale[i], data.location[i]+data.scale[i]);
|
||||||
tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
|
tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
|
||||||
static_tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
|
static_tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
|
||||||
|
|
@ -298,7 +283,7 @@ struct DamageSystem
|
||||||
EntityMeta meta = entity.getMeta();
|
EntityMeta meta = entity.getMeta();
|
||||||
CHitPoints* hp = meta.getComponent!CHitPoints;
|
CHitPoints* hp = meta.getComponent!CHitPoints;
|
||||||
hp.value -= event.damage;
|
hp.value -= event.damage;
|
||||||
if(hp.value < 0)launcher.manager.removeEntity(entity.id);
|
if(hp.value < 0)gEntityManager.removeEntity(entity.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -328,46 +313,46 @@ void brickBreakerRegister()
|
||||||
demo.texture.create();
|
demo.texture.create();
|
||||||
demo.texture.load("assets/textures/atlas.png");
|
demo.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
launcher.manager.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
registerRenderingModule(launcher.manager);
|
registerRenderingModule(gEntityManager);
|
||||||
registerCollisionModule(launcher.manager);
|
registerCollisionModule(gEntityManager);
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
gEntityManager.registerComponent!CLocation;
|
||||||
launcher.manager.registerComponent!CRotation;
|
gEntityManager.registerComponent!CRotation;
|
||||||
launcher.manager.registerComponent!CScale;
|
gEntityManager.registerComponent!CScale;
|
||||||
launcher.manager.registerComponent!CTexCoords;
|
gEntityManager.registerComponent!CTexCoords;
|
||||||
launcher.manager.registerComponent!CTexCoordsIndex;
|
gEntityManager.registerComponent!CTexCoordsIndex;
|
||||||
launcher.manager.registerComponent!CVelocity;
|
gEntityManager.registerComponent!CVelocity;
|
||||||
launcher.manager.registerComponent!CInput;
|
gEntityManager.registerComponent!CInput;
|
||||||
launcher.manager.registerComponent!CPaddle;
|
gEntityManager.registerComponent!CPaddle;
|
||||||
launcher.manager.registerComponent!CDamping;
|
gEntityManager.registerComponent!CDamping;
|
||||||
launcher.manager.registerComponent!CVelocityFactor;
|
gEntityManager.registerComponent!CVelocityFactor;
|
||||||
launcher.manager.registerComponent!CBall;
|
gEntityManager.registerComponent!CBall;
|
||||||
launcher.manager.registerComponent!CHitPoints;
|
gEntityManager.registerComponent!CHitPoints;
|
||||||
|
|
||||||
launcher.manager.registerEvent!EDamage;
|
gEntityManager.registerEvent!EDamage;
|
||||||
|
|
||||||
launcher.manager.registerSystem!MoveSystem(-100);
|
gEntityManager.registerSystem!MoveSystem(-100);
|
||||||
launcher.manager.registerSystem!EdgeCollisionSystem(-99);
|
gEntityManager.registerSystem!EdgeCollisionSystem(-99);
|
||||||
launcher.manager.registerSystem!BallCollisionSystem(-79);
|
gEntityManager.registerSystem!BallCollisionSystem(-79);
|
||||||
launcher.manager.registerSystem!InputMovementSystem(-120);
|
gEntityManager.registerSystem!InputMovementSystem(-120);
|
||||||
launcher.manager.registerSystem!DampingSystem(-120);
|
gEntityManager.registerSystem!DampingSystem(-120);
|
||||||
launcher.manager.registerSystem!DamageSystem(-120);
|
gEntityManager.registerSystem!DamageSystem(-120);
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
gEntityManager.endRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
void brickBreakerStart()
|
void brickBreakerStart()
|
||||||
{
|
{
|
||||||
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem;
|
||||||
draw_system.default_data.color = 0x80808080;
|
draw_system.default_data.color = 0x80808080;
|
||||||
draw_system.default_data.texture = demo.texture;
|
draw_system.default_data.texture = demo.texture;
|
||||||
draw_system.default_data.size = vec2(16,16);
|
draw_system.default_data.size = vec2(16,16);
|
||||||
draw_system.default_data.coords = vec4(246,64,2,2)*px;
|
draw_system.default_data.coords = vec4(246,64,2,2)*px;
|
||||||
draw_system.default_data.material_id = 0;
|
draw_system.default_data.material_id = 0;
|
||||||
|
|
||||||
EntityTemplate* brick_tmpl = launcher.manager.allocateTemplate(
|
EntityTemplate* brick_tmpl = gEntityManager.allocateTemplate(
|
||||||
[becsID!CLocation, becsID!CScale, becsID!CColor,
|
[becsID!CLocation, becsID!CScale, becsID!CColor,
|
||||||
becsID!CTexCoordsIndex, becsID!CBVH, becsID!CHitPoints,
|
becsID!CTexCoordsIndex, becsID!CBVH, becsID!CHitPoints,
|
||||||
becsID!CAABB, becsID!CStatic].staticArray
|
becsID!CAABB, becsID!CStatic].staticArray
|
||||||
|
|
@ -378,11 +363,11 @@ void brickBreakerStart()
|
||||||
brick_tmpl.getComponent!CHitPoints().value = 2;
|
brick_tmpl.getComponent!CHitPoints().value = 2;
|
||||||
//brick_tmpl.getComponent!CAABB().bounding = AABB(vec2(),vec2());
|
//brick_tmpl.getComponent!CAABB().bounding = AABB(vec2(),vec2());
|
||||||
|
|
||||||
EntityTemplate* big_brick_tmpl = launcher.manager.allocateTemplate(brick_tmpl);
|
EntityTemplate* big_brick_tmpl = gEntityManager.allocateTemplate(brick_tmpl);
|
||||||
big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px);
|
big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px);
|
||||||
big_brick_tmpl.getComponent!CScale().value = vec2(16,16);
|
big_brick_tmpl.getComponent!CScale().value = vec2(16,16);
|
||||||
|
|
||||||
EntityTemplate* paddle_tmpl = launcher.manager.allocateTemplate(
|
EntityTemplate* paddle_tmpl = gEntityManager.allocateTemplate(
|
||||||
[becsID!CLocation, becsID!CScale, becsID!CInput,
|
[becsID!CLocation, becsID!CScale, becsID!CInput,
|
||||||
becsID!CTexCoordsIndex, becsID!CPaddle, becsID!CVelocity,
|
becsID!CTexCoordsIndex, becsID!CPaddle, becsID!CVelocity,
|
||||||
becsID!CDamping, becsID!CVelocityFactor, becsID!CBVH,
|
becsID!CDamping, becsID!CVelocityFactor, becsID!CBVH,
|
||||||
|
|
@ -393,7 +378,7 @@ void brickBreakerStart()
|
||||||
paddle_tmpl.getComponent!CDamping().value = 14;
|
paddle_tmpl.getComponent!CDamping().value = 14;
|
||||||
paddle_tmpl.getComponent!CVelocityFactor().value = vec2(1,0);
|
paddle_tmpl.getComponent!CVelocityFactor().value = vec2(1,0);
|
||||||
|
|
||||||
EntityTemplate* ball_tmpl = launcher.manager.allocateTemplate(
|
EntityTemplate* ball_tmpl = gEntityManager.allocateTemplate(
|
||||||
[becsID!CLocation, becsID!CScale, //becsID!CDamping,
|
[becsID!CLocation, becsID!CScale, //becsID!CDamping,
|
||||||
becsID!CTexCoordsIndex, becsID!CBall, becsID!CVelocity].staticArray
|
becsID!CTexCoordsIndex, becsID!CBall, becsID!CVelocity].staticArray
|
||||||
);
|
);
|
||||||
|
|
@ -409,12 +394,15 @@ void brickBreakerStart()
|
||||||
launcher.gui_manager.addComponent(CTexCoords(), "Tex Coords");
|
launcher.gui_manager.addComponent(CTexCoords(), "Tex Coords");
|
||||||
launcher.gui_manager.addComponent(CTexCoordsIndex(), "Tex Coords Index");
|
launcher.gui_manager.addComponent(CTexCoordsIndex(), "Tex Coords Index");
|
||||||
launcher.gui_manager.addComponent(CVelocity(), "Velocity");
|
launcher.gui_manager.addComponent(CVelocity(), "Velocity");
|
||||||
launcher.gui_manager.addComponent(CInput(), "Velocity");
|
launcher.gui_manager.addComponent(CInput(), "Input");
|
||||||
|
launcher.gui_manager.addComponent(CPaddle(), "Paddle");
|
||||||
launcher.gui_manager.addComponent(CDamping(), "Damping");
|
launcher.gui_manager.addComponent(CDamping(), "Damping");
|
||||||
launcher.gui_manager.addComponent(CBall(), "Ball");
|
launcher.gui_manager.addComponent(CBall(), "Ball");
|
||||||
launcher.gui_manager.addComponent(CBVH(), "BVH");
|
launcher.gui_manager.addComponent(CBVH(), "BVH");
|
||||||
launcher.gui_manager.addComponent(CAABB(), "AABB");
|
launcher.gui_manager.addComponent(CAABB(), "AABB");
|
||||||
launcher.gui_manager.addComponent(CStatic(), "Static Flag");
|
launcher.gui_manager.addComponent(CStatic(), "Static Flag");
|
||||||
|
launcher.gui_manager.addComponent(CVelocityFactor(), "Velocity Factor");
|
||||||
|
launcher.gui_manager.addComponent(CHitPoints(), "Hit Points");
|
||||||
|
|
||||||
launcher.gui_manager.addSystem(becsID!MoveSystem, "Move System");
|
launcher.gui_manager.addSystem(becsID!MoveSystem, "Move System");
|
||||||
launcher.gui_manager.addSystem(becsID!EdgeCollisionSystem, "Edge Collision System");
|
launcher.gui_manager.addSystem(becsID!EdgeCollisionSystem, "Edge Collision System");
|
||||||
|
|
@ -446,12 +434,12 @@ void brickBreakerStart()
|
||||||
}
|
}
|
||||||
foreach (j; 0..20)
|
foreach (j; 0..20)
|
||||||
{
|
{
|
||||||
launcher.manager.addEntity(brick_tmpl,[CLocation(vec2(j*18,300-i*10)).ref_, color.ref_].staticArray);
|
gEntityManager.addEntity(brick_tmpl,[CLocation(vec2(j*18,300-i*10)).ref_, color.ref_].staticArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher.manager.addEntity(paddle_tmpl,[CLocation(vec2(190,20)).ref_].staticArray);
|
gEntityManager.addEntity(paddle_tmpl,[CLocation(vec2(190,20)).ref_].staticArray);
|
||||||
launcher.manager.addEntity(ball_tmpl,[CLocation(vec2(190,40)).ref_].staticArray);
|
gEntityManager.addEntity(ball_tmpl,[CLocation(vec2(190,40)).ref_].staticArray);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -470,18 +458,18 @@ bool brickBreakerLoop()
|
||||||
{
|
{
|
||||||
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
||||||
|
|
||||||
launcher.manager.begin();
|
gEntityManager.begin();
|
||||||
if(launcher.multithreading)
|
if(launcher.multithreading)
|
||||||
{
|
{
|
||||||
launcher.job_updater.begin();
|
launcher.job_updater.begin();
|
||||||
launcher.manager.updateMT();
|
gEntityManager.updateMT();
|
||||||
launcher.job_updater.call();
|
launcher.job_updater.call();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
launcher.manager.update();
|
gEntityManager.update();
|
||||||
}
|
}
|
||||||
launcher.manager.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,74 +116,6 @@ struct CParticleLife
|
||||||
/*#######################################################################################################################
|
/*#######################################################################################################################
|
||||||
------------------------------------------------ Systems ------------------------------------------------------------------
|
------------------------------------------------ Systems ------------------------------------------------------------------
|
||||||
#######################################################################################################################*/
|
#######################################################################################################################*/
|
||||||
/*
|
|
||||||
struct DrawSystem
|
|
||||||
{
|
|
||||||
mixin ECS.System!32;
|
|
||||||
|
|
||||||
struct EntitiesData
|
|
||||||
{
|
|
||||||
uint length;
|
|
||||||
//uint thread_id;
|
|
||||||
uint job_id;
|
|
||||||
//@readonly CTexCoords[] coords;
|
|
||||||
@readonly CLocation[] locations;
|
|
||||||
|
|
||||||
@optional @readonly CColor[] color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
|
||||||
{
|
|
||||||
if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached
|
|
||||||
import ecs_utils.gfx.renderer;
|
|
||||||
Renderer.DrawData draw_data;
|
|
||||||
draw_data.size = vec2(2,2);
|
|
||||||
draw_data.coords = vec4(246,64,2,2)*px;
|
|
||||||
draw_data.color = 0x80808080;
|
|
||||||
draw_data.material_id = 2;
|
|
||||||
draw_data.thread_id = data.job_id;
|
|
||||||
draw_data.texture = particles_demo.texture;
|
|
||||||
|
|
||||||
if(!data.color)
|
|
||||||
{
|
|
||||||
foreach(i; 0..data.length)
|
|
||||||
{
|
|
||||||
draw_data.position = data.locations[i];
|
|
||||||
launcher.renderer.draw(draw_data);//particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, 0x80808080, 0, 2, 0, data.job_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach(i; 0..data.length)
|
|
||||||
{
|
|
||||||
draw_data.position = data.locations[i];
|
|
||||||
draw_data.color = data.color[i].value;
|
|
||||||
launcher.renderer.draw(draw_data);//particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, data.color[i].value, 0, 2, 0, data.job_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// struct MoveSystem
|
|
||||||
// {
|
|
||||||
// mixin ECS.System!64;
|
|
||||||
|
|
||||||
// struct EntitiesData
|
|
||||||
// {
|
|
||||||
// uint length;
|
|
||||||
// CLocation[] locations;
|
|
||||||
// @readonly CVelocity[] velocity;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void onUpdate(EntitiesData data)
|
|
||||||
// {
|
|
||||||
// foreach(i; 0..data.length)
|
|
||||||
// {
|
|
||||||
// data.locations[i] += data.velocity[i] * launcher.deltaTime;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
struct MouseAttractSystem
|
struct MouseAttractSystem
|
||||||
{
|
{
|
||||||
|
|
@ -296,7 +228,7 @@ struct AttractSystem
|
||||||
{
|
{
|
||||||
Updater updater;
|
Updater updater;
|
||||||
updater.data = data;
|
updater.data = data;
|
||||||
launcher.manager.callEntitiesFunction!AttractorIterator(&updater.onUpdate);
|
gEntityManager.callEntitiesFunction!AttractorIterator(&updater.onUpdate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,47 +271,14 @@ struct PlayAreaSystem
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
if(data.locations[i].x > 440)launcher.manager.removeEntity(data.entity[i].id);
|
if(data.locations[i].x > 440)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
else if(data.locations[i].x < -40)launcher.manager.removeEntity(data.entity[i].id);
|
else if(data.locations[i].x < -40)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
if(data.locations[i].y > 340)launcher.manager.removeEntity(data.entity[i].id);
|
if(data.locations[i].y > 340)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
else if(data.locations[i].y < -40)launcher.manager.removeEntity(data.entity[i].id);
|
else if(data.locations[i].y < -40)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct DampingSystem
|
|
||||||
// {
|
|
||||||
// mixin ECS.System!32;
|
|
||||||
|
|
||||||
// struct EntitiesData
|
|
||||||
// {
|
|
||||||
// uint length;
|
|
||||||
// const (Entity)[] entity;
|
|
||||||
// @readonly CDamping[] damping;
|
|
||||||
// CVelocity[] velocity;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// float[10] damp = 0;
|
|
||||||
|
|
||||||
// bool onBegin()
|
|
||||||
// {
|
|
||||||
// foreach(i;0..10)
|
|
||||||
// {
|
|
||||||
// damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.deltaTime*0.1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void onUpdate(EntitiesData data)
|
|
||||||
// {
|
|
||||||
// foreach(i; 0..data.length)
|
|
||||||
// {
|
|
||||||
// data.velocity[i] = data.velocity[i] * damp[data.damping[i]];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
struct ParticleLifeSystem
|
struct ParticleLifeSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!32;
|
mixin ECS.System!32;
|
||||||
|
|
@ -404,7 +303,7 @@ struct ParticleLifeSystem
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
data.life[i] -= delta_time;
|
data.life[i] -= delta_time;
|
||||||
if(data.life[i] < 0)launcher.manager.removeEntity(data.entity[i].id);
|
if(data.life[i] < 0)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -452,45 +351,45 @@ void particlesRegister()
|
||||||
particles_demo.texture.create();
|
particles_demo.texture.create();
|
||||||
particles_demo.texture.load("assets/textures/atlas.png");
|
particles_demo.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
launcher.manager.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
registerRenderingModule(launcher.manager);
|
registerRenderingModule(gEntityManager);
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
gEntityManager.registerComponent!CLocation;
|
||||||
//launcher.manager.registerComponent!CTexCoords;
|
//gEntityManager.registerComponent!CTexCoords;
|
||||||
launcher.manager.registerComponent!CColor;
|
gEntityManager.registerComponent!CColor;
|
||||||
launcher.manager.registerComponent!CVelocity;
|
gEntityManager.registerComponent!CVelocity;
|
||||||
launcher.manager.registerComponent!CScale;
|
gEntityManager.registerComponent!CScale;
|
||||||
launcher.manager.registerComponent!CTexCoords;
|
gEntityManager.registerComponent!CTexCoords;
|
||||||
launcher.manager.registerComponent!CTexCoordsIndex;
|
gEntityManager.registerComponent!CTexCoordsIndex;
|
||||||
launcher.manager.registerComponent!CRotation;
|
gEntityManager.registerComponent!CRotation;
|
||||||
launcher.manager.registerComponent!CDepth;
|
gEntityManager.registerComponent!CDepth;
|
||||||
launcher.manager.registerComponent!CAttractor;
|
gEntityManager.registerComponent!CAttractor;
|
||||||
launcher.manager.registerComponent!CDamping;
|
gEntityManager.registerComponent!CDamping;
|
||||||
launcher.manager.registerComponent!CGravity;
|
gEntityManager.registerComponent!CGravity;
|
||||||
launcher.manager.registerComponent!CVortex;
|
gEntityManager.registerComponent!CVortex;
|
||||||
launcher.manager.registerComponent!CParticleLife;
|
gEntityManager.registerComponent!CParticleLife;
|
||||||
launcher.manager.registerComponent!CForceRange;
|
gEntityManager.registerComponent!CForceRange;
|
||||||
launcher.manager.registerComponent!CMaterialIndex;
|
gEntityManager.registerComponent!CMaterialIndex;
|
||||||
launcher.manager.registerComponent!CVelocityFactor;
|
gEntityManager.registerComponent!CVelocityFactor;
|
||||||
|
|
||||||
launcher.manager.registerSystem!MoveSystem(0);
|
gEntityManager.registerSystem!MoveSystem(0);
|
||||||
launcher.manager.registerSystem!DrawSystem(100);
|
gEntityManager.registerSystem!DrawSystem(100);
|
||||||
launcher.manager.registerSystem!PlayAreaSystem(102);
|
gEntityManager.registerSystem!PlayAreaSystem(102);
|
||||||
launcher.manager.registerSystem!AttractSystem(-1);
|
gEntityManager.registerSystem!AttractSystem(-1);
|
||||||
launcher.manager.registerSystem!MouseAttractSystem(1);
|
gEntityManager.registerSystem!MouseAttractSystem(1);
|
||||||
launcher.manager.registerSystem!DampingSystem(101);
|
gEntityManager.registerSystem!DampingSystem(101);
|
||||||
launcher.manager.registerSystem!ParticleLifeSystem(-10);
|
gEntityManager.registerSystem!ParticleLifeSystem(-10);
|
||||||
launcher.manager.registerSystem!GravitySystem(-2);
|
gEntityManager.registerSystem!GravitySystem(-2);
|
||||||
|
|
||||||
launcher.manager.registerSystem!AttractorIterator(-1);
|
gEntityManager.registerSystem!AttractorIterator(-1);
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
gEntityManager.endRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
void particlesStart()
|
void particlesStart()
|
||||||
{
|
{
|
||||||
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem;
|
||||||
draw_system.default_data.size = vec2(2,2);
|
draw_system.default_data.size = vec2(2,2);
|
||||||
draw_system.default_data.coords = vec4(246,64,2,2)*px;
|
draw_system.default_data.coords = vec4(246,64,2,2)*px;
|
||||||
draw_system.default_data.material_id = 2;
|
draw_system.default_data.material_id = 2;
|
||||||
|
|
@ -503,12 +402,20 @@ void particlesStart()
|
||||||
launcher.gui_manager.addSystem(becsID!MouseAttractSystem,"Mouse Attract System");
|
launcher.gui_manager.addSystem(becsID!MouseAttractSystem,"Mouse Attract System");
|
||||||
launcher.gui_manager.addSystem(becsID!DampingSystem,"Damping System");
|
launcher.gui_manager.addSystem(becsID!DampingSystem,"Damping System");
|
||||||
launcher.gui_manager.addSystem(becsID!ParticleLifeSystem,"Particle Life System");
|
launcher.gui_manager.addSystem(becsID!ParticleLifeSystem,"Particle Life System");
|
||||||
|
launcher.gui_manager.addSystem(becsID!GravitySystem,"Gravity System");
|
||||||
|
|
||||||
// launcher.gui_manager.addComponent(CColor(),"Color (white)");
|
// launcher.gui_manager.addComponent(CColor(),"Color (white)");
|
||||||
// launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)");
|
// launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)");
|
||||||
// launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)");
|
// launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)");
|
||||||
// launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)");
|
// launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)");
|
||||||
launcher.gui_manager.addComponent(CColor(0xFF101540),"Color");
|
launcher.gui_manager.addComponent(CLocation(),"Location");
|
||||||
|
launcher.gui_manager.addComponent(CScale(),"Scale");
|
||||||
|
launcher.gui_manager.addComponent(CTexCoords(),"Texture Coords");
|
||||||
|
launcher.gui_manager.addComponent(CTexCoordsIndex(),"Texture Coords Index");
|
||||||
|
launcher.gui_manager.addComponent(CRotation(),"Rotation");
|
||||||
|
launcher.gui_manager.addComponent(CDepth(),"Depth");
|
||||||
|
launcher.gui_manager.addComponent(CMaterialIndex(),"Material ID");
|
||||||
|
launcher.gui_manager.addComponent(CVelocityFactor(),"Velocity Factor");
|
||||||
launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor");
|
launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor");
|
||||||
launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange");
|
launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange");
|
||||||
launcher.gui_manager.addComponent(CVelocity(),"Velocity");
|
launcher.gui_manager.addComponent(CVelocity(),"Velocity");
|
||||||
|
|
@ -518,32 +425,32 @@ void particlesStart()
|
||||||
launcher.gui_manager.addComponent(CGravity(),"Gravity");
|
launcher.gui_manager.addComponent(CGravity(),"Gravity");
|
||||||
|
|
||||||
EntityTemplate* tmpl;
|
EntityTemplate* tmpl;
|
||||||
EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([becsID!CTexCoords, becsID!CLocation, becsID!CColor, becsID!CVelocity, becsID!CDamping, becsID!CScale, becsID!CMaterialIndex].staticArray);
|
EntityTemplate* base_tmpl = gEntityManager.allocateTemplate([becsID!CTexCoords, becsID!CLocation, becsID!CColor, becsID!CVelocity, becsID!CDamping, becsID!CScale, becsID!CMaterialIndex].staticArray);
|
||||||
base_tmpl.getComponent!CColor().value = 0xFF251010;
|
base_tmpl.getComponent!CColor().value = 0xFF251010;
|
||||||
base_tmpl.getComponent!CScale().value = vec2(2);
|
base_tmpl.getComponent!CScale().value = vec2(2);
|
||||||
base_tmpl.getComponent!CTexCoords().value = vec4(246,64,2,2)*px;
|
base_tmpl.getComponent!CTexCoords().value = vec4(246,64,2,2)*px;
|
||||||
base_tmpl.getComponent!CMaterialIndex().value = 2;
|
base_tmpl.getComponent!CMaterialIndex().value = 2;
|
||||||
launcher.gui_manager.addTemplate(base_tmpl,"Particle");
|
launcher.gui_manager.addTemplate(base_tmpl,"Particle");
|
||||||
// tmpl = launcher.manager.allocateTemplate(base_tmpl);
|
// tmpl = gEntityManager.allocateTemplate(base_tmpl);
|
||||||
// tmpl.getComponent!CColor().value = 0xFF251010;
|
// tmpl.getComponent!CColor().value = 0xFF251010;
|
||||||
// launcher.gui_manager.addTemplate(tmpl,"Particle (blue)");
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (blue)");
|
||||||
// tmpl = launcher.manager.allocateTemplate(base_tmpl);
|
// tmpl = gEntityManager.allocateTemplate(base_tmpl);
|
||||||
// tmpl.getComponent!CColor().value = 0xFF102010;
|
// tmpl.getComponent!CColor().value = 0xFF102010;
|
||||||
// launcher.gui_manager.addTemplate(tmpl,"Particle (green)");
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (green)");
|
||||||
// tmpl = launcher.manager.allocateTemplate(base_tmpl);
|
// tmpl = gEntityManager.allocateTemplate(base_tmpl);
|
||||||
// tmpl.getComponent!CColor().value = 0xFF101540;
|
// tmpl.getComponent!CColor().value = 0xFF101540;
|
||||||
// launcher.gui_manager.addTemplate(tmpl,"Particle (red)");
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (red)");
|
||||||
// tmpl = launcher.manager.allocateTemplate(tmpl, [becsID!CDamping].staticArray);
|
// tmpl = gEntityManager.allocateTemplate(tmpl, [becsID!CDamping].staticArray);
|
||||||
// launcher.gui_manager.addTemplate(tmpl,"Particle (damping)");
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (damping)");
|
||||||
// tmpl = launcher.manager.allocateTemplate(tmpl);
|
// tmpl = gEntityManager.allocateTemplate(tmpl);
|
||||||
// tmpl.getComponent!CDamping().power = 4;
|
// tmpl.getComponent!CDamping().power = 4;
|
||||||
// launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)");
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)");
|
||||||
tmpl = launcher.manager.allocateTemplate([becsID!CAttractor, becsID!CLocation, becsID!CForceRange, becsID!CScale].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CAttractor, becsID!CLocation, becsID!CForceRange, becsID!CScale].staticArray);
|
||||||
tmpl.getComponent!CScale().value = vec2(4);
|
tmpl.getComponent!CScale().value = vec2(4);
|
||||||
launcher.gui_manager.addTemplate(tmpl,"Attractor");
|
launcher.gui_manager.addTemplate(tmpl,"Attractor");
|
||||||
tmpl = launcher.manager.allocateTemplate(tmpl, [becsID!CVortex].staticArray);
|
tmpl = gEntityManager.allocateTemplate(tmpl, [becsID!CVortex].staticArray);
|
||||||
launcher.gui_manager.addTemplate(tmpl,"Vortex");
|
launcher.gui_manager.addTemplate(tmpl,"Vortex");
|
||||||
// tmpl = launcher.manager.allocateTemplate(tmpl);
|
// tmpl = gEntityManager.allocateTemplate(tmpl);
|
||||||
// tmpl.getComponent!CVortex().strength = -0.6;
|
// tmpl.getComponent!CVortex().strength = -0.6;
|
||||||
// launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)");
|
// launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)");
|
||||||
|
|
||||||
|
|
@ -553,7 +460,7 @@ void particlesEnd()
|
||||||
{
|
{
|
||||||
particles_demo.texture.destroy();
|
particles_demo.texture.destroy();
|
||||||
|
|
||||||
//launcher.manager.freeTemplate(simple.tmpl);
|
//gEntityManager.freeTemplate(simple.tmpl);
|
||||||
Mallocator.dispose(particles_demo);
|
Mallocator.dispose(particles_demo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -565,18 +472,18 @@ bool particlesLoop()
|
||||||
{
|
{
|
||||||
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
||||||
|
|
||||||
launcher.manager.begin();
|
gEntityManager.begin();
|
||||||
if(launcher.multithreading)
|
if(launcher.multithreading)
|
||||||
{
|
{
|
||||||
launcher.job_updater.begin();
|
launcher.job_updater.begin();
|
||||||
launcher.manager.updateMT();
|
gEntityManager.updateMT();
|
||||||
launcher.job_updater.call();
|
launcher.job_updater.call();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
launcher.manager.update();
|
gEntityManager.update();
|
||||||
}
|
}
|
||||||
launcher.manager.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,15 @@ void sandboxStart()
|
||||||
particlesStart();
|
particlesStart();
|
||||||
brickBreakerStart();
|
brickBreakerStart();
|
||||||
|
|
||||||
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem;
|
||||||
draw_system.default_data.size = vec2(16,16);
|
draw_system.default_data.size = vec2(16,16);
|
||||||
draw_system.default_data.coords = vec4(0,48,16,16)*demos.simple.px;
|
draw_system.default_data.coords = vec4(0,48,16,16)*demos.simple.px;
|
||||||
draw_system.default_data.material_id = 0;
|
draw_system.default_data.material_id = 0;
|
||||||
draw_system.default_data.texture = particles_demo.texture;
|
draw_system.default_data.texture = particles_demo.texture;
|
||||||
draw_system.default_data.color = 0x80808080;
|
draw_system.default_data.color = 0x80808080;
|
||||||
|
|
||||||
launcher.manager.getSystem(becsID!MouseAttractSystem).disable();
|
gEntityManager.getSystem(becsID!MouseAttractSystem).disable();
|
||||||
launcher.manager.getSystem(becsID!(demos.simple.MoveSystem)).disable();
|
gEntityManager.getSystem(becsID!(demos.simple.MoveSystem)).disable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ bool sandboxLoop()
|
||||||
{
|
{
|
||||||
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
||||||
|
|
||||||
launcher.manager.begin();
|
gEntityManager.begin();
|
||||||
|
|
||||||
float delta_time = launcher.delta_time;
|
float delta_time = launcher.delta_time;
|
||||||
if(delta_time > 2000)delta_time = 2000;
|
if(delta_time > 2000)delta_time = 2000;
|
||||||
|
|
@ -74,20 +74,20 @@ bool sandboxLoop()
|
||||||
{
|
{
|
||||||
time -= 200;
|
time -= 200;
|
||||||
|
|
||||||
launcher.manager.update("fixed");
|
gEntityManager.update("fixed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(launcher.multithreading)
|
if(launcher.multithreading)
|
||||||
{
|
{
|
||||||
launcher.job_updater.begin();
|
launcher.job_updater.begin();
|
||||||
launcher.manager.updateMT();
|
gEntityManager.updateMT();
|
||||||
launcher.job_updater.call();
|
launcher.job_updater.call();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
launcher.manager.update();
|
gEntityManager.update();
|
||||||
}
|
}
|
||||||
launcher.manager.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,22 @@ extern(C):
|
||||||
|
|
||||||
enum float px = 1.0/512.0;
|
enum float px = 1.0/512.0;
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
All demos uses same patten. Every demo is self contained except systems and components which was splitted into different files to enable sharing them between demos.
|
||||||
|
Every demo has same functions:
|
||||||
|
* register - called on start for registering proces
|
||||||
|
* initialize - called after register to initialize demo data
|
||||||
|
* deinitiliaze - called when demo is switching. There data is deisposed
|
||||||
|
* loop - it's called every frame
|
||||||
|
|
||||||
|
Demos uses some non-ECS functions to register components, systems and templates into GUI. Then components are showing by GUI and can be added to entities.
|
||||||
|
*/
|
||||||
|
|
||||||
/*#######################################################################################################################
|
/*#######################################################################################################################
|
||||||
------------------------------------------------ Components ------------------------------------------------------------------
|
------------------------------------------------ Components ------------------------------------------------------------------
|
||||||
#######################################################################################################################*/
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
//CLocation component was moved to game_code.basic
|
||||||
/*struct CLocation
|
/*struct CLocation
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -39,6 +51,7 @@ enum float px = 1.0/512.0;
|
||||||
/*#######################################################################################################################
|
/*#######################################################################################################################
|
||||||
------------------------------------------------ Systems ------------------------------------------------------------------
|
------------------------------------------------ Systems ------------------------------------------------------------------
|
||||||
#######################################################################################################################*/
|
#######################################################################################################################*/
|
||||||
|
//DrawSystem was moved to game_code.basic
|
||||||
/*
|
/*
|
||||||
struct DrawSystem
|
struct DrawSystem
|
||||||
{
|
{
|
||||||
|
|
@ -73,21 +86,29 @@ struct DrawSystem
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
//simple system which moves entities
|
||||||
struct MoveSystem
|
struct MoveSystem
|
||||||
{
|
{
|
||||||
|
//system will generate up to 64 jobs for multithreaded extecution
|
||||||
mixin ECS.System!64;
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
//structe contains components used by system
|
||||||
struct EntitiesData
|
struct EntitiesData
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
|
//system will use one component which is required. Only entities with CLocation component will be processed by this system
|
||||||
CLocation[] locations;
|
CLocation[] locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//onUpdate is called several times and covers all entities
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
|
//loop over entities in batch
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
|
//inscrease entity position in 'y' coordinate
|
||||||
data.locations[i].y = data.locations[i].y + 1;
|
data.locations[i].y = data.locations[i].y + 1;
|
||||||
|
//move entity to 0 if exceeded 300
|
||||||
if(data.locations[i].y > 300)data.locations[i].y = 0;
|
if(data.locations[i].y > 300)data.locations[i].y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +120,7 @@ struct MoveSystem
|
||||||
|
|
||||||
struct Simple
|
struct Simple
|
||||||
{
|
{
|
||||||
|
//tips showed in GUI
|
||||||
__gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Demo\" window.
|
__gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Demo\" window.
|
||||||
\"Tools\" window exists of three tools which can be used to manipulate game.
|
\"Tools\" window exists of three tools which can be used to manipulate game.
|
||||||
Options:
|
Options:
|
||||||
|
|
@ -132,61 +154,77 @@ Demo is capable rendering of hundreds of thousands of entities. Playable area is
|
||||||
|
|
||||||
__gshared Simple* simple;
|
__gshared Simple* simple;
|
||||||
|
|
||||||
|
//called when demo starts
|
||||||
void simpleRegister()
|
void simpleRegister()
|
||||||
{
|
{
|
||||||
simple = Mallocator.make!Simple;
|
simple = Mallocator.make!Simple;
|
||||||
|
|
||||||
|
//load texture (atlas)
|
||||||
simple.texture.create();
|
simple.texture.create();
|
||||||
simple.texture.load("assets/textures/atlas.png");
|
simple.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
launcher.manager.beginRegister();
|
//start registering process
|
||||||
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
registerRenderingModule(launcher.manager);
|
//register basic components and systems
|
||||||
|
registerRenderingModule(gEntityManager);
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
//register location component. It also registered inside registerRenderingModule() function, but it's there for clarity
|
||||||
|
gEntityManager.registerComponent!CLocation;
|
||||||
|
|
||||||
launcher.manager.registerSystem!MoveSystem(0);
|
gEntityManager.registerSystem!MoveSystem(0);
|
||||||
// launcher.manager.registerSystem!DrawSystem(1);
|
// DrawSystem is registered as RenderingModule
|
||||||
|
// gEntityManager.registerSystem!DrawSystem(1);
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
//end registering process
|
||||||
|
gEntityManager.endRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//called after simpleRegister
|
||||||
void simpleStart()
|
void simpleStart()
|
||||||
{
|
{
|
||||||
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
//get DrawSystem instance and change some data
|
||||||
|
DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem;
|
||||||
draw_system.default_data.color = 0x80808080;
|
draw_system.default_data.color = 0x80808080;
|
||||||
draw_system.default_data.texture = simple.texture;
|
draw_system.default_data.texture = simple.texture;
|
||||||
draw_system.default_data.size = vec2(16,16);
|
draw_system.default_data.size = vec2(16,16);
|
||||||
draw_system.default_data.coords = vec4(0,48,16,16)*px;//vec4(0,0,1,1);
|
draw_system.default_data.coords = vec4(0,48,16,16)*px;//vec4(0,0,1,1);
|
||||||
|
|
||||||
|
//add systems to GUI. It's non ECS part
|
||||||
launcher.gui_manager.addSystem(becsID!MoveSystem,"Move Up System");
|
launcher.gui_manager.addSystem(becsID!MoveSystem,"Move Up System");
|
||||||
launcher.gui_manager.addSystem(becsID!DrawSystem,"Draw System");
|
launcher.gui_manager.addSystem(becsID!DrawSystem,"Draw System");
|
||||||
|
|
||||||
|
//add components to GUI. It's non ECS part
|
||||||
launcher.gui_manager.addComponent(CLocation(), "Location");
|
launcher.gui_manager.addComponent(CLocation(), "Location");
|
||||||
launcher.gui_manager.addComponent(CDrawDefault(), "DrawDefault");
|
launcher.gui_manager.addComponent(CDrawDefault(), "DrawDefault");
|
||||||
|
|
||||||
simple.tmpl = launcher.manager.allocateTemplate([becsID!CLocation, becsID!CDrawDefault].staticArray);
|
//allocate new template with two components
|
||||||
//*simple.tmpl.getComponent!CTexCoordsIndex = TexCoordsManager.instance.getCoordIndex(vec4(0,48,16,16)*px);
|
simple.tmpl = gEntityManager.allocateTemplate([becsID!CLocation, becsID!CDrawDefault].staticArray);
|
||||||
//CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
|
||||||
|
|
||||||
|
//add template to GUI. It's non ECS part
|
||||||
launcher.gui_manager.addTemplate(simple.tmpl, "Basic");
|
launcher.gui_manager.addTemplate(simple.tmpl, "Basic");
|
||||||
|
|
||||||
|
//add 100 entities
|
||||||
foreach(i; 0..10)
|
foreach(i; 0..10)
|
||||||
foreach(j; 0..10)
|
foreach(j; 0..10)
|
||||||
{
|
{
|
||||||
//loc_comp.value = vec2(i*16+64,j*16+64);
|
//add entities in grid locations. "ref_" return ComponentRef structure. I'm not sure if adding component inside array generation isn't undefined behaviour but it works on tested platforms
|
||||||
launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(i*16+64,j*16+64)).ref_].staticArray);
|
gEntityManager.addEntity(simple.tmpl,[CLocation(vec2(i*16+64,j*16+64)).ref_].staticArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//called when demo is switched to different one
|
||||||
void simpleEnd()
|
void simpleEnd()
|
||||||
{
|
{
|
||||||
launcher.manager.getSystem(becsID!MoveSystem).disable();
|
//disable systems used by this demo.
|
||||||
launcher.manager.getSystem(becsID!DrawSystem).disable();
|
gEntityManager.getSystem(becsID!MoveSystem).disable();
|
||||||
|
gEntityManager.getSystem(becsID!DrawSystem).disable();
|
||||||
|
|
||||||
|
//free texture memory
|
||||||
simple.texture.destroy();
|
simple.texture.destroy();
|
||||||
|
|
||||||
//launcher.manager.freeTemplate(simple.tmpl);
|
//GUI manager will free template
|
||||||
|
//gEntityManager.freeTemplate(simple.tmpl);
|
||||||
Mallocator.dispose(simple);
|
Mallocator.dispose(simple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,9 +234,8 @@ void simpleEvent(SDL_Event* event)
|
||||||
|
|
||||||
void spawnEntity()
|
void spawnEntity()
|
||||||
{
|
{
|
||||||
//CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
//spawn entity in random location
|
||||||
//loc_comp.value = vec2(randomf() * 400,0);
|
gEntityManager.addEntity(simple.tmpl,[CLocation(vec2(randomf() * 400,0)).ref_].staticArray);
|
||||||
launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(randomf() * 400,0)).ref_].staticArray);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simpleLoop()
|
bool simpleLoop()
|
||||||
|
|
@ -210,18 +247,26 @@ bool simpleLoop()
|
||||||
foreach(i;0..20)spawnEntity();
|
foreach(i;0..20)spawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher.manager.begin();
|
//begin frame
|
||||||
|
gEntityManager.begin();
|
||||||
|
//if multithreading is enabled different path is used
|
||||||
if(launcher.multithreading)
|
if(launcher.multithreading)
|
||||||
{
|
{
|
||||||
|
//prepare data for multithreading. Clear previous jobs data.
|
||||||
launcher.job_updater.begin();
|
launcher.job_updater.begin();
|
||||||
launcher.manager.updateMT();
|
//generate jobs
|
||||||
|
gEntityManager.updateMT();
|
||||||
|
//call jobs in multithreaded fashion
|
||||||
launcher.job_updater.call();
|
launcher.job_updater.call();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
launcher.manager.update();
|
//update call will call inUpdate for all systems
|
||||||
|
gEntityManager.update();
|
||||||
|
|
||||||
}
|
}
|
||||||
launcher.manager.end();
|
//end ECS frame
|
||||||
|
gEntityManager.end();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,14 @@ import ecs_utils.utils;
|
||||||
|
|
||||||
import game_core.basic;
|
import game_core.basic;
|
||||||
|
|
||||||
|
import gui.attributes;
|
||||||
//import std.array : staticArray;
|
//import std.array : staticArray;
|
||||||
|
|
||||||
enum float px = 1.0/512.0;
|
enum float px = 1.0/512.0;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
|
//Map is simple grid. Every cell has type and id to entity.
|
||||||
struct MapElement
|
struct MapElement
|
||||||
{
|
{
|
||||||
enum Type
|
enum Type
|
||||||
|
|
@ -38,6 +40,7 @@ struct MapElement
|
||||||
EntityID id;
|
EntityID id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//snake part is corresponding to graphical representation of snake
|
||||||
enum SnakePart : ubyte
|
enum SnakePart : ubyte
|
||||||
{
|
{
|
||||||
head_up = 0,
|
head_up = 0,
|
||||||
|
|
@ -81,9 +84,9 @@ This demo is an example that in ECS you can make very \"non-ECS\" game";
|
||||||
{
|
{
|
||||||
if(snake_destroy_particle_frames)Mallocator.dispose(snake_destroy_particle_frames);
|
if(snake_destroy_particle_frames)Mallocator.dispose(snake_destroy_particle_frames);
|
||||||
if(smoke_frames)Mallocator.dispose(smoke_frames);
|
if(smoke_frames)Mallocator.dispose(smoke_frames);
|
||||||
if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl);
|
if(apple_tmpl)gEntityManager.freeTemplate(apple_tmpl);
|
||||||
if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl);
|
if(snake_tmpl)gEntityManager.freeTemplate(snake_tmpl);
|
||||||
if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle);
|
if(snake_destroy_particle)gEntityManager.freeTemplate(snake_destroy_particle);
|
||||||
texture.destroy();
|
texture.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +119,7 @@ This demo is an example that in ECS you can make very \"non-ECS\" game";
|
||||||
}
|
}
|
||||||
if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return;
|
if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return;
|
||||||
}
|
}
|
||||||
launcher.manager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray);
|
gEntityManager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,14 +128,16 @@ struct Animation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//component has array of frames (texture coordinates) and time used for selection frames
|
||||||
struct CAnimation
|
struct CAnimation
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
vec4[] frames;
|
vec4[] frames;
|
||||||
float time = 0;
|
@GUIRangeF(0,float.max)float time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//CIlocation is integer location used as grid cell coordination
|
||||||
struct CILocation
|
struct CILocation
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -199,14 +204,16 @@ struct CSnake
|
||||||
}
|
}
|
||||||
|
|
||||||
Parts parts;
|
Parts parts;
|
||||||
CMovement.Direction direction;
|
@GUIRange(0,3)CMovement.Direction direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//flag for apple
|
||||||
struct CApple
|
struct CApple
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//particle is removed when life drops below 0
|
||||||
struct CParticle
|
struct CParticle
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -214,6 +221,7 @@ struct CParticle
|
||||||
float life = 0;
|
float life = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//vector for particle movement
|
||||||
struct CParticleVector
|
struct CParticleVector
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -221,6 +229,7 @@ struct CParticleVector
|
||||||
vec2 velocity = vec2(0,0);
|
vec2 velocity = vec2(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//contains current movement direction for snake
|
||||||
struct CMovement
|
struct CMovement
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -233,7 +242,7 @@ struct CMovement
|
||||||
right
|
right
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction direction;
|
@GUIRange(0,3)Direction direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct CInput
|
// struct CInput
|
||||||
|
|
@ -241,6 +250,7 @@ struct CMovement
|
||||||
// mixin ECS.Component;
|
// mixin ECS.Component;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
//this system has no onUpdate and only processing events. It responsible for adding and removing applce from grid.
|
||||||
struct AppleSystem
|
struct AppleSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!1;
|
mixin ECS.System!1;
|
||||||
|
|
@ -253,15 +263,17 @@ struct AppleSystem
|
||||||
@readonly CILocation[] location;
|
@readonly CILocation[] location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//called when entity was created
|
||||||
void onAddEntity(EntitiesData data)
|
void onAddEntity(EntitiesData data)
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.apple,data.entity[i].id),data.location[i]);
|
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.apple,data.entity[i].id),data.location[i]);
|
||||||
else launcher.manager.removeEntity(data.entity[i].id);
|
else gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//called when entity was removed
|
||||||
void onRemoveEntity(EntitiesData data)
|
void onRemoveEntity(EntitiesData data)
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
|
|
@ -272,6 +284,7 @@ struct AppleSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//system is responsible for killing particles when their life drops below 0
|
||||||
struct ParticleSystem
|
struct ParticleSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!1;
|
mixin ECS.System!1;
|
||||||
|
|
@ -288,11 +301,12 @@ struct ParticleSystem
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
data.particle[i].life -= launcher.deltaTime;
|
data.particle[i].life -= launcher.deltaTime;
|
||||||
if(data.particle[i].life < 0)launcher.manager.removeEntity(data.entities[i].id);
|
if(data.particle[i].life < 0)gEntityManager.removeEntity(data.entities[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//system responsible for moving particles
|
||||||
struct ParticleMovementSystem
|
struct ParticleMovementSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!1;
|
mixin ECS.System!1;
|
||||||
|
|
@ -360,10 +374,11 @@ struct AnimationRenderSystem
|
||||||
draw_data.depth = -1;
|
draw_data.depth = -1;
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
|
uint frame = cast(uint)(data.animation[i].time);
|
||||||
|
if(frame >= data.animation[i].frames.length)frame = cast(uint)data.animation[i].frames.length - 1;
|
||||||
draw_data.position = data.location[i];
|
draw_data.position = data.location[i];
|
||||||
draw_data.coords = data.animation[i].frames[cast(int)(data.animation[i].time)];
|
draw_data.coords = data.animation[i].frames[frame];
|
||||||
launcher.renderer.draw(draw_data);
|
launcher.renderer.draw(draw_data);
|
||||||
//launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i], vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,8 +388,6 @@ struct MoveSystem
|
||||||
mixin ECS.System!64;
|
mixin ECS.System!64;
|
||||||
|
|
||||||
EntityTemplate* destroy_template;
|
EntityTemplate* destroy_template;
|
||||||
//CLocation* destroy_location;
|
|
||||||
//CParticleVector* destroy_vector;
|
|
||||||
|
|
||||||
struct EntitiesData
|
struct EntitiesData
|
||||||
{
|
{
|
||||||
|
|
@ -387,9 +400,8 @@ struct MoveSystem
|
||||||
|
|
||||||
void setTemplates()
|
void setTemplates()
|
||||||
{
|
{
|
||||||
|
//template is used for adding particles when snake will collide with himself
|
||||||
destroy_template = snake.snake_destroy_particle;
|
destroy_template = snake.snake_destroy_particle;
|
||||||
//destroy_location = destroy_template.getComponent!CLocation;
|
|
||||||
//destroy_vector = destroy_template.getComponent!CParticleVector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveLocation(ref CILocation location, CMovement.Direction direction)
|
void moveLocation(ref CILocation location, CMovement.Direction direction)
|
||||||
|
|
@ -446,7 +458,7 @@ struct MoveSystem
|
||||||
//destroy_location.x = loc.x * 16;
|
//destroy_location.x = loc.x * 16;
|
||||||
//destroy_location.y = loc.y * 16;
|
//destroy_location.y = loc.y * 16;
|
||||||
snake.element(MapElement(MapElement.Type.empty, EntityID()),loc);
|
snake.element(MapElement(MapElement.Type.empty, EntityID()),loc);
|
||||||
launcher.manager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(loc * 16)).ref_].staticArray);
|
gEntityManager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(loc * 16)).ref_].staticArray);
|
||||||
|
|
||||||
CLocation destroy_location;
|
CLocation destroy_location;
|
||||||
foreach(j;0..10)
|
foreach(j;0..10)
|
||||||
|
|
@ -455,15 +467,15 @@ struct MoveSystem
|
||||||
destroy_location.y = loc.y * 16 + randomf() * 8 - 4;
|
destroy_location.y = loc.y * 16 + randomf() * 8 - 4;
|
||||||
//destroy_vector.velocity = vec2(randomf(),randomf())*0.4-0.2;
|
//destroy_vector.velocity = vec2(randomf(),randomf())*0.4-0.2;
|
||||||
snake.element(MapElement(MapElement.Type.empty, EntityID()),loc);
|
snake.element(MapElement(MapElement.Type.empty, EntityID()),loc);
|
||||||
launcher.manager.addEntity(snake.snake_destroy_particle, [destroy_location.ref_, CParticleVector(vec2(randomf(),randomf())*0.4-0.2).ref_].staticArray);
|
gEntityManager.addEntity(snake.snake_destroy_particle, [destroy_location.ref_, CParticleVector(vec2(randomf(),randomf())*0.4-0.2).ref_].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//destroy_location.x = new_location.x * 16;
|
//destroy_location.x = new_location.x * 16;
|
||||||
//destroy_location.y = new_location.y * 16;
|
//destroy_location.y = new_location.y * 16;
|
||||||
snake.element(MapElement(MapElement.Type.empty, EntityID()),new_location);
|
snake.element(MapElement(MapElement.Type.empty, EntityID()),new_location);
|
||||||
launcher.manager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(new_location * 16)).ref_].staticArray);
|
gEntityManager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(new_location * 16)).ref_].staticArray);
|
||||||
launcher.manager.removeEntity(data.entities[i].id);
|
gEntityManager.removeEntity(data.entities[i].id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MapElement.Type.wall:break;
|
case MapElement.Type.wall:break;
|
||||||
|
|
@ -482,7 +494,7 @@ struct MoveSystem
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MapElement.Type.apple:
|
case MapElement.Type.apple:
|
||||||
launcher.manager.removeEntity(snake.element(data.location[i].location).id);
|
gEntityManager.removeEntity(snake.element(data.location[i].location).id);
|
||||||
if(data.snakes[i].parts.length >= 99)
|
if(data.snakes[i].parts.length >= 99)
|
||||||
{
|
{
|
||||||
snake.addApple();
|
snake.addApple();
|
||||||
|
|
@ -537,7 +549,7 @@ struct SnakeSystem
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.snake,data.entity[i].id),data.location[i]);
|
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.snake,data.entity[i].id),data.location[i]);
|
||||||
else launcher.manager.removeEntity(data.entity[i].id);
|
else gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -814,7 +826,7 @@ struct CleanSystem
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
launcher.manager.removeEntity(data.entities[i].id);
|
gEntityManager.removeEntity(data.entities[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -859,38 +871,38 @@ void snakeRegister()
|
||||||
snake.texture.create();
|
snake.texture.create();
|
||||||
snake.texture.load("assets/textures/atlas.png");
|
snake.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
launcher.manager.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
launcher.manager.registerPass("fixed");
|
gEntityManager.registerPass("fixed");
|
||||||
|
|
||||||
registerRenderingModule(launcher.manager);
|
registerRenderingModule(gEntityManager);
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
gEntityManager.registerComponent!CLocation;
|
||||||
launcher.manager.registerComponent!CILocation;
|
gEntityManager.registerComponent!CILocation;
|
||||||
launcher.manager.registerComponent!CSnake;
|
gEntityManager.registerComponent!CSnake;
|
||||||
launcher.manager.registerComponent!CApple;
|
gEntityManager.registerComponent!CApple;
|
||||||
launcher.manager.registerComponent!CParticle;
|
gEntityManager.registerComponent!CParticle;
|
||||||
launcher.manager.registerComponent!CParticleVector;
|
gEntityManager.registerComponent!CParticleVector;
|
||||||
launcher.manager.registerComponent!CMovement;
|
gEntityManager.registerComponent!CMovement;
|
||||||
launcher.manager.registerComponent!CInput;
|
gEntityManager.registerComponent!CInput;
|
||||||
launcher.manager.registerComponent!CAnimation;
|
gEntityManager.registerComponent!CAnimation;
|
||||||
|
|
||||||
launcher.manager.registerSystem!MoveSystem(0,"fixed");
|
gEntityManager.registerSystem!MoveSystem(0,"fixed");
|
||||||
launcher.manager.registerSystem!InputSystem(-100);
|
gEntityManager.registerSystem!InputSystem(-100);
|
||||||
launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed");
|
gEntityManager.registerSystem!FixSnakeDirectionSystem(-1,"fixed");
|
||||||
launcher.manager.registerSystem!AnimationRenderSystem(100);
|
gEntityManager.registerSystem!AnimationRenderSystem(100);
|
||||||
launcher.manager.registerSystem!AnimationSystem(-1);
|
gEntityManager.registerSystem!AnimationSystem(-1);
|
||||||
launcher.manager.registerSystem!ParticleSystem(-1);
|
gEntityManager.registerSystem!ParticleSystem(-1);
|
||||||
launcher.manager.registerSystem!ParticleMovementSystem(-1);
|
gEntityManager.registerSystem!ParticleMovementSystem(-1);
|
||||||
launcher.manager.registerSystem!DrawAppleSystem(99);
|
gEntityManager.registerSystem!DrawAppleSystem(99);
|
||||||
launcher.manager.registerSystem!DrawSnakeSystem(101);
|
gEntityManager.registerSystem!DrawSnakeSystem(101);
|
||||||
|
|
||||||
launcher.manager.registerSystem!CopyLocationSystem(100);
|
gEntityManager.registerSystem!CopyLocationSystem(100);
|
||||||
//launcher.manager.registerSystem!AppleRemoveSystem(100);
|
//gEntityManager.registerSystem!AppleRemoveSystem(100);
|
||||||
launcher.manager.registerSystem!AppleSystem(101);
|
gEntityManager.registerSystem!AppleSystem(101);
|
||||||
launcher.manager.registerSystem!SnakeSystem(101);
|
gEntityManager.registerSystem!SnakeSystem(101);
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
gEntityManager.endRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
void snakeStart()
|
void snakeStart()
|
||||||
|
|
@ -901,8 +913,9 @@ void snakeStart()
|
||||||
launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector");
|
launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector");
|
||||||
launcher.gui_manager.addComponent(CInput(),"Input");
|
launcher.gui_manager.addComponent(CInput(),"Input");
|
||||||
launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement");
|
launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement");
|
||||||
//launcher.gui_manager.addComponent(CAnimation(),"Movement");
|
launcher.gui_manager.addComponent(CAnimation(),"Animation");
|
||||||
launcher.gui_manager.addComponent(CILocation(),"Int Location");
|
launcher.gui_manager.addComponent(CILocation(),"Int Location");
|
||||||
|
launcher.gui_manager.addComponent(CLocation(),"Location");
|
||||||
|
|
||||||
launcher.gui_manager.addSystem(becsID!MoveSystem,"Move System");
|
launcher.gui_manager.addSystem(becsID!MoveSystem,"Move System");
|
||||||
launcher.gui_manager.addSystem(becsID!InputSystem,"Input System");
|
launcher.gui_manager.addSystem(becsID!InputSystem,"Input System");
|
||||||
|
|
@ -913,17 +926,20 @@ void snakeStart()
|
||||||
launcher.gui_manager.addSystem(becsID!ParticleMovementSystem,"Particle Movement System");
|
launcher.gui_manager.addSystem(becsID!ParticleMovementSystem,"Particle Movement System");
|
||||||
launcher.gui_manager.addSystem(becsID!DrawAppleSystem,"Draw Apple System");
|
launcher.gui_manager.addSystem(becsID!DrawAppleSystem,"Draw Apple System");
|
||||||
launcher.gui_manager.addSystem(becsID!DrawSnakeSystem,"Draw Snake System");
|
launcher.gui_manager.addSystem(becsID!DrawSnakeSystem,"Draw Snake System");
|
||||||
|
launcher.gui_manager.addSystem(becsID!CopyLocationSystem,"Copy Location System");
|
||||||
|
//launcher.gui_manager.addSystem(becsID!AppleSystem,"Apple System");
|
||||||
|
//launcher.gui_manager.addSystem(becsID!SnakeSystem,"Snake System");
|
||||||
|
|
||||||
snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray);
|
snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray);
|
||||||
|
|
||||||
{
|
{
|
||||||
ushort[5] components = [becsID!CILocation, becsID!CSnake, becsID!CMovement, becsID!CInput, becsID!CLocation];
|
ushort[5] components = [becsID!CILocation, becsID!CSnake, becsID!CMovement, becsID!CInput, becsID!CLocation];
|
||||||
snake.snake_tmpl = launcher.manager.allocateTemplate(components);
|
snake.snake_tmpl = gEntityManager.allocateTemplate(components);
|
||||||
launcher.manager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray);
|
gEntityManager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
snake.snake_destroy_particle = launcher.manager.allocateTemplate([becsID!CLocation, becsID!CParticle, becsID!CParticleVector, becsID!CAnimation, becsID!CLocation].staticArray);
|
snake.snake_destroy_particle = gEntityManager.allocateTemplate([becsID!CLocation, becsID!CParticle, becsID!CParticleVector, becsID!CAnimation, becsID!CLocation].staticArray);
|
||||||
CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation;
|
CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation;
|
||||||
canim.frames = snake.snake_destroy_particle_frames;
|
canim.frames = snake.snake_destroy_particle_frames;
|
||||||
CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle;
|
CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle;
|
||||||
|
|
@ -932,21 +948,21 @@ void snakeStart()
|
||||||
|
|
||||||
{
|
{
|
||||||
ushort[3] components = [becsID!CILocation, becsID!CApple, becsID!CLocation];
|
ushort[3] components = [becsID!CILocation, becsID!CApple, becsID!CLocation];
|
||||||
snake.apple_tmpl = launcher.manager.allocateTemplate(components);
|
snake.apple_tmpl = gEntityManager.allocateTemplate(components);
|
||||||
snake.addApple();
|
snake.addApple();
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(snake.snake_tmpl), "Snake");
|
launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(snake.snake_tmpl), "Snake");
|
||||||
launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(snake.apple_tmpl), "Apple");
|
launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(snake.apple_tmpl), "Apple");
|
||||||
launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(snake.snake_destroy_particle), "Particle");
|
launcher.gui_manager.addTemplate(gEntityManager.allocateTemplate(snake.snake_destroy_particle), "Particle");
|
||||||
|
|
||||||
MoveSystem* move_system = launcher.manager.getSystem!MoveSystem();
|
MoveSystem* move_system = gEntityManager.getSystem!MoveSystem();
|
||||||
move_system.setTemplates();
|
move_system.setTemplates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void snakeEnd()
|
void snakeEnd()
|
||||||
{
|
{
|
||||||
//launcher.manager.freeTemplate(simple.tmpl);
|
//gEntityManager.freeTemplate(simple.tmpl);
|
||||||
Mallocator.dispose(snake);
|
Mallocator.dispose(snake);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -970,7 +986,7 @@ bool snakeLoop()
|
||||||
// igEnd();
|
// igEnd();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
launcher.manager.begin();
|
gEntityManager.begin();
|
||||||
|
|
||||||
float delta_time = launcher.deltaTime;
|
float delta_time = launcher.deltaTime;
|
||||||
if(delta_time > 2000)delta_time = 2000;
|
if(delta_time > 2000)delta_time = 2000;
|
||||||
|
|
@ -983,12 +999,12 @@ bool snakeLoop()
|
||||||
{
|
{
|
||||||
time -= 200;
|
time -= 200;
|
||||||
|
|
||||||
launcher.manager.update("fixed");
|
gEntityManager.update("fixed");
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher.manager.update();
|
gEntityManager.update();
|
||||||
|
|
||||||
launcher.manager.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -13,33 +13,39 @@ import app : launcher;
|
||||||
|
|
||||||
import bindbc.sdl;
|
import bindbc.sdl;
|
||||||
|
|
||||||
|
//position component
|
||||||
struct CLocation
|
struct CLocation
|
||||||
{
|
{
|
||||||
|
//adds some extra functionality. Not required. Will be probably removed from library in the future.
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
alias value this;
|
alias value this;//use component as it value
|
||||||
|
|
||||||
|
//default values work properly
|
||||||
vec2 value = vec2(0);
|
vec2 value = vec2(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//scale component
|
||||||
struct CScale
|
struct CScale
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
alias value this;///use component as it value
|
alias value this;//use component as it value
|
||||||
|
|
||||||
vec2 value = vec2(16,16);
|
vec2 value = vec2(16,16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//rotation component
|
||||||
struct CRotation
|
struct CRotation
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
alias value this;///use component as it value
|
alias value this;//use component as it value
|
||||||
|
|
||||||
float value = 0;
|
float value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//depth component. Entity with higher depth will be rendered on top
|
||||||
struct CDepth
|
struct CDepth
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -49,6 +55,7 @@ struct CDepth
|
||||||
short value;
|
short value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//color component
|
||||||
struct CColor
|
struct CColor
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -58,6 +65,7 @@ struct CColor
|
||||||
@GUIColor uint value;
|
@GUIColor uint value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//component used for selection
|
||||||
struct CSelected
|
struct CSelected
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -65,11 +73,13 @@ struct CSelected
|
||||||
bool value = false;
|
bool value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//component indicating that entity should receive input from mouse, keyboard, etc.
|
||||||
struct CInput
|
struct CInput
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//component with damping value
|
||||||
struct CDamping
|
struct CDamping
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -79,6 +89,7 @@ struct CDamping
|
||||||
@GUIRange(0,9) byte value = 1;
|
@GUIRange(0,9) byte value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//velocity component
|
||||||
struct CVelocity
|
struct CVelocity
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -88,6 +99,7 @@ struct CVelocity
|
||||||
vec2 value = vec2(0,0);
|
vec2 value = vec2(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//factor which is used for velocity masking
|
||||||
struct CVelocityFactor
|
struct CVelocityFactor
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
@ -97,30 +109,35 @@ struct CVelocityFactor
|
||||||
vec2 value = vec2(1);
|
vec2 value = vec2(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//flag indicating that entity is static and shouldn't be updated by most systems in every frame
|
||||||
struct CStatic
|
struct CStatic
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//system which slowing down entities
|
||||||
struct DampingSystem
|
struct DampingSystem
|
||||||
{
|
{
|
||||||
|
//system will generate up to 32 jobs
|
||||||
mixin ECS.System!32;
|
mixin ECS.System!32;
|
||||||
|
|
||||||
struct EntitiesData
|
struct EntitiesData
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
const (Entity)[] entity;
|
const (Entity)[] entity; //entity is readonly
|
||||||
@readonly CDamping[] damping;
|
@readonly CDamping[] damping;//damping is readonly. Marking with @readonly will help multithreading algorithm
|
||||||
CVelocity[] velocity;
|
CVelocity[] velocity;//velocity is wirtable as it will be modified for entities in this system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//20 predefined damping speeds. Gives possibility to store damping as single byte.
|
||||||
float[20] damp = 0;
|
float[20] damp = 0;
|
||||||
|
|
||||||
bool onBegin()
|
bool onBegin()
|
||||||
{
|
{
|
||||||
|
//calculate damping values
|
||||||
foreach(i;0..20)
|
foreach(i;0..20)
|
||||||
{
|
{
|
||||||
damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1);
|
damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.deltaTime*0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -130,11 +147,13 @@ struct DampingSystem
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
|
//constantly slow down entity
|
||||||
data.velocity[i] = data.velocity[i] * damp[data.damping[i]];
|
data.velocity[i] = data.velocity[i] * damp[data.damping[i]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//system used for entity movement
|
||||||
struct MoveSystem
|
struct MoveSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!64;
|
mixin ECS.System!64;
|
||||||
|
|
@ -144,23 +163,24 @@ struct MoveSystem
|
||||||
uint length;
|
uint length;
|
||||||
CLocation[] location;
|
CLocation[] location;
|
||||||
@readonly CVelocity[] velocity;
|
@readonly CVelocity[] velocity;
|
||||||
@optional @readonly CVelocityFactor[] vel_factor;
|
@optional @readonly CVelocityFactor[] vel_factor;//CVeclocityFactor is not required so entites without this component will be also updated
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
|
//split into two loops for two types of entities. Doing it in "normal" way by testing data.vel_factor inside loop in every iteration will be probably compiled as same machine code in release build (it works in LDC)
|
||||||
if(data.vel_factor)
|
if(data.vel_factor)
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time;
|
data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
data.location[i] += data.velocity[i] * launcher.delta_time;
|
data.location[i] += data.velocity[i] * launcher.deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,32 +248,13 @@ struct InputMovementSystem
|
||||||
*/
|
*/
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
/*if(move_vector.x == 0)
|
|
||||||
{
|
|
||||||
foreach(i; 0..data.length)
|
|
||||||
{
|
|
||||||
data.textures[i].coords = vec4(0*px,80*px,48*px,32*px);
|
|
||||||
}
|
|
||||||
//return;
|
|
||||||
}*/
|
|
||||||
//move every entity using movement vector
|
|
||||||
//if(move_vector.x != 0 || move_vector.y != 0)
|
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
data.velocity[i] += move_vector * launcher.delta_time * 0.005;
|
data.velocity[i] += move_vector * launcher.deltaTime * 0.005;
|
||||||
if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5;
|
if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5;
|
||||||
else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5;
|
else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5;
|
||||||
if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5;
|
if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5;
|
||||||
else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5;
|
else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5;
|
||||||
//data.locations[i].x += move_vector.x * launcher.delta_time * 0.25;
|
|
||||||
//data.locations[i].y += move_vector.y * launcher.delta_time * 0.25;
|
|
||||||
//if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px);
|
|
||||||
//else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px);
|
|
||||||
}
|
}
|
||||||
/*else
|
|
||||||
foreach(i; 0..data.length)
|
|
||||||
{
|
|
||||||
data.velocity[i] = vec2(0,0);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ import ecs_utils.utils;
|
||||||
|
|
||||||
import game_core.basic;
|
import game_core.basic;
|
||||||
|
|
||||||
|
import gui.attributes;
|
||||||
|
|
||||||
void registerCollisionModule(EntityManager* manager)
|
void registerCollisionModule(EntityManager* manager)
|
||||||
{
|
{
|
||||||
|
|
@ -46,7 +47,7 @@ struct CBVH
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
uint index;
|
@GUIDisabled uint index;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CAABB
|
struct CAABB
|
||||||
|
|
@ -64,7 +65,7 @@ struct CShootGridMask
|
||||||
|
|
||||||
alias value this;
|
alias value this;
|
||||||
|
|
||||||
ubyte value;
|
@GUIDisabled ubyte value;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CColliderScale
|
struct CColliderScale
|
||||||
|
|
@ -188,7 +189,7 @@ struct ShootGridCleaner
|
||||||
|
|
||||||
bool onBegin()
|
bool onBegin()
|
||||||
{
|
{
|
||||||
grid = gEM.getSystem!ShootGridManager().grid;
|
grid = gEntityManager.getSystem!ShootGridManager().grid;
|
||||||
if(grid != null)return true;
|
if(grid != null)return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
@ -964,7 +965,7 @@ struct BVHBuilder2
|
||||||
|
|
||||||
void onCreate()
|
void onCreate()
|
||||||
{
|
{
|
||||||
tree = gEM.getSystem!BVHBuilder().tree;
|
tree = gEntityManager.getSystem!BVHBuilder().tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool onBegin()
|
bool onBegin()
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,8 @@ module game_core.job_updater;
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
import bubel.ecs.vector;
|
import bubel.ecs.vector;
|
||||||
import bubel.ecs.atomic;
|
import bubel.ecs.atomic;
|
||||||
|
|
||||||
import ecs_utils.utils;
|
|
||||||
|
|
||||||
//import core.time;
|
|
||||||
import bubel.ecs.manager;
|
import bubel.ecs.manager;
|
||||||
|
|
||||||
import mmutils.thread_pool;
|
import mmutils.thread_pool;
|
||||||
|
|
||||||
version(LDC)
|
version(LDC)
|
||||||
|
|
@ -21,7 +18,26 @@ else
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//import supre.core.call_graph_generator;
|
version(Android)
|
||||||
|
{
|
||||||
|
alias pthread_key_t = uint;
|
||||||
|
|
||||||
|
extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow;
|
||||||
|
extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow;
|
||||||
|
extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow;
|
||||||
|
extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow;
|
||||||
|
}
|
||||||
|
else version(WebAssembly)
|
||||||
|
{
|
||||||
|
alias pthread_key_t = uint;
|
||||||
|
|
||||||
|
extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow;
|
||||||
|
extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow;
|
||||||
|
extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow;
|
||||||
|
extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow;
|
||||||
|
|
||||||
|
extern (C) void emscripten_main_thread_process_queued_calls();
|
||||||
|
}
|
||||||
|
|
||||||
struct ECSJobUpdater
|
struct ECSJobUpdater
|
||||||
{
|
{
|
||||||
|
|
@ -33,30 +49,15 @@ struct ECSJobUpdater
|
||||||
|
|
||||||
~this()
|
~this()
|
||||||
{
|
{
|
||||||
|
//wait for end of jobs
|
||||||
pool.waitThreads();
|
pool.waitThreads();
|
||||||
//pool.unregistExternalThread(thread_data);
|
//dispose jobs array
|
||||||
if(jobs)Mallocator.dispose(jobs);
|
if(jobs)Mallocator.dispose(jobs);
|
||||||
|
//free TLS data
|
||||||
version(WebAssembly)pthread_key_delete(tls_key);
|
version(WebAssembly)pthread_key_delete(tls_key);
|
||||||
else version(Android)pthread_key_delete(tls_key);
|
else version(Android)pthread_key_delete(tls_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
version(WebAssembly)
|
|
||||||
{
|
|
||||||
__gshared pthread_key_t tls_key;
|
|
||||||
}
|
|
||||||
else version(Android)
|
|
||||||
{
|
|
||||||
__gshared pthread_key_t tls_key;
|
|
||||||
}
|
|
||||||
else static uint thread_id = 0;
|
|
||||||
|
|
||||||
ThreadPool pool;
|
|
||||||
ThreadData* thread_data;
|
|
||||||
|
|
||||||
int job_id = 0;
|
|
||||||
int no_dep_count = 0;
|
|
||||||
//static uint thread_id = 0;
|
|
||||||
|
|
||||||
struct Group
|
struct Group
|
||||||
{
|
{
|
||||||
~this() nothrow
|
~this() nothrow
|
||||||
|
|
@ -65,33 +66,40 @@ struct ECSJobUpdater
|
||||||
}
|
}
|
||||||
|
|
||||||
JobsGroup group;
|
JobsGroup group;
|
||||||
JobData[1024] jobs;
|
//each group can have up to 128 jobs
|
||||||
JobCaller[1024] callers;
|
JobData[128] jobs;
|
||||||
|
JobCaller[128] callers;
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
|
//mmutils.ThreadPool uses system of dependency where dependencies are added for child groups.
|
||||||
|
//Parent group has atomic counter and after completition it will add job groups dependant on it.
|
||||||
void dependantOn(Group* dependency)
|
void dependantOn(Group* dependency)
|
||||||
{
|
{
|
||||||
group.dependantOn(&dependency.group);
|
group.dependantOn(&dependency.group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add group to pool
|
||||||
void start()
|
void start()
|
||||||
{
|
{
|
||||||
group.thPool.addGroupAsynchronous(&group);
|
group.thPool.addGroupAsynchronous(&group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add jobs slice to group structure
|
||||||
void build(ThreadPool* pool)
|
void build(ThreadPool* pool)
|
||||||
{
|
{
|
||||||
group.thPool = pool;
|
group.thPool = pool;
|
||||||
group.jobs = jobs[0..count];
|
group.jobs = jobs[0..count];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//clear jobs
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
group = JobsGroup("name",null);
|
group = JobsGroup("name",null);
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add single job to group
|
||||||
void add(JobCaller caller)
|
void add(JobCaller caller)
|
||||||
{
|
{
|
||||||
callers[count] = caller;
|
callers[count] = caller;
|
||||||
|
|
@ -100,15 +108,10 @@ struct ECSJobUpdater
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Group[] jobs;
|
//initialize thread pool and data
|
||||||
Vector!(Group*) call_jobs;
|
|
||||||
Group last_job;
|
|
||||||
JobData[1] groupEndJobs;
|
|
||||||
|
|
||||||
//TrackData[32] trackers;
|
|
||||||
|
|
||||||
void onCreate(uint threads_count)
|
void onCreate(uint threads_count)
|
||||||
{
|
{
|
||||||
|
//create TLS for Android and WebAsssembly
|
||||||
version(WebAssembly)pthread_key_create(&tls_key, null);
|
version(WebAssembly)pthread_key_create(&tls_key, null);
|
||||||
else version(Android)pthread_key_create(&tls_key, null);
|
else version(Android)pthread_key_create(&tls_key, null);
|
||||||
|
|
||||||
|
|
@ -119,6 +122,7 @@ struct ECSJobUpdater
|
||||||
jobs = Mallocator.makeArray!Group(256);
|
jobs = Mallocator.makeArray!Group(256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this function are providingn ThreadID to ECS. BubelECS is expecting ThreadID to be linear ID in range (0;ThreadsCount)
|
||||||
uint getThreadID() @nogc nothrow
|
uint getThreadID() @nogc nothrow
|
||||||
{
|
{
|
||||||
version(WebAssembly)return cast(int)pthread_getspecific(tls_key);
|
version(WebAssembly)return cast(int)pthread_getspecific(tls_key);
|
||||||
|
|
@ -126,9 +130,9 @@ struct ECSJobUpdater
|
||||||
else return thread_id;
|
else return thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//clear jobs data
|
||||||
void begin()
|
void begin()
|
||||||
{
|
{
|
||||||
job_id = 0;
|
|
||||||
call_jobs.clear();
|
call_jobs.clear();
|
||||||
|
|
||||||
foreach(ref job;jobs)
|
foreach(ref job;jobs)
|
||||||
|
|
@ -139,68 +143,57 @@ struct ECSJobUpdater
|
||||||
last_job.clear();
|
last_job.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearTracker()
|
//execute jobs
|
||||||
{
|
|
||||||
//foreach(ref tracker;trackers)tracker.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@optStrategy("none")
|
|
||||||
void nop()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@optStrategy("none")
|
|
||||||
void call()
|
void call()
|
||||||
{
|
{
|
||||||
|
//if there is no work return
|
||||||
if(last_job.group.getDependenciesWaitCount() == 0)return;
|
if(last_job.group.getDependenciesWaitCount() == 0)return;
|
||||||
if(call_jobs.length == 0)return;
|
if(call_jobs.length == 0)return;
|
||||||
|
|
||||||
//JobData[1] groupEndJobs;
|
//set last job
|
||||||
groupEndJobs[0] = JobData(&releaseMainThread, "Stop Threads", null, null);
|
groupEndJobs[0] = JobData(&releaseMainThread, "Stop Threads", null, null);
|
||||||
|
|
||||||
|
//add job to group
|
||||||
last_job.group.jobs = groupEndJobs;
|
last_job.group.jobs = groupEndJobs;
|
||||||
|
//set thread pool pointer
|
||||||
last_job.group.thPool = &pool;
|
last_job.group.thPool = &pool;
|
||||||
|
//last job should be called on main thread. It prevent some issues with death loops.
|
||||||
last_job.group.executeOnThreadNum = 0;
|
last_job.group.executeOnThreadNum = 0;
|
||||||
|
|
||||||
|
//start jobs without dependencies
|
||||||
foreach(job;call_jobs)
|
foreach(job;call_jobs)
|
||||||
{
|
{
|
||||||
job.start();
|
job.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*while(atomicLoad(ret) == 1)//!cas(&ret,0,1))
|
//add main thread to pool. It will be released in last job.
|
||||||
{
|
|
||||||
nop();
|
|
||||||
version(WebAssembly)//emscripten_main_thread_process_queued_calls();
|
|
||||||
}//*/
|
|
||||||
|
|
||||||
thread_data.threadStartFunc();
|
thread_data.threadStartFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//callback that will release main thread
|
||||||
void releaseMainThread(ThreadData* th_data, JobData* data)
|
void releaseMainThread(ThreadData* th_data, JobData* data)
|
||||||
{
|
{
|
||||||
//atomicStore(ret,0);
|
|
||||||
pool.releaseExternalThreads();
|
pool.releaseExternalThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct JobCaller
|
static struct JobCaller
|
||||||
{
|
{
|
||||||
|
//ECS job
|
||||||
EntityManager.Job* job;
|
EntityManager.Job* job;
|
||||||
|
//pointer to parent
|
||||||
ECSJobUpdater* updater;
|
ECSJobUpdater* updater;
|
||||||
|
//job ID
|
||||||
uint id;
|
uint id;
|
||||||
|
|
||||||
|
//called by external thread
|
||||||
void callJob(ThreadData* th_data, JobData* data)
|
void callJob(ThreadData* th_data, JobData* data)
|
||||||
{
|
{
|
||||||
|
|
||||||
//uint job_id = updater.getThreadID();
|
|
||||||
//updater.trackers[job_id].begin(id);
|
|
||||||
version(WebAssembly)
|
version(WebAssembly)
|
||||||
{
|
{
|
||||||
//updater.thread_id = th_data.threadId;
|
|
||||||
pthread_setspecific(tls_key, cast(void*)th_data.threadId);
|
pthread_setspecific(tls_key, cast(void*)th_data.threadId);
|
||||||
if(th_data.threadId == 0)
|
if(th_data.threadId == 0)
|
||||||
{
|
{
|
||||||
|
//this emscripten call is required to make multithreading working
|
||||||
emscripten_main_thread_process_queued_calls();
|
emscripten_main_thread_process_queued_calls();
|
||||||
job.execute();
|
job.execute();
|
||||||
emscripten_main_thread_process_queued_calls();
|
emscripten_main_thread_process_queued_calls();
|
||||||
|
|
@ -214,23 +207,27 @@ struct ECSJobUpdater
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//set thread id
|
||||||
updater.thread_id = th_data.threadId;
|
updater.thread_id = th_data.threadId;
|
||||||
|
//execture job. It's the function from BubelECS
|
||||||
job.execute();
|
job.execute();
|
||||||
}
|
}
|
||||||
//atomicOp!"-="(updater.jobs_count,1);
|
|
||||||
//updater.trackers[job_id].end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this is callback passed to EntityManager. EntityManager will call this for every jobs group. Every system will generate one group.
|
||||||
void dispatch(EntityManager.JobGroup group)
|
void dispatch(EntityManager.JobGroup group)
|
||||||
{
|
{
|
||||||
|
//check if group isn't empty
|
||||||
if(group.jobs.length == 0)
|
if(group.jobs.length == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add name for job. Used for traces.
|
||||||
jobs[group.id].name = cast(string)group.caller.system.name;
|
jobs[group.id].name = cast(string)group.caller.system.name;
|
||||||
|
|
||||||
|
//add jobs to group
|
||||||
foreach(ref job;group.jobs)
|
foreach(ref job;group.jobs)
|
||||||
{
|
{
|
||||||
uint index = 0;
|
uint index = 0;
|
||||||
|
|
@ -242,21 +239,51 @@ struct ECSJobUpdater
|
||||||
jobs[group.id].add(caller);
|
jobs[group.id].add(caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//build group
|
||||||
jobs[group.id].build(&pool);
|
jobs[group.id].build(&pool);
|
||||||
|
|
||||||
uint deps = cast(uint)group.dependencies.length;
|
uint deps = cast(uint)group.dependencies.length;
|
||||||
|
|
||||||
|
//add dependencies
|
||||||
foreach(dep;group.dependencies)
|
foreach(dep;group.dependencies)
|
||||||
{
|
{
|
||||||
if(jobs[dep.id].count && dep.caller.system.willExecute && dep.caller.system.enabled)jobs[group.id].dependantOn(&jobs[dep.id]);
|
if(jobs[dep.id].count && dep.caller.system.willExecute && dep.caller.system.enabled)jobs[group.id].dependantOn(&jobs[dep.id]);
|
||||||
else deps--;
|
else deps--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set as job without dependencies if it hasn't any
|
||||||
if(deps == 0)
|
if(deps == 0)
|
||||||
{
|
{
|
||||||
call_jobs.add(&jobs[group.id]);
|
call_jobs.add(&jobs[group.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//last job is dependant on all jobs so it will be called after everything will be finished
|
||||||
last_job.dependantOn(&jobs[group.id]);
|
last_job.dependantOn(&jobs[group.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Webassembly version works properly only when there is no thread local data (static variables).
|
||||||
|
//Because of that I'm using pthread tls instead of D. TLS is used only for storing ThreadID
|
||||||
|
version(WebAssembly)
|
||||||
|
{
|
||||||
|
__gshared pthread_key_t tls_key;
|
||||||
|
}
|
||||||
|
else version(Android)
|
||||||
|
{
|
||||||
|
__gshared pthread_key_t tls_key;
|
||||||
|
}
|
||||||
|
else static uint thread_id = 0;
|
||||||
|
|
||||||
|
//thread pool
|
||||||
|
ThreadPool pool;
|
||||||
|
//thread data used for main thread
|
||||||
|
ThreadData* thread_data;
|
||||||
|
|
||||||
|
//array of jobs
|
||||||
|
Group[] jobs;
|
||||||
|
//list of jobs which should be called on frame start as they have no dependencies
|
||||||
|
Vector!(Group*) call_jobs;
|
||||||
|
//last job group is used for releasing main thread from pool
|
||||||
|
Group last_job;
|
||||||
|
//last_job group has one job
|
||||||
|
JobData[1] groupEndJobs;
|
||||||
}
|
}
|
||||||
|
|
@ -4,17 +4,20 @@ enum GUIColor = "GUIColor";
|
||||||
|
|
||||||
struct GUIRange
|
struct GUIRange
|
||||||
{
|
{
|
||||||
union
|
struct
|
||||||
{
|
{
|
||||||
struct
|
int min;
|
||||||
{
|
int max;
|
||||||
int min;
|
|
||||||
int max;
|
|
||||||
}
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float minf;
|
|
||||||
float maxf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GUIRangeF
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float minf;
|
||||||
|
float maxf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum GUIDisabled = "GUIDisabled";
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ struct VariableGUI
|
||||||
Type type;
|
Type type;
|
||||||
const (char)* name;
|
const (char)* name;
|
||||||
ushort offset;
|
ushort offset;
|
||||||
|
bool disabled = false;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
Int int_;
|
Int int_;
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ struct GUIManager
|
||||||
{
|
{
|
||||||
foreach(tmpl; templates)
|
foreach(tmpl; templates)
|
||||||
{
|
{
|
||||||
launcher.manager.freeTemplate(tmpl.tmpl);
|
gEntityManager.freeTemplate(tmpl.tmpl);
|
||||||
}
|
}
|
||||||
foreach(comp; components)
|
foreach(comp; components)
|
||||||
{
|
{
|
||||||
|
|
@ -102,14 +102,14 @@ struct GUIManager
|
||||||
{
|
{
|
||||||
if(sys.id == id)return;
|
if(sys.id == id)return;
|
||||||
}
|
}
|
||||||
System* system = launcher.manager.getSystem(id);
|
System* system = gEntityManager.getSystem(id);
|
||||||
//const (char)* name =
|
//const (char)* name =
|
||||||
systems.add(SystemGUI(name,id,enabled));
|
systems.add(SystemGUI(name,id,enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTemplate(ushort[] components, const (char)* name)
|
void addTemplate(ushort[] components, const (char)* name)
|
||||||
{
|
{
|
||||||
templates.add(TemplateGUI(name, launcher.manager.allocateTemplate(components)));
|
templates.add(TemplateGUI(name, gEntityManager.allocateTemplate(components)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTemplate(EntityTemplate* tmpl, const (char)* name)
|
void addTemplate(EntityTemplate* tmpl, const (char)* name)
|
||||||
|
|
@ -119,7 +119,7 @@ struct GUIManager
|
||||||
|
|
||||||
// void addComponent(ComponentRef comp, const (char)* name)
|
// void addComponent(ComponentRef comp, const (char)* name)
|
||||||
// {
|
// {
|
||||||
// uint size = EntityManager.instance.components[becsID(comp)].size;
|
// uint size = gEntityManager.components[becsID(comp)].size;
|
||||||
// void* data = malloc(size);
|
// void* data = malloc(size);
|
||||||
// memcpy(data, comp.ptr, size);
|
// memcpy(data, comp.ptr, size);
|
||||||
// components.add(ComponentGUI(name, data, becsID(comp)));
|
// components.add(ComponentGUI(name, data, becsID(comp)));
|
||||||
|
|
@ -127,7 +127,7 @@ struct GUIManager
|
||||||
|
|
||||||
void addComponent(T)(T comp, const (char)* name)
|
void addComponent(T)(T comp, const (char)* name)
|
||||||
{
|
{
|
||||||
uint size = EntityManager.instance.components[becsID(comp)].size;
|
uint size = gEntityManager.components[becsID(comp)].size;
|
||||||
void* data = malloc(size);
|
void* data = malloc(size);
|
||||||
memcpy(data, &comp, size);
|
memcpy(data, &comp, size);
|
||||||
components.add(ComponentGUI(name, data, becsID(comp)));
|
components.add(ComponentGUI(name, data, becsID(comp)));
|
||||||
|
|
@ -152,6 +152,7 @@ struct GUIManager
|
||||||
//pragma(msg,member_type);
|
//pragma(msg,member_type);
|
||||||
//pragma(msg,__traits(getMember, T, member).offsetof);
|
//pragma(msg,__traits(getMember, T, member).offsetof);
|
||||||
ushort offset = member.offsetof;//cast(ushort)__traits(getMember, T, member).offsetof;
|
ushort offset = member.offsetof;//cast(ushort)__traits(getMember, T, member).offsetof;
|
||||||
|
|
||||||
static if(is(member_type == vec2))
|
static if(is(member_type == vec2))
|
||||||
{
|
{
|
||||||
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec2,member_str,offset);
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec2,member_str,offset);
|
||||||
|
|
@ -236,14 +237,20 @@ struct GUIManager
|
||||||
}
|
}
|
||||||
static if(hasUDA!(member,GUIRange))
|
static if(hasUDA!(member,GUIRange))
|
||||||
{
|
{
|
||||||
comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRange)[0].minf;
|
comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRange)[0].min;
|
||||||
comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRange)[1].maxf;
|
comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRange)[0].max;
|
||||||
}
|
}
|
||||||
|
else static if(hasUDA!(member,GUIRangeF))
|
||||||
{
|
{
|
||||||
|
comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRangeF)[0].minf;
|
||||||
|
comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRangeF)[0].maxf;
|
||||||
|
}
|
||||||
|
else {
|
||||||
comp_edit.variables[comp_edit.used-1].float_.min = -float.max;
|
comp_edit.variables[comp_edit.used-1].float_.min = -float.max;
|
||||||
comp_edit.variables[comp_edit.used-1].float_.max = float.max;
|
comp_edit.variables[comp_edit.used-1].float_.max = float.max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static if(hasUDA!(member,GUIDisabled))comp_edit.variables[comp_edit.used - 1].disabled = true;
|
||||||
}
|
}
|
||||||
edit_components[becsID(comp)] = comp_edit;
|
edit_components[becsID(comp)] = comp_edit;
|
||||||
}
|
}
|
||||||
|
|
@ -256,12 +263,14 @@ struct GUIManager
|
||||||
igIndent(8);
|
igIndent(8);
|
||||||
foreach(ref SystemGUI system;systems)
|
foreach(ref SystemGUI system;systems)
|
||||||
{
|
{
|
||||||
|
igPushIDPtr(&system);
|
||||||
if(igCheckbox(system.name,&system.enabled))
|
if(igCheckbox(system.name,&system.enabled))
|
||||||
{
|
{
|
||||||
System* sys = launcher.manager.getSystem(system.id);
|
System* sys = gEntityManager.getSystem(system.id);
|
||||||
if(system.enabled)sys.enable();
|
if(system.enabled)sys.enable();
|
||||||
else sys.disable();
|
else sys.disable();
|
||||||
}
|
}
|
||||||
|
igPopID();
|
||||||
}
|
}
|
||||||
igUnindent(8);
|
igUnindent(8);
|
||||||
}
|
}
|
||||||
|
|
@ -337,13 +346,15 @@ struct GUIManager
|
||||||
{
|
{
|
||||||
vec4 color;
|
vec4 color;
|
||||||
if(comp_id >= edit_components.length)return;
|
if(comp_id >= edit_components.length)return;
|
||||||
if(edit_components[comp_id].used)
|
//if(edit_components[comp_id].used)
|
||||||
|
if(edit_components[comp_id].name)
|
||||||
{
|
{
|
||||||
if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen))
|
if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
igIndent(8);
|
igIndent(8);
|
||||||
foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used])
|
foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used])
|
||||||
{
|
{
|
||||||
|
|
||||||
igPushIDPtr(&var);
|
igPushIDPtr(&var);
|
||||||
switch(var.type)
|
switch(var.type)
|
||||||
{
|
{
|
||||||
|
|
@ -351,7 +362,12 @@ struct GUIManager
|
||||||
igDragScalarClamp(var.name, ImGuiDataType_S8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
igDragScalarClamp(var.name, ImGuiDataType_S8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
break;
|
break;
|
||||||
case VariableGUI.Type.ubyte_:
|
case VariableGUI.Type.ubyte_:
|
||||||
igDragScalarClamp(var.name, ImGuiDataType_U8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
if(var.disabled)
|
||||||
|
{
|
||||||
|
ubyte v = *cast(ubyte*)(data_ptr+var.offset);
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_U8, &v, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
}
|
||||||
|
else igDragScalarClamp(var.name, ImGuiDataType_U8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
break;
|
break;
|
||||||
case VariableGUI.Type.short_:
|
case VariableGUI.Type.short_:
|
||||||
igDragScalarClamp(var.name, ImGuiDataType_S16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
igDragScalarClamp(var.name, ImGuiDataType_S16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
|
@ -363,7 +379,12 @@ struct GUIManager
|
||||||
igDragScalarClamp(var.name, ImGuiDataType_S32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
igDragScalarClamp(var.name, ImGuiDataType_S32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
break;
|
break;
|
||||||
case VariableGUI.Type.uint_:
|
case VariableGUI.Type.uint_:
|
||||||
igDragScalarClamp(var.name, ImGuiDataType_U32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
if(var.disabled)
|
||||||
|
{
|
||||||
|
uint v = *cast(uint*)(data_ptr+var.offset);
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_U32, &v, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
}
|
||||||
|
else igDragScalarClamp(var.name, ImGuiDataType_U32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
break;
|
break;
|
||||||
case VariableGUI.Type.float_:
|
case VariableGUI.Type.float_:
|
||||||
igDragScalarClamp(var.name, ImGuiDataType_Float, data_ptr+var.offset, 0.1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, "%2.2f", 1);
|
igDragScalarClamp(var.name, ImGuiDataType_Float, data_ptr+var.offset, 0.1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, "%2.2f", 1);
|
||||||
|
|
@ -472,7 +493,7 @@ struct GUIManager
|
||||||
break;
|
break;
|
||||||
case Tool.selector:
|
case Tool.selector:
|
||||||
{
|
{
|
||||||
Entity* entity = gEM.getEntity(launcher.selected_entity);
|
Entity* entity = gEntityManager.getEntity(launcher.selected_entity);
|
||||||
style.Colors[ImGuiCol_Header] = col;
|
style.Colors[ImGuiCol_Header] = col;
|
||||||
entityComponentsGUI(entity);
|
entityComponentsGUI(entity);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
"subConfigurations":
|
"subConfigurations":
|
||||||
{
|
{
|
||||||
"bindbc-sdl": "static",
|
"bindbc-sdl": "static",
|
||||||
"ecs":"library"
|
"bubel_ecs":"library"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
"subConfigurations":
|
"subConfigurations":
|
||||||
{
|
{
|
||||||
"bindbc-sdl": "staticBC",
|
"bindbc-sdl": "staticBC",
|
||||||
"ecs":"library-betterC"
|
"bubel_ecs":"library-betterC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -448,6 +448,7 @@ struct Renderer
|
||||||
void draw(scope ref const(DrawData) data)
|
void draw(scope ref const(DrawData) data)
|
||||||
{
|
{
|
||||||
if(prepared_items >= MaxObjects)return;
|
if(prepared_items >= MaxObjects)return;
|
||||||
|
if(threads[data.thread_id].blocks.length <= data.material_id)return;
|
||||||
__draw(this,data);//tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id);
|
__draw(this,data);//tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
dub.json
9
dub.json
|
|
@ -50,8 +50,7 @@
|
||||||
],
|
],
|
||||||
"dflags": [
|
"dflags": [
|
||||||
"-unittest"
|
"-unittest"
|
||||||
],
|
]
|
||||||
"targetName" : "ecs"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "unittest-runner-cov",
|
"name": "unittest-runner-cov",
|
||||||
|
|
@ -65,8 +64,7 @@
|
||||||
"dflags": [
|
"dflags": [
|
||||||
"-unittest",
|
"-unittest",
|
||||||
"-cov"
|
"-cov"
|
||||||
],
|
]
|
||||||
"targetName" : "ecs"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "library-betterC",
|
"name" : "library-betterC",
|
||||||
|
|
@ -129,8 +127,7 @@
|
||||||
"excludedSourceFiles":[
|
"excludedSourceFiles":[
|
||||||
"source\/win_dll.d",
|
"source\/win_dll.d",
|
||||||
"tests/tests.d"
|
"tests/tests.d"
|
||||||
],
|
]
|
||||||
"targetName" : "ecs"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -3,10 +3,12 @@ project('decs', 'd', version : '0.5.0')
|
||||||
# Options
|
# Options
|
||||||
betterC_opt = get_option('betterC')
|
betterC_opt = get_option('betterC')
|
||||||
BuildDemos_opt = get_option('BuildDemos')
|
BuildDemos_opt = get_option('BuildDemos')
|
||||||
|
BuildTests_opt = get_option('BuildTests')
|
||||||
LTO_otp = get_option('LTO')
|
LTO_otp = get_option('LTO')
|
||||||
|
|
||||||
summary('betterC enabled', betterC_opt)
|
summary('betterC enabled', betterC_opt)
|
||||||
summary('build demos', BuildDemos_opt)
|
summary('build demos', BuildDemos_opt)
|
||||||
|
summary('build tests', BuildTests_opt)
|
||||||
summary('LTO enabled', LTO_otp)
|
summary('LTO enabled', LTO_otp)
|
||||||
|
|
||||||
meson_minimum_version = '>=0.57.1'
|
meson_minimum_version = '>=0.57.1'
|
||||||
|
|
@ -71,7 +73,9 @@ decs_dep = declare_dependency(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
subdir('tests')
|
if BuildTests_opt
|
||||||
|
subdir('tests')
|
||||||
|
endif
|
||||||
|
|
||||||
# Demos
|
# Demos
|
||||||
if BuildDemos_opt
|
if BuildDemos_opt
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
option('betterC', type: 'boolean', value: false)
|
option('betterC', type: 'boolean', value: false)
|
||||||
option('BuildDemos', type: 'boolean', value: false)
|
option('BuildDemos', type: 'boolean', value: false)
|
||||||
|
option('BuildTests', type: 'boolean', value: false)
|
||||||
option('LTO', type: 'boolean', value: false)
|
option('LTO', type: 'boolean', value: false)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ $(LIST
|
||||||
* Component: make component structure
|
* Component: make component structure
|
||||||
* Event: make event structure
|
* Event: make event structure
|
||||||
)
|
)
|
||||||
|
This mixins are optional and are used to adding some additional capabilities, e.g. ECS.System is used to configuring default number of jobs for system.
|
||||||
|
|
||||||
---
|
---
|
||||||
Struct System1
|
Struct System1
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ struct Entity
|
||||||
*/
|
*/
|
||||||
T* getComponent(T)() const
|
T* getComponent(T)() const
|
||||||
{
|
{
|
||||||
/*EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
/*EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(&this);
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -46,17 +46,17 @@ struct Entity
|
||||||
|
|
||||||
void* getComponent(ushort component_id) const
|
void* getComponent(ushort component_id) const
|
||||||
{
|
{
|
||||||
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(&this);
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)
|
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return (cast(void*)block + info.deltas[component_id] + block.entityIndex(&this) * gEM.components[component_id].size);
|
return (cast(void*)block + info.deltas[component_id] + block.entityIndex(&this) * gEntityManager.components[component_id].size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasComponent(ushort component_id) const
|
bool hasComponent(ushort component_id) const
|
||||||
{
|
{
|
||||||
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(&this);
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false;
|
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -65,7 +65,7 @@ struct Entity
|
||||||
EntityMeta getMeta() const
|
EntityMeta getMeta() const
|
||||||
{
|
{
|
||||||
EntityMeta meta;
|
EntityMeta meta;
|
||||||
meta.block = gEM.getMetaData(&this);
|
meta.block = gEntityManager.getMetaData(&this);
|
||||||
meta.index = meta.block.entityIndex(&this);
|
meta.index = meta.block.entityIndex(&this);
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ struct EntityMeta
|
||||||
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)
|
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return (cast(void*)block + info.deltas[component_id] + index * gEM.components[component_id].size);
|
return (cast(void*)block + info.deltas[component_id] + index * gEntityManager.components[component_id].size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasComponent(ushort component_id) const
|
bool hasComponent(ushort component_id) const
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,11 @@ import bubel.ecs.traits;
|
||||||
import bubel.ecs.vector;
|
import bubel.ecs.vector;
|
||||||
import bubel.ecs.atomic;
|
import bubel.ecs.atomic;
|
||||||
|
|
||||||
export alias gEM = EntityManager.instance;
|
|
||||||
export alias gEntityManager = EntityManager.instance;
|
|
||||||
alias SerializeVector = bubel.ecs.vector.Vector!ubyte;
|
alias SerializeVector = bubel.ecs.vector.Vector!ubyte;
|
||||||
|
|
||||||
|
///Global EntityManager used for everything.
|
||||||
|
export __gshared EntityManager* gEntityManager = null;
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
Entity manager is responsible for everything.
|
Entity manager is responsible for everything.
|
||||||
|
|
||||||
|
|
@ -40,7 +41,7 @@ Entity manager can be in three states:
|
||||||
|
|
||||||
Manager can be only in one state simultaneously.
|
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.
|
Manager must be initialized before use. There is global instance of EntityManager: gEntityManager or gEntityManager as alias.
|
||||||
|
|
||||||
Registration process consist of registration of passes, systems, entities and events.
|
Registration process consist of registration of passes, systems, entities and events.
|
||||||
|
|
||||||
|
|
@ -58,21 +59,24 @@ grouped by component type so entity can be fracted in big memory chunk.
|
||||||
There is two types of update:
|
There is two types of update:
|
||||||
- update(): function used to call update pass.
|
- 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.
|
- updateMT(): function used to call update pass multithreaded. This call only generates jobs which must be called by user.
|
||||||
|
|
||||||
|
WARNING! No fileds from EntityManager should be used directly, they are not private for special, advanced things which are not implemented in library.
|
||||||
|
So if you don't need anything special, simply use only EntityManager methods.
|
||||||
*/
|
*/
|
||||||
export struct EntityManager
|
export struct EntityManager
|
||||||
{
|
{
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
Initialize ECS.
|
Initialize ECS.
|
||||||
*/
|
*/
|
||||||
export static void initialize(uint threads_count, uint page_size = 32768,
|
export static void initialize(uint threads_count = 1, uint page_size = 32768,
|
||||||
uint block_pages_count = 128)
|
uint block_pages_count = 128)
|
||||||
{
|
{
|
||||||
if (instance is null)
|
if (gEntityManager is null)
|
||||||
{
|
{
|
||||||
//instance = Mallocator.make!EntityManager(threads_count);
|
//gEntityManager = Mallocator.make!EntityManager(threads_count);
|
||||||
instance = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count);
|
gEntityManager = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count);
|
||||||
|
|
||||||
with (instance)
|
with (gEntityManager)
|
||||||
{
|
{
|
||||||
UpdatePass* pass = Mallocator.make!UpdatePass;
|
UpdatePass* pass = Mallocator.make!UpdatePass;
|
||||||
pass.name = Mallocator.makeArray(cast(char[]) "update");
|
pass.name = Mallocator.makeArray(cast(char[]) "update");
|
||||||
|
|
@ -89,10 +93,10 @@ export struct EntityManager
|
||||||
*/
|
*/
|
||||||
export static void destroy()
|
export static void destroy()
|
||||||
{
|
{
|
||||||
if (instance is null)
|
if (gEntityManager is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
with (instance)
|
with (gEntityManager)
|
||||||
{
|
{
|
||||||
foreach (ref system; systems)
|
foreach (ref system; systems)
|
||||||
{
|
{
|
||||||
|
|
@ -131,8 +135,8 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mallocator.dispose(instance);
|
Mallocator.dispose(gEntityManager);
|
||||||
instance = null;
|
gEntityManager = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
|
|
@ -1610,11 +1614,6 @@ export struct EntityManager
|
||||||
m_thread_id_func = cast(uint delegate() nothrow @nogc) get_id_callback;
|
m_thread_id_func = cast(uint delegate() nothrow @nogc) get_id_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*export void setJobDispachFunc(void delegate(JobGroup) @nogc nothrow func) nothrow @nogc
|
|
||||||
{
|
|
||||||
m_dispatch_jobs = func;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
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.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1904,8 +1903,8 @@ export struct EntityManager
|
||||||
addSystemCaller(*info, cast(uint) i);
|
addSystemCaller(*info, cast(uint) i);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length);
|
info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(gEntityManager.components.length);
|
||||||
//info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length);
|
//info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(gEntityManager.components.length);
|
||||||
info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
|
info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
|
||||||
|
|
||||||
foreach (comp; info.components)
|
foreach (comp; info.components)
|
||||||
|
|
@ -3406,7 +3405,7 @@ export struct EntityManager
|
||||||
if (comp_add_info.length <= id)
|
if (comp_add_info.length <= id)
|
||||||
{
|
{
|
||||||
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(
|
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(
|
||||||
instance.components.length);
|
gEntityManager.components.length);
|
||||||
if (comp_add_info !is null)
|
if (comp_add_info !is null)
|
||||||
{
|
{
|
||||||
//new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $];
|
//new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $];
|
||||||
|
|
@ -3445,7 +3444,7 @@ export struct EntityManager
|
||||||
|
|
||||||
assert(len == components.length + 1);
|
assert(len == components.length + 1);
|
||||||
|
|
||||||
EntityInfo* new_info = instance.getEntityInfo(ids);
|
EntityInfo* new_info = gEntityManager.getEntityInfo(ids);
|
||||||
|
|
||||||
comp_add_info[id] = new_info;
|
comp_add_info[id] = new_info;
|
||||||
return new_info;
|
return new_info;
|
||||||
|
|
@ -3456,7 +3455,7 @@ export struct EntityManager
|
||||||
/*if (comp_rem_info.length <= id)
|
/*if (comp_rem_info.length <= id)
|
||||||
{
|
{
|
||||||
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(
|
EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(
|
||||||
instance.components.length, &this);
|
gEntityManager.components.length, &this);
|
||||||
if (comp_rem_info !is null)
|
if (comp_rem_info !is null)
|
||||||
{
|
{
|
||||||
//new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $];
|
//new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $];
|
||||||
|
|
@ -3486,7 +3485,7 @@ export struct EntityManager
|
||||||
|
|
||||||
assert(len == components.length - 1);
|
assert(len == components.length - 1);
|
||||||
|
|
||||||
EntityInfo* new_info = instance.getEntityInfo(ids[0 .. len]);
|
EntityInfo* new_info = gEntityManager.getEntityInfo(ids[0 .. len]);
|
||||||
|
|
||||||
comp_rem_info[id] = new_info;
|
comp_rem_info[id] = new_info;
|
||||||
return new_info;
|
return new_info;
|
||||||
|
|
@ -3646,10 +3645,10 @@ export struct EntityManager
|
||||||
|
|
||||||
export void execute() nothrow @nogc
|
export void execute() nothrow @nogc
|
||||||
{
|
{
|
||||||
//EntityManager.instance.getThreadID();
|
//gEntityManager.getThreadID();
|
||||||
foreach (ref caller; callers)
|
foreach (ref caller; callers)
|
||||||
{
|
{
|
||||||
caller.thread_id = EntityManager.instance.threadID();
|
caller.thread_id = gEntityManager.threadID();
|
||||||
caller.job_id = id;
|
caller.job_id = id;
|
||||||
caller.update();
|
caller.update();
|
||||||
}
|
}
|
||||||
|
|
@ -3761,20 +3760,6 @@ export struct EntityManager
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*uint thread_id() @nogc nothrow
|
|
||||||
{
|
|
||||||
if (m_thread_id_func)
|
|
||||||
return (cast(uint delegate() nothrow @nogc) m_thread_id_func)();
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void thread_id(uint) @nogc nothrow
|
|
||||||
{
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//static uint thread_id;
|
|
||||||
|
|
||||||
ThreadData[] threads;
|
ThreadData[] threads;
|
||||||
|
|
||||||
Vector!(UpdatePass*) passes;
|
Vector!(UpdatePass*) passes;
|
||||||
|
|
@ -3867,5 +3852,4 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export __gshared EntityManager* instance = null;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,26 +54,26 @@ EntityTemplate* tmpl;
|
||||||
|
|
||||||
void beforeEveryTest()
|
void beforeEveryTest()
|
||||||
{
|
{
|
||||||
gEM.initialize(0);
|
gEntityManager.initialize(0);
|
||||||
|
|
||||||
gEM.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
gEM.registerComponent!CLong;
|
gEntityManager.registerComponent!CLong;
|
||||||
gEM.registerComponent!CInt;
|
gEntityManager.registerComponent!CInt;
|
||||||
gEM.registerComponent!CUInt;
|
gEntityManager.registerComponent!CUInt;
|
||||||
gEM.registerComponent!CBig;
|
gEntityManager.registerComponent!CBig;
|
||||||
|
|
||||||
gEM.endRegister();
|
gEntityManager.endRegister();
|
||||||
|
|
||||||
tmpl = gEM.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray);
|
||||||
foreach(i; 0 .. 100_000)gEM.addEntity(tmpl);
|
foreach(i; 0 .. 100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void afterEveryTest()
|
void afterEveryTest()
|
||||||
{
|
{
|
||||||
if(tmpl)gEM.freeTemplate(tmpl);
|
if(tmpl)gEntityManager.freeTemplate(tmpl);
|
||||||
tmpl = null;
|
tmpl = null;
|
||||||
gEM.destroy();
|
gEntityManager.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@("DirectAccess100k1comp")
|
@("DirectAccess100k1comp")
|
||||||
|
|
@ -81,7 +81,7 @@ unittest
|
||||||
{
|
{
|
||||||
foreach(i;0..25000)
|
foreach(i;0..25000)
|
||||||
{
|
{
|
||||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0));
|
||||||
CUInt* comp1 = entity.getComponent!CUInt;
|
CUInt* comp1 = entity.getComponent!CUInt;
|
||||||
comp1.value = 4;
|
comp1.value = 4;
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ unittest
|
||||||
{
|
{
|
||||||
foreach(i;0..25000)
|
foreach(i;0..25000)
|
||||||
{
|
{
|
||||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0));
|
||||||
CUInt* comp1 = entity.getComponent!CUInt;
|
CUInt* comp1 = entity.getComponent!CUInt;
|
||||||
comp1.value = 4;
|
comp1.value = 4;
|
||||||
CInt* comp2 = entity.getComponent!CInt;
|
CInt* comp2 = entity.getComponent!CInt;
|
||||||
|
|
@ -109,7 +109,7 @@ unittest
|
||||||
{
|
{
|
||||||
foreach(i;0..25000)
|
foreach(i;0..25000)
|
||||||
{
|
{
|
||||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0));
|
||||||
EntityMeta meta = entity.getMeta();
|
EntityMeta meta = entity.getMeta();
|
||||||
CUInt* comp1 = meta.getComponent!CUInt;
|
CUInt* comp1 = meta.getComponent!CUInt;
|
||||||
comp1.value = 4;
|
comp1.value = 4;
|
||||||
|
|
@ -121,7 +121,7 @@ unittest
|
||||||
{
|
{
|
||||||
foreach(i;0..25000)
|
foreach(i;0..25000)
|
||||||
{
|
{
|
||||||
Entity* entity = gEM.getEntity(EntityID(i*4+1,0));
|
Entity* entity = gEntityManager.getEntity(EntityID(i*4+1,0));
|
||||||
EntityMeta meta = entity.getMeta();
|
EntityMeta meta = entity.getMeta();
|
||||||
CUInt* comp1 = meta.getComponent!CUInt;
|
CUInt* comp1 = meta.getComponent!CUInt;
|
||||||
comp1.value = 4;
|
comp1.value = 4;
|
||||||
|
|
|
||||||
660
tests/basic.d
660
tests/basic.d
File diff suppressed because it is too large
Load diff
70
tests/bugs.d
70
tests/bugs.d
|
|
@ -45,23 +45,23 @@ unittest
|
||||||
|
|
||||||
void onCreate()
|
void onCreate()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CInt, becsID!CLong].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDestroy()
|
void onDestroy()
|
||||||
{
|
{
|
||||||
gEM.freeTemplate(tmpl);
|
gEntityManager.freeTemplate(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleEvent(Entity* entity, Event1 event)
|
void handleEvent(Entity* entity, Event1 event)
|
||||||
{
|
{
|
||||||
gEM.removeEntity(event.id);
|
gEntityManager.removeEntity(event.id);
|
||||||
gEM.sendEvent(entity.id,Event2());
|
gEntityManager.sendEvent(entity.id,Event2());
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleEvent(Entity* entity, Event2 event)
|
void handleEvent(Entity* entity, Event2 event)
|
||||||
{
|
{
|
||||||
id = gEM.addEntity(tmpl).id;
|
id = gEntityManager.addEntity(tmpl).id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,49 +94,49 @@ unittest
|
||||||
///remove every entity
|
///remove every entity
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)gEM.removeEntity(data.entity[i].id);
|
foreach(i;0..data.length)gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gEM.initialize(0);
|
gEntityManager.initialize(0);
|
||||||
|
|
||||||
gEM.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
gEM.registerComponent!CInt;
|
gEntityManager.registerComponent!CInt;
|
||||||
gEM.registerComponent!CFloat;
|
gEntityManager.registerComponent!CFloat;
|
||||||
gEM.registerComponent!CDouble;
|
gEntityManager.registerComponent!CDouble;
|
||||||
gEM.registerComponent!CLong;
|
gEntityManager.registerComponent!CLong;
|
||||||
gEM.registerComponent!CShort;
|
gEntityManager.registerComponent!CShort;
|
||||||
gEM.registerComponent!CFlag;
|
gEntityManager.registerComponent!CFlag;
|
||||||
|
|
||||||
gEM.registerEvent!Event1;
|
gEntityManager.registerEvent!Event1;
|
||||||
gEM.registerEvent!Event2;
|
gEntityManager.registerEvent!Event2;
|
||||||
|
|
||||||
gEM.registerSystem!System1(0);
|
gEntityManager.registerSystem!System1(0);
|
||||||
gEM.registerSystem!System2(-200);
|
gEntityManager.registerSystem!System2(-200);
|
||||||
gEM.registerSystem!System3(-200);
|
gEntityManager.registerSystem!System3(-200);
|
||||||
|
|
||||||
gEM.endRegister();
|
gEntityManager.endRegister();
|
||||||
|
|
||||||
EntityTemplate* tmpl = gEM.allocateTemplate([becsID!CInt, becsID!CLong].staticArray);
|
EntityTemplate* tmpl = gEntityManager.allocateTemplate([becsID!CInt, becsID!CLong].staticArray);
|
||||||
EntityID id = gEM.addEntity(tmpl,[CLong(10).ref_, CInt(6).ref_].staticArray).id;
|
EntityID id = gEntityManager.addEntity(tmpl,[CLong(10).ref_, CInt(6).ref_].staticArray).id;
|
||||||
EntityID id2 = gEM.addEntity(tmpl,[CInt(4).ref_].staticArray).id;
|
EntityID id2 = gEntityManager.addEntity(tmpl,[CInt(4).ref_].staticArray).id;
|
||||||
gEM.freeTemplate(tmpl);
|
gEntityManager.freeTemplate(tmpl);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
gEM.sendEvent(id2, Event1(id));
|
gEntityManager.sendEvent(id2, Event1(id));
|
||||||
|
|
||||||
gEM.getSystem(becsID!System2).disable();
|
gEntityManager.getSystem(becsID!System2).disable();
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
gEM.getSystem(becsID!System2).enable();
|
gEntityManager.getSystem(becsID!System2).enable();
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
gEM.destroy();
|
gEntityManager.destroy();
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
tests_src = files(
|
tests_src = files(
|
||||||
'tests.d',
|
'access_perf.d',
|
||||||
|
'basic.d',
|
||||||
|
'bugs.d',
|
||||||
|
'id_manager.d',
|
||||||
|
'map.d',
|
||||||
|
'perf.d',
|
||||||
|
'runner.d',
|
||||||
|
'time.d',
|
||||||
|
'vector.d'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if host_machine.cpu_family() != 'wasm32'
|
if host_machine.cpu_family() != 'wasm32'
|
||||||
exe = executable('decs-tests', tests_src,
|
exe = executable('decs-tests', tests_src,
|
||||||
include_directories : [inc],
|
include_directories : [inc, '..'],
|
||||||
dependencies : decs_dep,
|
dependencies : decs_dep,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
60
tests/perf.d
60
tests/perf.d
|
|
@ -63,123 +63,123 @@ EntityTemplate* tmpl;
|
||||||
|
|
||||||
void beforeEveryTest()
|
void beforeEveryTest()
|
||||||
{
|
{
|
||||||
gEM.initialize(0);
|
gEntityManager.initialize(0);
|
||||||
|
|
||||||
gEM.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
|
|
||||||
gEM.registerComponent!CLong;
|
gEntityManager.registerComponent!CLong;
|
||||||
gEM.registerComponent!CShort;
|
gEntityManager.registerComponent!CShort;
|
||||||
gEM.registerComponent!CInt;
|
gEntityManager.registerComponent!CInt;
|
||||||
gEM.registerComponent!CUInt;
|
gEntityManager.registerComponent!CUInt;
|
||||||
gEM.registerComponent!CBig;
|
gEntityManager.registerComponent!CBig;
|
||||||
|
|
||||||
gEM.endRegister();
|
gEntityManager.endRegister();
|
||||||
tmpl = null;
|
tmpl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void afterEveryTest()
|
void afterEveryTest()
|
||||||
{
|
{
|
||||||
if(tmpl)gEM.freeTemplate(tmpl);
|
if(tmpl)gEntityManager.freeTemplate(tmpl);
|
||||||
tmpl = null;
|
tmpl = null;
|
||||||
gEM.destroy();
|
gEntityManager.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void smallTmpl()
|
void smallTmpl()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CShort].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CShort].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bigTmpl()
|
void bigTmpl()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CBig].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CBig].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiSmallTmpl()
|
void multiSmallTmpl()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CShort, becsID!CLong, becsID!CInt, becsID!CUInt].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CShort, becsID!CLong, becsID!CInt, becsID!CUInt].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiBigTmpl()
|
void multiBigTmpl()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k1comp2b") @(before, &smallTmpl)
|
@("AddEntities100k1comp2b") @(before, &smallTmpl)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k1comp128b") @(before, &bigTmpl)
|
@("AddEntities100k1comp128b") @(before, &bigTmpl)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k4comp18b") @(before, &multiSmallTmpl)
|
@("AddEntities100k4comp18b") @(before, &multiSmallTmpl)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k4comp144b") @(before, &multiBigTmpl)
|
@("AddEntities100k4comp144b") @(before, &multiBigTmpl)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allocDealloc100k()
|
void allocDealloc100k()
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
foreach(i; 0..100_000)gEM.removeEntity(EntityID(i + 1,0));
|
foreach(i; 0..100_000)gEntityManager.removeEntity(EntityID(i + 1,0));
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void smallTmplPreAlloc()
|
void smallTmplPreAlloc()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CShort].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CShort].staticArray);
|
||||||
allocDealloc100k();
|
allocDealloc100k();
|
||||||
}
|
}
|
||||||
|
|
||||||
void bigTmplPreAlloc()
|
void bigTmplPreAlloc()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CBig].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CBig].staticArray);
|
||||||
allocDealloc100k();
|
allocDealloc100k();
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiSmallTmplPreAlloc()
|
void multiSmallTmplPreAlloc()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CShort, becsID!CLong, becsID!CInt, becsID!CUInt].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CShort, becsID!CLong, becsID!CInt, becsID!CUInt].staticArray);
|
||||||
allocDealloc100k();
|
allocDealloc100k();
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiBigTmplPreAlloc()
|
void multiBigTmplPreAlloc()
|
||||||
{
|
{
|
||||||
tmpl = gEM.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray);
|
tmpl = gEntityManager.allocateTemplate([becsID!CLong, becsID!CInt, becsID!CUInt, becsID!CBig].staticArray);
|
||||||
allocDealloc100k();
|
allocDealloc100k();
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k1comp2bPreAlloc") @(before, &smallTmplPreAlloc)
|
@("AddEntities100k1comp2bPreAlloc") @(before, &smallTmplPreAlloc)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k1comp128bPreAlloc") @(before, &bigTmplPreAlloc)
|
@("AddEntities100k1comp128bPreAlloc") @(before, &bigTmplPreAlloc)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k4comp18bPreAlloc") @(before, &multiSmallTmplPreAlloc)
|
@("AddEntities100k4comp18bPreAlloc") @(before, &multiSmallTmplPreAlloc)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("AddEntities100k4comp144bPreAlloc") @(before, &multiBigTmplPreAlloc)
|
@("AddEntities100k4comp144bPreAlloc") @(before, &multiBigTmplPreAlloc)
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
foreach(i; 0..100_000)gEM.addEntity(tmpl);
|
foreach(i; 0..100_000)gEntityManager.addEntity(tmpl);
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ module tests.runner;
|
||||||
|
|
||||||
import core.stdc.stdio;
|
import core.stdc.stdio;
|
||||||
import core.stdc.string;
|
import core.stdc.string;
|
||||||
import core.sys.posix.setjmp;
|
|
||||||
|
|
||||||
import bubel.ecs.vector;
|
import bubel.ecs.vector;
|
||||||
import bubel.ecs.simple_vector;
|
import bubel.ecs.simple_vector;
|
||||||
|
|
@ -25,11 +24,36 @@ else
|
||||||
enum int ASSERTED = 123;
|
enum int ASSERTED = 123;
|
||||||
enum string OUT_FILE = "test_report.xml";
|
enum string OUT_FILE = "test_report.xml";
|
||||||
|
|
||||||
static jmp_buf gEnvBuffer;
|
|
||||||
static AssertInfo gAssertInfo;
|
|
||||||
|
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
{
|
{
|
||||||
|
version(Posix)
|
||||||
|
{
|
||||||
|
import core.sys.posix.setjmp;
|
||||||
|
}
|
||||||
|
else version(Windows)
|
||||||
|
{
|
||||||
|
version(X86)
|
||||||
|
alias jmp_buf = ubyte[64];
|
||||||
|
else version(X86_64)
|
||||||
|
alias jmp_buf = ubyte[256];
|
||||||
|
else version(IA64)
|
||||||
|
alias jmp_buf = ubyte[512];
|
||||||
|
|
||||||
|
extern (C) {
|
||||||
|
int _setjmp(ref jmp_buf);
|
||||||
|
void longjmp(ref jmp_buf, int);
|
||||||
|
}
|
||||||
|
alias setjmp = _setjmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static jmp_buf gEnvBuffer;
|
||||||
|
static AssertInfo gAssertInfo;
|
||||||
|
|
||||||
|
extern (C) void __assert(const char* msg, const char* file, int line)
|
||||||
|
{
|
||||||
|
gAssertInfo = AssertInfo(msg, file, line);
|
||||||
|
longjmp(gEnvBuffer, ASSERTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else version = notBetterC;
|
else version = notBetterC;
|
||||||
|
|
||||||
|
|
@ -40,12 +64,6 @@ struct AssertInfo
|
||||||
int line;
|
int line;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern (C) void __assert(const char* msg, const char* file, int line)
|
|
||||||
{
|
|
||||||
gAssertInfo = AssertInfo(msg, file, line);
|
|
||||||
longjmp(gEnvBuffer, ASSERTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Test
|
struct Test
|
||||||
{
|
{
|
||||||
string file;
|
string file;
|
||||||
|
|
@ -427,6 +445,13 @@ extern (C) int main(int argc, char** args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static import tests.id_manager;
|
||||||
|
static import tests.vector;
|
||||||
|
static import tests.basic;
|
||||||
|
static import tests.perf;
|
||||||
|
static import tests.access_perf;
|
||||||
|
static import tests.bugs;
|
||||||
|
static import tests.map;
|
||||||
TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs, tests.map) runner;
|
TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs, tests.map) runner;
|
||||||
|
|
||||||
runner.runTests(include[], exclude[]);
|
runner.runTests(include[], exclude[]);
|
||||||
|
|
|
||||||
280
tests/tests.d
280
tests/tests.d
|
|
@ -226,7 +226,7 @@ struct EverySystem
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
gEM.removeEntity(data.entity[i].id);
|
gEntityManager.removeEntity(data.entity[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,7 +234,7 @@ struct EverySystem
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
gEM.addComponents(data.entity[i].id, TestComp2());
|
gEntityManager.addComponents(data.entity[i].id, TestComp2());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -566,7 +566,7 @@ struct TestSystem2
|
||||||
test.bg = event.a;
|
test.bg = event.a;
|
||||||
TestEvent2 event2;
|
TestEvent2 event2;
|
||||||
event2.a = event.a + 8;
|
event2.a = event.a + 8;
|
||||||
gEM.sendEvent(entity.id, event2);
|
gEntityManager.sendEvent(entity.id, event2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleEvent(Entity* entity, TestEvent2 event)
|
void handleEvent(Entity* entity, TestEvent2 event)
|
||||||
|
|
@ -601,12 +601,12 @@ struct TestSystem2
|
||||||
data.test[i].gg += 14;
|
data.test[i].gg += 14;
|
||||||
TestEvent event;
|
TestEvent event;
|
||||||
event.a = data.test[i].gg + 4;
|
event.a = data.test[i].gg + 4;
|
||||||
gEM.sendEvent(data.entity[i].id, event); //*/
|
gEntityManager.sendEvent(data.entity[i].id, event); //*/
|
||||||
/*TestEvent2 event2;
|
/*TestEvent2 event2;
|
||||||
event2.a = data.test[i].gg + 8;
|
event2.a = data.test[i].gg + 8;
|
||||||
gEM.sendEvent(data.entity[i].id, event2);//*/
|
gEntityManager.sendEvent(data.entity[i].id, event2);//*/
|
||||||
//gEM.sendEvent!(TestEvent)(data.entity[i].id, event);
|
//gEntityManager.sendEvent!(TestEvent)(data.entity[i].id, event);
|
||||||
//gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent());
|
//gEntityManager.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,7 +615,7 @@ struct TestSystem2
|
||||||
foreach (i; 0 .. data.test.length)
|
foreach (i; 0 .. data.test.length)
|
||||||
{
|
{
|
||||||
data.test[i].gg -= 1;
|
data.test[i].gg -= 1;
|
||||||
//gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent());
|
//gEntityManager.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -686,25 +686,25 @@ else:
|
||||||
|
|
||||||
EntityManager.initialize(1);
|
EntityManager.initialize(1);
|
||||||
|
|
||||||
//gEM.setJobDispachFunc(&dispatch);
|
//gEntityManager.setJobDispachFunc(&dispatch);
|
||||||
gEM.setMultithreadingCallbacks(&dispatch, &getID);
|
gEntityManager.setMultithreadingCallbacks(&dispatch, &getID);
|
||||||
//assert(gEM !is null);
|
//assert(gEntityManager !is null);
|
||||||
|
|
||||||
gEM.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
gEM.registerPass("fixed");
|
gEntityManager.registerPass("fixed");
|
||||||
|
|
||||||
//MonoTime time = MonoTime.currTime;
|
//MonoTime time = MonoTime.currTime;
|
||||||
long time = Time.getUSecTime();
|
long time = Time.getUSecTime();
|
||||||
|
|
||||||
gEM.registerComponent!TestComp2;
|
gEntityManager.registerComponent!TestComp2;
|
||||||
gEM.registerComponent!TestComp4;
|
gEntityManager.registerComponent!TestComp4;
|
||||||
gEM.registerComponent!TestComp;
|
gEntityManager.registerComponent!TestComp;
|
||||||
gEM.registerComponent!TestComp3;
|
gEntityManager.registerComponent!TestComp3;
|
||||||
gEM.registerComponent!TestComp5;
|
gEntityManager.registerComponent!TestComp5;
|
||||||
gEM.registerComponent!CPosition;
|
gEntityManager.registerComponent!CPosition;
|
||||||
|
|
||||||
gEM.registerEvent!TestEvent;
|
gEntityManager.registerEvent!TestEvent;
|
||||||
gEM.registerEvent!TestEvent2;
|
gEntityManager.registerEvent!TestEvent2;
|
||||||
|
|
||||||
/*ulong dur = (MonoTime.currTime - time).total!"usecs";
|
/*ulong dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Components register: ", dur, " usecs");
|
//writeln("Components register: ", dur, " usecs");
|
||||||
|
|
@ -714,19 +714,19 @@ else:
|
||||||
printf("Components register: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Components register: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
gEM.registerSystem!TestSystemWithHighPriority(100, "fixed");
|
gEntityManager.registerSystem!TestSystemWithHighPriority(100, "fixed");
|
||||||
gEM.registerSystem!TestSystem(0);
|
gEntityManager.registerSystem!TestSystem(0);
|
||||||
gEM.registerSystem!ChangeTestSystem(0);
|
gEntityManager.registerSystem!ChangeTestSystem(0);
|
||||||
gEM.registerSystem!Sys1(10);
|
gEntityManager.registerSystem!Sys1(10);
|
||||||
gEM.registerSystem!Sys2(-100);
|
gEntityManager.registerSystem!Sys2(-100);
|
||||||
gEM.registerSystem!Sys3(-2);
|
gEntityManager.registerSystem!Sys3(-2);
|
||||||
gEM.registerSystem!EmptySystem(2);
|
gEntityManager.registerSystem!EmptySystem(2);
|
||||||
gEM.registerSystem!EmptyEventSystem(2);
|
gEntityManager.registerSystem!EmptyEventSystem(2);
|
||||||
gEM.registerSystem!EventSystem(2);
|
gEntityManager.registerSystem!EventSystem(2);
|
||||||
gEM.registerSystem!EverySystem(0);
|
gEntityManager.registerSystem!EverySystem(0);
|
||||||
//gEM.registerSystem!TestSystemWithHighPriority(100);
|
//gEntityManager.registerSystem!TestSystemWithHighPriority(100);
|
||||||
//gEM.registerSystem!TestSystem2(0);
|
//gEntityManager.registerSystem!TestSystem2(0);
|
||||||
gEM.endRegister();
|
gEntityManager.endRegister();
|
||||||
|
|
||||||
/*dur = (MonoTime.currTime - time).total!"usecs";
|
/*dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Systems register: ", dur, " usecs");
|
//writeln("Systems register: ", dur, " usecs");
|
||||||
|
|
@ -737,11 +737,11 @@ else:
|
||||||
|
|
||||||
//ushort[3] ids = [becsID!TestComp2, becsID!TestComp, becsID!TestComp4];
|
//ushort[3] ids = [becsID!TestComp2, becsID!TestComp, becsID!TestComp4];
|
||||||
ushort[2] ids = [becsID!TestComp2, becsID!TestComp];
|
ushort[2] ids = [becsID!TestComp2, becsID!TestComp];
|
||||||
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
|
EntityTemplate* tmpl = gEntityManager.allocateTemplate(ids);
|
||||||
|
|
||||||
//ushort[3] ids2 = [becsID!TestComp3, becsID!TestComp, becsID!TestComp4];
|
//ushort[3] ids2 = [becsID!TestComp3, becsID!TestComp, becsID!TestComp4];
|
||||||
ushort[2] ids2 = [becsID!TestComp3, becsID!TestComp];
|
ushort[2] ids2 = [becsID!TestComp3, becsID!TestComp];
|
||||||
EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2);
|
EntityTemplate* tmpl2 = gEntityManager.allocateTemplate(ids2);
|
||||||
////writeln(tmpl.info.components[]);
|
////writeln(tmpl.info.components[]);
|
||||||
//*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1);
|
//*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1);
|
||||||
|
|
||||||
|
|
@ -752,67 +752,67 @@ else:
|
||||||
|
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
ushort[1] empty_ids = [becsID!CPosition];
|
ushort[1] empty_ids = [becsID!CPosition];
|
||||||
EntityTemplate* tmpl_empty = gEM.allocateTemplate(empty_ids);
|
EntityTemplate* tmpl_empty = gEntityManager.allocateTemplate(empty_ids);
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
foreach(i;0..2_000_000)gEM.addEntity(tmpl_empty);
|
foreach(i;0..2_000_000)gEntityManager.addEntity(tmpl_empty);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
printf("Adding 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Adding 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().iterate);
|
gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().iterate);
|
||||||
printf("Iterate 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Iterate 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
printf("Iterate 1M entities (update): %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Iterate 1M entities (update): %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().free);
|
gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().free);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
printf("Deleting 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Deleting 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
foreach(i;0..4_000_000)gEntityManager.addEntity(tmpl_empty);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
foreach(i;0..2_000_000)gEM.addEntity(tmpl_empty);
|
foreach(i;0..2_000_000)gEntityManager.addEntity(tmpl_empty);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
printf("Adding 1M entities (prealloc): %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Adding 1M entities (prealloc): %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().addOne);
|
gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().addOne);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
printf("Adding 1M component: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Adding 1M component: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().free);
|
gEntityManager.callEntitiesFunction!EverySystem(&gEntityManager.getSystem!EverySystem().free);
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
EntityID entity;
|
EntityID entity;
|
||||||
|
|
||||||
{
|
{
|
||||||
entity = gEM.addEntity(tmpl).id;
|
entity = gEntityManager.addEntity(tmpl).id;
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEntityManager.getEntity(entity));
|
||||||
EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData(
|
EntityManager.EntitiesBlock* block = gEntityManager.getMetaData(
|
||||||
gEM.getEntity(entity));
|
gEntityManager.getEntity(entity));
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
//writeln(info.add_listeners);
|
//writeln(info.add_listeners);
|
||||||
//if(info)assert(0);
|
//if(info)assert(0);
|
||||||
|
|
@ -821,9 +821,9 @@ else:
|
||||||
//time = MonoTime.currTime;
|
//time = MonoTime.currTime;
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
//foreach(i; 0..1_000_000)gEM.addEntity(tmpl);
|
//foreach(i; 0..1_000_000)gEntityManager.addEntity(tmpl);
|
||||||
|
|
||||||
//foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id);
|
//foreach(i; 0..1_000_000)gEntityManager.removeEntity(gEntityManager.addEntity(tmpl).id);
|
||||||
|
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
|
|
||||||
|
|
@ -832,14 +832,14 @@ else:
|
||||||
|
|
||||||
foreach (i; 0 .. 200)
|
foreach (i; 0 .. 200)
|
||||||
{
|
{
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
foreach (j; 0 .. 5_000)
|
foreach (j; 0 .. 5_000)
|
||||||
idss[j] = gEM.addEntity(tmpl).id;
|
idss[j] = gEntityManager.addEntity(tmpl).id;
|
||||||
foreach (j; 0 .. 5_000)
|
foreach (j; 0 .. 5_000)
|
||||||
gEM.removeEntity(idss[j]);
|
gEntityManager.removeEntity(idss[j]);
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
}
|
}
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Entities adding: ", dur, " usecs");
|
//writeln("Entities adding: ", dur, " usecs");
|
||||||
|
|
@ -847,7 +847,7 @@ else:
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
uint blocks = 0;
|
uint blocks = 0;
|
||||||
foreach (info; &gEM.entities_infos.byValue)
|
foreach (info; &gEntityManager.entities_infos.byValue)
|
||||||
{
|
{
|
||||||
EntityManager.EntitiesBlock* block = info.first_block;
|
EntityManager.EntitiesBlock* block = info.first_block;
|
||||||
while (block !is null)
|
while (block !is null)
|
||||||
|
|
@ -859,13 +859,13 @@ else:
|
||||||
//writeln("Entities blocks: ", blocks);
|
//writeln("Entities blocks: ", blocks);
|
||||||
printf("Entities blocks: %u\n", blocks);
|
printf("Entities blocks: %u\n", blocks);
|
||||||
|
|
||||||
//foreach(j; 0..1_000)gEM.addEntity(tmpl);
|
//foreach(j; 0..1_000)gEntityManager.addEntity(tmpl);
|
||||||
|
|
||||||
gEM.beginRegister();
|
gEntityManager.beginRegister();
|
||||||
gEM.registerSystem!TestSystem2(0);
|
gEntityManager.registerSystem!TestSystem2(0);
|
||||||
gEM.endRegister();
|
gEntityManager.endRegister();
|
||||||
|
|
||||||
//gEM.generateDependencies();
|
//gEntityManager.generateDependencies();
|
||||||
|
|
||||||
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1));
|
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1));
|
||||||
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1));
|
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1));
|
||||||
|
|
@ -878,12 +878,12 @@ else:
|
||||||
EntityID[] entities = Mallocator.makeArray!EntityID(1_000_000);
|
EntityID[] entities = Mallocator.makeArray!EntityID(1_000_000);
|
||||||
foreach (i; 0 .. 500_000)
|
foreach (i; 0 .. 500_000)
|
||||||
{
|
{
|
||||||
entity2 = gEM.addEntity(tmpl).id;
|
entity2 = gEntityManager.addEntity(tmpl).id;
|
||||||
entities[i * 2] = entity2;
|
entities[i * 2] = entity2;
|
||||||
entities[i * 2 + 1] = gEM.addEntity(tmpl2).id;
|
entities[i * 2 + 1] = gEntityManager.addEntity(tmpl2).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Entities adding2: ", dur, " usecs");
|
//writeln("Entities adding2: ", dur, " usecs");
|
||||||
|
|
||||||
|
|
@ -893,12 +893,12 @@ else:
|
||||||
|
|
||||||
foreach (i; 0 .. 1_000_000)
|
foreach (i; 0 .. 1_000_000)
|
||||||
{
|
{
|
||||||
EntityManager.instance.addComponents(entities[i], TestComp5());
|
gEntityManager.addComponents(entities[i], TestComp5());
|
||||||
if ((i & 0x00FFFF) == 0)
|
if ((i & 0x00FFFF) == 0)
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Components adding: ", dur, " usecs");
|
//writeln("Components adding: ", dur, " usecs");
|
||||||
|
|
||||||
|
|
@ -908,11 +908,11 @@ else:
|
||||||
|
|
||||||
foreach (i; 0 .. 1_000_000)
|
foreach (i; 0 .. 1_000_000)
|
||||||
{
|
{
|
||||||
EntityManager.instance.removeComponents!TestComp5(entities[i]);
|
gEntityManager.removeComponents!TestComp5(entities[i]);
|
||||||
//if((i & 0x00FFFF) == 0)gEM.commit();
|
//if((i & 0x00FFFF) == 0)gEntityManager.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Components removing: ", dur, " usecs");
|
//writeln("Components removing: ", dur, " usecs");
|
||||||
printf("Components removing: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Components removing: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
@ -923,102 +923,102 @@ else:
|
||||||
//time = MonoTime.currTime;
|
//time = MonoTime.currTime;
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
//gEM.updateMT();
|
//gEntityManager.updateMT();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Update: ", dur, " usecs");
|
//writeln("Update: ", dur, " usecs");
|
||||||
printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity2));
|
writeEntityComponents(gEntityManager.getEntity(entity2));
|
||||||
|
|
||||||
//time = MonoTime.currTime;
|
//time = MonoTime.currTime;
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.updateMT();
|
gEntityManager.updateMT();
|
||||||
//gEM.update();
|
//gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Update: ", dur, " usecs");
|
//writeln("Update: ", dur, " usecs");
|
||||||
printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity2));
|
writeEntityComponents(gEntityManager.getEntity(entity2));
|
||||||
|
|
||||||
//time = MonoTime.currTime;
|
//time = MonoTime.currTime;
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.updateMT();
|
gEntityManager.updateMT();
|
||||||
//gEM.update();
|
//gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Update: ", dur, " usecs");
|
//writeln("Update: ", dur, " usecs");
|
||||||
printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Update: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity2));
|
writeEntityComponents(gEntityManager.getEntity(entity2));
|
||||||
|
|
||||||
entity = gEM.addEntity(tmpl).id;
|
entity = gEntityManager.addEntity(tmpl).id;
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
//Entity* pp;// = gEM.getEntity(entity.id);
|
//Entity* pp;// = gEntityManager.getEntity(entity.id);
|
||||||
////writeln((cast(uint*) pp)[0 .. 14], " ", pp);
|
////writeln((cast(uint*) pp)[0 .. 14], " ", pp);
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEntityManager.getEntity(entity));
|
||||||
|
|
||||||
//writeln("Entity, its copy, and template, and default filled tempalte");
|
//writeln("Entity, its copy, and template, and default filled tempalte");
|
||||||
gEM.addEntity(tmpl);
|
gEntityManager.addEntity(tmpl);
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEntityManager.getEntity(entity));
|
||||||
writeEntityComponents(gEM.addEntityCopy(entity));
|
writeEntityComponents(gEntityManager.addEntityCopy(entity));
|
||||||
EntityTemplate* copy_tempalte = gEM.allocateTemplate(entity);
|
EntityTemplate* copy_tempalte = gEntityManager.allocateTemplate(entity);
|
||||||
writeEntityComponents(gEM.addEntity(copy_tempalte));
|
writeEntityComponents(gEntityManager.addEntity(copy_tempalte));
|
||||||
EntityTemplate* copy_default_tempalte = gEM.allocateTemplate(entity, true);
|
EntityTemplate* copy_default_tempalte = gEntityManager.allocateTemplate(entity, true);
|
||||||
writeEntityComponents(gEM.addEntity(copy_default_tempalte));
|
writeEntityComponents(gEntityManager.addEntity(copy_default_tempalte));
|
||||||
|
|
||||||
gEM.addComponents(entity, TestComp4());
|
gEntityManager.addComponents(entity, TestComp4());
|
||||||
gEM.addComponents(entity, TestComp3());
|
gEntityManager.addComponents(entity, TestComp3());
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEntityManager.getEntity(entity));
|
||||||
|
|
||||||
gEM.removeComponents!(TestComp)(entity);
|
gEntityManager.removeComponents!(TestComp)(entity);
|
||||||
gEM.addComponents(entity, TestComp());
|
gEntityManager.addComponents(entity, TestComp());
|
||||||
gEM.addComponents(entity, TestComp5());
|
gEntityManager.addComponents(entity, TestComp5());
|
||||||
|
|
||||||
gEM.begin();
|
gEntityManager.begin();
|
||||||
gEM.update();
|
gEntityManager.update();
|
||||||
gEM.update("fixed");
|
gEntityManager.update("fixed");
|
||||||
gEM.end();
|
gEntityManager.end();
|
||||||
|
|
||||||
gEM.removeComponents!(TestComp4)(entity);
|
gEntityManager.removeComponents!(TestComp4)(entity);
|
||||||
|
|
||||||
gEM.commit();
|
gEntityManager.commit();
|
||||||
|
|
||||||
System* sys = EntityManager.instance.getSystem(becsID!TestSystem2);
|
System* sys = gEntityManager.getSystem(becsID!TestSystem2);
|
||||||
|
|
||||||
ExternalUpdateCallTest external_update_test;
|
ExternalUpdateCallTest external_update_test;
|
||||||
|
|
||||||
EntityManager.instance.callEntitiesFunction!TestSystem2(&external_update_test.update);
|
gEntityManager.callEntitiesFunction!TestSystem2(&external_update_test.update);
|
||||||
|
|
||||||
printf("pre end\n");
|
printf("pre end\n");
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEntityManager.getEntity(entity));
|
||||||
//import std.stdio;
|
//import std.stdio;
|
||||||
////writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
////writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
||||||
gEM.freeTemplate(tmpl_empty);
|
gEntityManager.freeTemplate(tmpl_empty);
|
||||||
gEM.freeTemplate(tmpl);
|
gEntityManager.freeTemplate(tmpl);
|
||||||
gEM.freeTemplate(tmpl2);
|
gEntityManager.freeTemplate(tmpl2);
|
||||||
gEM.freeTemplate(copy_tempalte);
|
gEntityManager.freeTemplate(copy_tempalte);
|
||||||
gEM.freeTemplate(copy_default_tempalte);
|
gEntityManager.freeTemplate(copy_default_tempalte);
|
||||||
EntityManager.destroy();
|
EntityManager.destroy();
|
||||||
|
|
||||||
Mallocator.dispose(idss);
|
Mallocator.dispose(idss);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue