This repository has been archived by the owner on Oct 4, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Robert G
authored and
Robert G
committed
Oct 23, 2017
0 parents
commit 94a91ec
Showing
12 changed files
with
1,170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.dub | ||
docs.json | ||
__dummy.html | ||
*.o | ||
*.obj | ||
decs.exe | ||
dub.selections.json | ||
source/app.d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Boost Software License - Version 1.0 - August 17th, 2003 | ||
|
||
Permission is hereby granted, free of charge, to any person or organization | ||
obtaining a copy of the software and accompanying documentation covered by | ||
this license (the "Software") to use, reproduce, display, distribute, | ||
execute, and transmit the Software, and to prepare derivative works of the | ||
Software, and to permit third-parties to whom the Software is furnished to | ||
do so, all subject to the following: | ||
|
||
The copyright notices in the Software and this entire statement, including | ||
the above license grant, this restriction and the following disclaimer, | ||
must be included in all copies of the Software, in whole or in part, and | ||
all derivative works of the Software, unless such copies or derivative | ||
works are solely in the form of machine-executable object code generated by | ||
a source language processor. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT | ||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE | ||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, | ||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/** Works in progress **/ | ||
|
||
decs | ||
=========== | ||
|
||
decs is my attempt to build a @nogc D language Entity Component System. | ||
I'm not really an game dev, im trying to learn how an ECS works so some portions of this code can be inefficients or bug prone. | ||
|
||
It's inspired by the following projects : | ||
|
||
https://github.com/miguelmartin75/anax => C++ ECS | ||
https://github.com/jzhu98/star-entity => D ECS | ||
https://github.com/claudemr/entitysysd => D ECS | ||
|
||
## How to build | ||
|
||
You have to use [dub](https://code.dlang.org/download) to build the project. | ||
|
||
Add this project as a dependency to your **dub.json**: | ||
|
||
```json | ||
"dependencies": { | ||
"decs": "~>1.0.0" | ||
} | ||
``` | ||
|
||
## How to use | ||
|
||
### Entity Manager | ||
|
||
```cs | ||
|
||
import decs; | ||
|
||
void main() | ||
{ | ||
auto em = new EntityManager(); | ||
|
||
while(game) | ||
{ | ||
em.update(dt); | ||
} | ||
|
||
// !important! | ||
em.dispose(); | ||
} | ||
|
||
``` | ||
|
||
### Entities | ||
|
||
You can create an entity, kill it, invalidate it or activate it (still need some work here). | ||
|
||
```cs | ||
auto entity = em.createEntity(); | ||
|
||
// Notifies all systems that a new entity is alive (check system section to understand this part) | ||
entity.activate(); | ||
|
||
// Entity is still alive but will be invalid in current scope | ||
entity.invalidate(); | ||
|
||
// Poor entity :< | ||
entity.kill(); | ||
``` | ||
|
||
### Components | ||
|
||
An component must be represented as a struct. | ||
|
||
```cs | ||
struct PositionComponent | ||
{ | ||
float x, y, z; | ||
} | ||
``` | ||
|
||
You can add a component to an entity : | ||
|
||
```cs | ||
// add | ||
entity.add!PositionComponent(1, 2, 3); | ||
|
||
// update (its handled as a pointer) | ||
entity.get!PositionComponent().y = 50; | ||
|
||
// check | ||
if(entity.has!PositionComponent()) | ||
{ | ||
// ... | ||
} | ||
``` | ||
### Systems | ||
|
||
An system must be a class that inherits **decs.System**. | ||
|
||
```cs | ||
class MovementSystem : System | ||
{ | ||
public void update(in float delta) | ||
{ | ||
|
||
} | ||
} | ||
``` | ||
There is 2 ways to query entities from your system : | ||
|
||
* 1 => Using entity manager **entities!(components...)** function | ||
* 2 => Using the components filter mixin **mixin ComponentsFilter!(components...);** | ||
|
||
|
||
If you provide an components filter, when an entity is activated, it will be automatically added to the systems whose filters match her components. | ||
|
||
```cs | ||
class MovementSystem : System | ||
{ | ||
// option 2 | ||
mixin ComponentsFilter!(PositionComponent); | ||
|
||
public void update(in float deltaTime) | ||
{ | ||
// option 1 | ||
auto entities = this.m_entityManager.entities!(PositionComponent); | ||
|
||
// option 2 (should be more efficient) | ||
foreach(entity; this.m_entities) | ||
{ | ||
|
||
} | ||
} | ||
} | ||
``` | ||
System's update method will be called automatically by the entity manager in the main loop. If you want to handle the update manually, you can set the **System.UpdatePolicy** to manual : | ||
|
||
```cs | ||
class MovementSystem : System | ||
{ | ||
public this() | ||
{ | ||
super(System.UpdatePolicy.Manual); | ||
} | ||
} | ||
|
||
// ... | ||
while(game) | ||
{ | ||
em.update(dt); | ||
|
||
// you have to call it manually (before or after the em.update call) | ||
myMovementSystem.update(dt); | ||
} | ||
``` | ||
|
||
### Events | ||
|
||
wip | ||
|
||
## TODOs | ||
|
||
* Add **@component** and **@event** UDAs | ||
* Add the possibility to defines systems execution order when using **em.update(dt)** | ||
* Add anexample project | ||
* Improve this readme |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "decs", | ||
"authors": [ | ||
"aldo" | ||
], | ||
"dependencies": { | ||
"dnogc": "~master" | ||
}, | ||
"description": "@nogc D Entity Component System", | ||
"license": "Boost Software License" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module decs.Component; | ||
|
||
struct GlobalComponentCounter | ||
{ | ||
static uint counter = 0; | ||
} | ||
|
||
/** | ||
* Helper used to get an unique id per component | ||
*/ | ||
struct ComponentCounter(Component) | ||
{ | ||
private GlobalComponentCounter globalComponentCounter; | ||
|
||
public static uint getId() nothrow @safe @nogc | ||
{ | ||
static uint counter = -1; | ||
|
||
if(counter == -1) | ||
{ | ||
counter = globalComponentCounter.counter; | ||
globalComponentCounter.counter++; | ||
} | ||
|
||
return counter; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
module decs.ComponentPool; | ||
|
||
import dnogc.DynamicArray; | ||
|
||
interface IComponentPool | ||
{ | ||
public void dispose(); | ||
public void expand() nothrow @safe @nogc; | ||
public size_t length() const pure nothrow @safe @nogc; | ||
} | ||
|
||
class ComponentPool(T) : IComponentPool | ||
{ | ||
private DynamicArray!T m_components; | ||
|
||
public this(in size_t poolSize) nothrow @safe @nogc | ||
{ | ||
this.m_components = DynamicArray!T(poolSize); | ||
this.m_components.length = poolSize; | ||
} | ||
|
||
public void dispose() | ||
{ | ||
this.m_components.dispose(); | ||
} | ||
|
||
public void insert()(auto ref T component) nothrow @safe @nogc | ||
{ | ||
this.m_components.insert(component); | ||
} | ||
|
||
/** | ||
* Returns the component at the specified index | ||
* Params: | ||
* index : | ||
*/ | ||
public T* get(in uint index) pure nothrow @trusted @nogc | ||
{ | ||
assert(index < this.m_components.length); | ||
|
||
immutable ptr = index * T.sizeof; | ||
|
||
auto data = this.m_components.ptr; | ||
|
||
return cast(T*)data[ptr..(ptr + T.sizeof)]; | ||
} | ||
|
||
/** | ||
* Sets the value of the component at the specified index | ||
* Params: | ||
* index : | ||
* component : | ||
*/ | ||
public void set(in uint index, ref T component) pure nothrow @safe @nogc | ||
{ | ||
assert(index < this.m_components.length); | ||
|
||
this.m_components[index] = component; | ||
} | ||
|
||
/** | ||
* Expands the pool with an empty value | ||
*/ | ||
public void expand() nothrow @safe @nogc | ||
{ | ||
this.m_components.insert(T()); | ||
} | ||
|
||
@property | ||
public size_t length() const pure nothrow @safe @nogc | ||
{ | ||
return this.m_components.length; | ||
} | ||
} |
Oops, something went wrong.