Added System docs
Improved the accuracy of system.md Added ECSSystem.md and SystemManager.md
This commit is contained in:
parent
fdb06e0668
commit
7b09b13889
@ -3,16 +3,13 @@
|
||||
### In this folder
|
||||
[Implementation](./implementation.md) *how to use JavaECS*
|
||||
|
||||
[Usage](#Usage)
|
||||
|
||||
[Notes](#Notes)
|
||||
|
||||
### See also:
|
||||
[entity](./entity/entity.md)
|
||||
[Entity](./entity/Entity.md)
|
||||
|
||||
[component](./component/component.md)
|
||||
[Component](./component/Component.md)
|
||||
|
||||
[system](./system/system.md)
|
||||
[System](./system/System.md)
|
||||
|
||||
[event](./)
|
||||
|
||||
|
67
docs/system/ECSSystem.md
Normal file
67
docs/system/ECSSystem.md
Normal file
@ -0,0 +1,67 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [system](./dir.md) | ECSSystem[]().md*
|
||||
# System Manager
|
||||
|
||||
### In this section
|
||||
[About](#about)
|
||||
|
||||
[Implementation](#implementation)
|
||||
|
||||
[Constructors](#constructors)
|
||||
|
||||
[Methods](#methods)
|
||||
|
||||
[Fields](#fields)
|
||||
|
||||
[Examples](#examples)
|
||||
|
||||
[Notes](#notes)
|
||||
|
||||
|
||||
## About
|
||||
The system manager class controls references to the systems.
|
||||
|
||||
## Implementation
|
||||
See [System.md](./System.md#implmentation)
|
||||
## Constructors
|
||||
Default constructor
|
||||
``` java
|
||||
public ECSSystem(){}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
### init
|
||||
``` java
|
||||
public void init(){}
|
||||
```
|
||||
Functionality that needs to occur at the initialisation of the system should be performed here
|
||||
* `init()` should be called only once, before the system is utilised
|
||||
* An example of the type of call that could be made here is opening a file
|
||||
|
||||
<br>
|
||||
|
||||
### update
|
||||
``` java
|
||||
public void update(){}
|
||||
```
|
||||
Functionality that needs to be called regularly should be defined here
|
||||
* `update()` is intended to be called regularly
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
## Fields
|
||||
### entities
|
||||
``` java
|
||||
Set<Integer> entities = new HashSet<>();
|
||||
```
|
||||
The list of entities associated with this system
|
||||
|
||||
<br>
|
||||
|
||||
## Examples
|
||||
|
||||
<br>
|
||||
|
||||
## Notes
|
87
docs/system/SystemManager.md
Normal file
87
docs/system/SystemManager.md
Normal file
@ -0,0 +1,87 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [system](./dir.md) | SystemManager[]().md*
|
||||
# System Manager
|
||||
|
||||
### In this section
|
||||
[About](#about)
|
||||
|
||||
[Implementation](#implementation)
|
||||
|
||||
[Constructors](#constructors)
|
||||
|
||||
[Methods](#methods)
|
||||
|
||||
[Fields](#fields)
|
||||
|
||||
[Examples](#examples)
|
||||
|
||||
[Notes](#notes)
|
||||
|
||||
|
||||
## About
|
||||
The system manager class controls references to the systems.
|
||||
|
||||
## Implementation
|
||||
Before attempting to use a system, it must be registered.
|
||||
|
||||
Registration requires a call to `registerSystem(String systemName, ECSSystem system)`, with params of the `String name` and a object reference of the [ECSSystem](./ECSSystem.md). Using the object reference, a system can be invoked at any time.
|
||||
|
||||
## Constructors
|
||||
Default constructor
|
||||
``` java
|
||||
public SystemManager(){}
|
||||
```
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
|
||||
### entityDestroyed
|
||||
``` java
|
||||
public void entityDestroyed(int entity);
|
||||
```
|
||||
Removes the specified entity from every system, if it was associated
|
||||
|
||||
<br>
|
||||
|
||||
### entitySignatureChanged
|
||||
``` java
|
||||
public void entitySignatureChanged(int entity, BitSet entitySignature);
|
||||
```
|
||||
Checks the entity's new signature against the current registrations. Registers the entity if it wasn't previously registered, or removes it if it is no longer registered.
|
||||
|
||||
<br>
|
||||
|
||||
### registerSystem
|
||||
``` java
|
||||
public boolean registerSystem(String systemName, ECSSystem system);
|
||||
```
|
||||
Registers the specified system name and system reference to this manager.
|
||||
|
||||
*adds a `systemName:system` pair to [systems](#systems)*
|
||||
|
||||
*and a `systemName:new BitSet()` pair to [signatures](#signatures)*
|
||||
|
||||
<br>
|
||||
|
||||
### setSignature
|
||||
``` java
|
||||
public void setSignature(String system, BitSet registrations);
|
||||
```
|
||||
Sets the required signature of the `system`
|
||||
|
||||
<br>
|
||||
|
||||
## Fields
|
||||
### signatures
|
||||
``` java
|
||||
Map<String, BitSet> signatures = new HashMap<>();
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### systems
|
||||
``` java
|
||||
Map<String, ECSSystem> systems = new HashMap<>();
|
||||
```
|
||||
|
||||
<br>
|
||||
|
@ -1,4 +1,6 @@
|
||||
*| [JavaECS](../README.md) | [docs](../overview.md) | system*
|
||||
# Overview
|
||||
### In this folder
|
||||
[system.md](./system.md)
|
||||
* [ECSSystem.md](./ECSSystem.md)
|
||||
* [System.md](./System.md)
|
||||
* [SystemManager.md](./SystemManager.md)
|
@ -1,4 +1,4 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [system](./dir.md) | system[]().md*
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [system](./dir.md) | System[]().md*
|
||||
# System
|
||||
|
||||
### In this section
|
||||
@ -12,51 +12,103 @@
|
||||
|
||||
|
||||
## About
|
||||
The system runs operations that must be performed on its assoiciated components.
|
||||
>A system is a functionality that is executed regularly by the game engine.
|
||||
|
||||
Typically, this is expected to be run every frame, though this is not a strict requirement.
|
||||
The [SystemManager](./SystemManager.md) ensures that the system has an up-to-date list of entities that the system would act upon. This is performed by comparing the system's declared required components with the components of a potential entity. An entity containing all required components is added to the system's list.
|
||||
|
||||
A system must implement the Runnable interface (this is a limited case of inheritence in this library)
|
||||
A system does not explicitly require any entities to be registered; but it can make more sense to directly perform such operations in the game loop.
|
||||
|
||||
This allows a simpler implementation of any system, and also allows concurrency to be implemented with relative ease.
|
||||
`TODO`
|
||||
There is a single layer of inheritence in this design, which is the overriden `init()` and `update()` functions.
|
||||
This allows each system's `update()` to be called in a uniform way.
|
||||
|
||||
|
||||
|
||||
|
||||
Examples of the `system` include the `health_system`; which reads the value of the entitie's `health` component and ensures h > 0.
|
||||
``` java
|
||||
void health_system(){
|
||||
for (i = 0; i < registeredComponents.size(); i++){
|
||||
if (registeredComponents[i].health <= 0){
|
||||
registeredComponents[i].dead = true;
|
||||
if (registeredComponents[i].isPlayer){
|
||||
GameOver();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
## Implementation
|
||||
|
||||
The systems are managed by the following code:
|
||||
All systems should extend [ECSSystem](./ECSSystem.md), which implements the entities list as a simple set.
|
||||
|
||||
This can be overriden if there are certain requirements for the order of the entities (e.g. a Render System might require the further-most elements to be drawn first, to ensure the correct z-ordering)
|
||||
|
||||
``` java
|
||||
class SystemManager{
|
||||
ECS baseECS;
|
||||
int systemIndex;
|
||||
|
||||
public SystemManager(ECS baseECS){
|
||||
this.baseECS = baseECS;
|
||||
systemIndex = 0;
|
||||
class ECSSystem{
|
||||
Set<Integer> entities = new HashSet<>();
|
||||
}
|
||||
```
|
||||
``` java
|
||||
class NewSystem extends ECSSystem{
|
||||
void init() {}
|
||||
void update(/* any required parameters*/){
|
||||
/* implementation */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
### System that operates on entities with <span style="color:white">multiple components</span>
|
||||
``` java
|
||||
public class PhysicsSystem extends ECSSystem{
|
||||
ECS gameEngine;
|
||||
public PhysicsSystem(ECS gameEngine){
|
||||
this.gameEngine = gameEngine;
|
||||
}
|
||||
|
||||
void init() {}
|
||||
|
||||
void update(double dt){
|
||||
for (Integer entity : entities) {
|
||||
// Get entity components
|
||||
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class.getName());
|
||||
RidgidBody ridgidBody = (RidgidBody)gameEngine.getComponentData(entity, RidgidBody.class.getName());
|
||||
Gravity gravity = (Gravity)gameEngine.getComponentData(entity, Gravity.class.getName());
|
||||
// Add the result of the accelerative forces to the ridgidbody's velocity
|
||||
ridgidBody.xdot += ridgidBody.xAcc * dt;
|
||||
ridgidBody.ydot += ridgidBody.yAcc * dt;
|
||||
|
||||
// Gravity is a force of acceleration as above, but is generally considered to be constant.
|
||||
if (gravity.terminalX < 0 || Math.abs(ridgidBody.xdot) < gravity.terminalX){
|
||||
ridgidBody.xdot += gravity.x * dt;
|
||||
}
|
||||
if (gravity.terminalY < 0 || Math.abs(ridgidBody.ydot) < gravity.terminalY){
|
||||
ridgidBody.ydot += gravity.y * dt;
|
||||
}
|
||||
|
||||
// Finally, move the vec2d by the new velocity
|
||||
pos.x += ridgidBody.xdot * dt;
|
||||
pos.y += ridgidBody.ydot * dt;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
### System that operates on a <span style="color:white">single component</span>
|
||||
``` java
|
||||
public class LogVec2DSystem extends ECSSystem{
|
||||
ECS gameEngine;
|
||||
public LogVec2DSystem(ECS gameEngine){
|
||||
this.gameEngine = gameEngine;
|
||||
}
|
||||
|
||||
void init() {}
|
||||
|
||||
void update(double dt){
|
||||
for (Integer entity : entities) {
|
||||
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class.getName());
|
||||
System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
### System that operates on <span style="color:white">no components</span>
|
||||
Note that it does not require a reference the the `gameEngine`; no component data is accessed.
|
||||
``` java
|
||||
public class FrameRateSystem extends ECSSystem{
|
||||
void init() {}
|
||||
|
||||
void update(double dt, double idleTime){
|
||||
System.out.print(String.format("dt: %.3g (%.3g idle) ", dt, idleTime));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
* Each system is represented by a name-index pair, and the action that gets executed every time the system is performed.
|
||||
* This is implicitly sequential, but a custom system that performs concurrent actions can be implemented.
|
||||
* Care must be taken to ensure all threads are synchronised before the concurrent system finishes its execution
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user