Compare commits
49
Commits
7395b943b8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2405f1fb53 | ||
|
|
5a3e3a33fc | ||
|
|
0bc67fe87b | ||
|
|
e00558937a | ||
|
|
6aab0ee986 | ||
|
|
2bc53528d0 | ||
|
|
02aa0891cb | ||
|
|
227d7fd874 | ||
|
|
4cbfb97225 | ||
|
|
8d8b7ad3a6 | ||
|
|
e4d5d8c794 | ||
|
|
d5bc3447b5 | ||
|
|
fb088d50ff | ||
|
|
65b498a460 | ||
|
|
066de0e362 | ||
|
|
b0b465c650 | ||
|
|
f650409d12 | ||
|
|
2bb1b41d89 | ||
|
|
35caf24749 | ||
|
|
1e31bbaa75 | ||
|
|
a77b1e5589 | ||
|
|
84a4c93742 | ||
|
|
89f407baa1 | ||
|
|
1d4df19e43 | ||
|
|
971db6c6a7 | ||
|
|
7994725f26 | ||
|
|
2ee01184a8 | ||
|
|
2d0aa6b830 | ||
|
|
aa6380644f | ||
|
|
453d3f1356 | ||
|
|
56f3ebda34 | ||
|
|
c3bedfc324 | ||
|
|
772b6c6582 | ||
|
|
18b21c6fbb | ||
|
|
9276234d2b | ||
|
|
016d115ec4 | ||
|
|
4a26b9aa2c | ||
|
|
ab957e5789 | ||
|
|
78822fe1c5 | ||
|
|
f88ca79d0e | ||
|
|
8f74b67bfb | ||
|
|
1f5f09ee0c | ||
|
|
155ef6e394 | ||
|
|
e79552015d | ||
|
|
fea90a49ae | ||
|
|
fa7fe1c8e1 | ||
|
|
0bbf3bc5b5 | ||
|
|
d40dc06b93 | ||
|
|
f952a928ac |
@@ -4,63 +4,66 @@
|
||||
### [View the Documentation](./docs/overview.md)
|
||||
|
||||
## *About Entity-Component-Systems*
|
||||
An Enity-Component-System comprises of four main parts
|
||||
1. The [entity](./docs/entity/Entity.md) which is essentially just a unique ID *i.e. an integer value*
|
||||
2. The [component](./docs/entity/Component.md) which is a `struct` (`class` in Java). Typically contains data, but can be empty (to be used as a flag for certain systems) or contain function definitions.
|
||||
3. The [system](./docs/system/System.md) which defines two main functions: `init()` and `update()`. Systems define a filter that is used to maintain a current and relevant list of entities that the system will act on.
|
||||
4. The [engine](./docs/Engine.md), which ties everything together. It exposes the functions that should be called, and methods for retrieving data correctly. The initialisation of everything required also takes place here
|
||||
|
||||
Traditional game-engine designs typically follow the standard functional or object-oriented design paradigms.
|
||||
This choice of paradigm is as important as it is in typical applications.
|
||||
## About the implementation
|
||||
The JavaECS project is a Maven project targeting Java SE 1.8.
|
||||
It is released under the MIT licence.
|
||||
It is intended to be compiled and packed into a `.jar` and referenced and imported into a project.
|
||||
The Maven build script will produce a `javadoc` `.jar` with the library.
|
||||
|
||||
A functional-paradigm game usually focuses on a 'this-then-that' model, e.g.:
|
||||
## Getting started with JavaECS
|
||||
Initialise the library like so:
|
||||
``` java
|
||||
Engine gameEngine = new Engine(/* desired number of entities */);
|
||||
```
|
||||
Next, the known components should be added.
|
||||
|
||||
***Simple Driving Game***
|
||||
|
||||
``` py
|
||||
turn = GetTurn()
|
||||
TurnCar(turn)
|
||||
if IsCollided(): # and other checks
|
||||
GameOver()
|
||||
else:
|
||||
DrawNextFrame()
|
||||
turn = GetTurn()
|
||||
Use the reflective component type:
|
||||
``` java
|
||||
gameEngine.registerComponent(ExampleComponent.class);
|
||||
```
|
||||
|
||||
Such a system works well for some game-designs; it is simplistic and follows a deterministic sequence of steps. But it lacks scalability and extensibility.
|
||||
|
||||
An Object-Oriented approach could be used instead:
|
||||
``` py
|
||||
# Create a base-class that is a vehicle, with basic properties:
|
||||
class Vehicle:
|
||||
position = [x,y]
|
||||
IsCrashed = False
|
||||
def CalcTurn():
|
||||
pass
|
||||
def IsCollided():
|
||||
pass
|
||||
|
||||
# Create the PlayerVehicle class which extends Vehicle to include the player input method
|
||||
class PlayerVehicle(Vehicle):
|
||||
def GetPlayerInput():
|
||||
pass
|
||||
|
||||
def GameLoop():
|
||||
vehicles[] = GetAllVehichles()
|
||||
allCollided = False
|
||||
while not allCollided:
|
||||
for v in vehicles:
|
||||
turnAmount
|
||||
if v is PlayerVehicle:
|
||||
turnAmount = v.GetPlayerInput()
|
||||
else:
|
||||
turnAmount = v.CalcTurn()
|
||||
v.TurnVehicle()
|
||||
if v.IsCollided():
|
||||
v.IsCrashed = True
|
||||
anyNotCollided = False
|
||||
for v in vehicles:
|
||||
if v.IsCrashed = False:
|
||||
anyNotCollided = True
|
||||
break
|
||||
Next, register the systems that are required.
|
||||
Each system must be constructed, and passed as a parameter to the Engine.
|
||||
- *If the system shall be invoked elsewhere, then you can petition the engine for the instance of the system.*
|
||||
``` java
|
||||
ExampleSystem exampleSystem = new ExampleSystem(gameEngine);
|
||||
gameEngine.registerSystem(ExampleSystem.class, exampleSystem);
|
||||
```
|
||||
|
||||
Which allows the instancing of objects. Each action also results in an objective state, which can be simply compared to determine the result.
|
||||
Next, create the entities that are needed as required.
|
||||
``` java
|
||||
Entity newEntity = gameEngine.createEntity();
|
||||
```
|
||||
|
||||
ECS are typically built on object-oriented ideas, but make specfic attempts to reduce overheads that come from object-oriented ideas.
|
||||
The primary reduction made in ECS is to eliminate or otherwise minimise inhertance cycles to reduce the amount of virtual calls required.
|
||||
Assign the components to the entity:
|
||||
``` java
|
||||
gameEngine.addComponent(newEntity, ExampleComponent.class, new ExampleComponent());
|
||||
```
|
||||
|
||||
Be sure to call `init()` on each system, before the logical loop of the program
|
||||
``` java
|
||||
exampleSystem.init();
|
||||
```
|
||||
|
||||
Finally, the engine is ready to enter the logical loop, e.g.:
|
||||
``` java
|
||||
while (true){
|
||||
exampleSystem.update();
|
||||
}
|
||||
```
|
||||
* note systems are *not* required to perform their `update()` in the normal logical loop.
|
||||
* the update can also be performed at a factored rate. E.g. physics can be performed at a different rate to the renderer, in order to improve physics accuracy
|
||||
* when using your own implmentation of a system, you may leave `init()` empty. Therefore, it isn't necessary to call `init()` before the game loop. **However**, It is recommended that you call `init()` to maintain consistency with all systems in the engine.
|
||||
* Entities, components, and systems can be created at any time in the program lifecycle.
|
||||
* Entities can be destroyed.
|
||||
* Components and systems cannot be destroyed.
|
||||
* Be aware that component registrations are contained via [BitSet](https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html). As the array is extended as bits are needed, note that the order of the set bits may impact performance with a large number of component types.
|
||||
|
||||
### Example:
|
||||
[App.java](/BrychanD/JavaECS-Examples/src/branch/master/demo1/src/main/java/nz/ac/massey/javaecs/examples/App.java#line=12-128)
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0px;
|
||||
background-color: #383c4a;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/css/index.css">
|
||||
<link rel="stylesheet" href="/css/theme-night-sky.css">
|
||||
|
||||
<script>
|
||||
const queryString = window.location.search;
|
||||
const queryLoc = window.location.origin;
|
||||
const queryRequest = window.location.href.split('?')[0];
|
||||
const windowLoc = window.location.toString();
|
||||
console.log(queryString);
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const requestURL = urlParams.get('url')
|
||||
const selector = urlParams.get('selector')
|
||||
var pageLink;
|
||||
// Fetch the content
|
||||
fetch(queryLoc + requestURL)
|
||||
.then(function (data) {
|
||||
return data.text();
|
||||
})
|
||||
.then(function (html) {
|
||||
// Parse the DOM of the fetched file
|
||||
var parser = new DOMParser();
|
||||
var doc = parser.parseFromString(html, "text/html");
|
||||
// Select the correct container
|
||||
var htmlTrimmed = doc.querySelector(selector);
|
||||
if (htmlTrimmed) {
|
||||
htmlTrimmed = htmlTrimmed.parentElement;
|
||||
/*
|
||||
var styleSheets = doc.querySelectorAll("link");
|
||||
for (var i = 0; i < styleSheets.length; i++) {
|
||||
document.head.appendChild(styleSheets[i]);
|
||||
} */
|
||||
// Fetch and refactor links, to use this html doc where appropriate
|
||||
document.title = doc.title;
|
||||
var hlinks = htmlTrimmed.querySelectorAll("a");
|
||||
for (var i = 0; i < hlinks.length; i++) {
|
||||
if (hlinks[i].href.replace(queryLoc, "").startsWith("/")) {
|
||||
// Replace either http://<somehost>/<somedoc> or http://<somehost> with "" so that:
|
||||
// 1.) links to elements on the same page work
|
||||
// 2.) disable cross-origin requests
|
||||
var fixedURL = hlinks[i].href.replace(windowLoc.split('#')[0], "").replace(queryLoc, "")
|
||||
// If the remaining character is the hash, this is a same-page section link
|
||||
// There are two cases here;
|
||||
// 1.) The hash-url is just a typical page-link
|
||||
// 2.) The hash-url is a page content reference
|
||||
if (fixedURL.contains("#page=")) {
|
||||
pageLink.add(fixedURL);
|
||||
|
||||
}
|
||||
else if (fixedURL.startsWith("#")){
|
||||
fixedURL = requestURL + fixedURL;
|
||||
}
|
||||
// selector is the selector used to select the element. Use body if the whole page is required
|
||||
hlinks[i].href = queryRequest + "?selector=" + selector + "&url=" + fixedURL;
|
||||
}
|
||||
}
|
||||
// Paste the fetched html into this doc; set styles of the root element
|
||||
document.getElementById('renderspot').innerHTML = htmlTrimmed.innerHTML;
|
||||
document.getElementById("renderspot").classList = htmlTrimmed.classList;
|
||||
// Find and run scripts
|
||||
var scripts = document.getElementById("renderspot").querySelectorAll("script");
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
if (scripts[i].innerText) {
|
||||
eval(scripts[i].innerText);
|
||||
} else {
|
||||
fetch(scripts[i].src).then(function (data) {
|
||||
data.text().then(function (r) {
|
||||
eval(r);
|
||||
})
|
||||
});
|
||||
}
|
||||
// To not repeat the element
|
||||
scripts[i].parentNode.removeChild(scripts[i]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
// In case of an error url, just use the standard 404 page
|
||||
fetch(queryLoc + "/404")
|
||||
.then(function (data) {
|
||||
return data.text();
|
||||
})
|
||||
.then(function (html) {
|
||||
document.getElementById('capsule').innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#capsule {
|
||||
padding-right: 15px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body margin="0">
|
||||
<div id="capsule" class="ui container">
|
||||
<!-- style="height: 100%; width: 100%" -->
|
||||
<div id="renderspot" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +0,0 @@
|
||||
<script>
|
||||
function cleanContent()
|
||||
{
|
||||
var $iFrameContents = $('iframe').contents(),
|
||||
$entryContent = $iFrameContents.find('div.file-view');
|
||||
$iFrameContents.find('html').replaceWith($entryContent);
|
||||
// Next restore the style-sheets
|
||||
var stylesheet = $('iframe').contents().find('link[rel="stylesheet"]').prependTo($iFrameContents.find('div.file-view'));
|
||||
}
|
||||
$('iframe').load( function(){
|
||||
//put your iframe code here
|
||||
cleanContent();
|
||||
});
|
||||
</script>
|
||||
<iframe width="100%" height="100%" onLoad="cleanContent()" src="https://git.software.kauripeak.co.nz/BrychanD/JavaECS-Docs/src/branch/master/README.md" frameborder="0"></iframe>
|
||||
@@ -1,4 +1,4 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [component](./dir.md) | component[]().md*
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [component](./dir.md) | Component[]().md*
|
||||
# Component
|
||||
|
||||
### Contents
|
||||
@@ -45,7 +45,7 @@ I.e.:
|
||||
|
||||
The `position` component might not have a `position_system`, but may be utilised by the `collision_system`, which may use `position.x` and `position.y` to determine the location of the entity.
|
||||
|
||||
See [System](../system/system.md) for more information.
|
||||
See [System](../system/System.md) for more information.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [component](./dir.md) | ComponentArray[]().md*
|
||||
# Component Array
|
||||
| **In this Section** |
|
||||
|-|
|
||||
| [About](#about) |
|
||||
| [Implementation](#implementation) |
|
||||
| [Constructors](#constructors) |
|
||||
| [Methods](#methods) |
|
||||
| [Fields](#fields) |
|
||||
| [Examples](#examples)|
|
||||
| [Notes](#notes)|
|
||||
|
||||
## About
|
||||
The `ComponentArray` class defines the a common structure that all component data is stored in.
|
||||
|
||||
## Implementation
|
||||
Associatively maps an entity to the index position of its component data.
|
||||
|
||||
See [ComponentArray.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/ComponentArray.java) for the full implementation.
|
||||
|
||||
## Constructors
|
||||
Default constructor
|
||||
``` java
|
||||
public ComponentArray(){}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
|
||||
### getData
|
||||
``` java
|
||||
protected Object getData(int entity);
|
||||
```
|
||||
Gets the data Object associated with the entity. Returns `null` if the object was not found.
|
||||
|
||||
<br>
|
||||
|
||||
### insertData
|
||||
``` java
|
||||
protected boolean insertData(int entity, Object component);
|
||||
```
|
||||
Inserts the specified `component` and associates it with the entity. If the entity alread has data associated to it, then returns `false`, without adding data.
|
||||
|
||||
<br>
|
||||
|
||||
### moveData
|
||||
``` java
|
||||
protected int moveData(int sourceEntity, int destinationEntity);
|
||||
```
|
||||
'Moves' data from the `sourceEntity` to the `destinationEntity`. Actual implementation copies the data Object associated with the key, and inserts it associated with the new entity.
|
||||
Returns `0` if the operation succeeded, `-1` if the object data was null, `-2` if a `NullPointerException` occurred, and `-3` if inserting the new data failed.
|
||||
|
||||
<br>
|
||||
|
||||
### removeData
|
||||
``` java
|
||||
protected boolean removeData(int entity);
|
||||
```
|
||||
Returns `true` if it removed the specified entity's data. If the entity does not exist (data isn't mapped to that entity), then returns `false`.
|
||||
|
||||
<br>
|
||||
|
||||
## Fields
|
||||
### componentArray
|
||||
``` java
|
||||
private List<Object> componentArray = new ArrayList<>();
|
||||
```
|
||||
The `List<>` containing the component Object data
|
||||
|
||||
<br>
|
||||
|
||||
### componentDataEntityMap
|
||||
``` java
|
||||
private Map<Integer, Integer> componentDataEntityMap = new HashMap<>();
|
||||
```
|
||||
The mapped list of component data indicies to entities.
|
||||
|
||||
<br>
|
||||
|
||||
### entityComponentDataMap
|
||||
``` java
|
||||
private Map<Integer, Integer> entityComponentDataMap = new HashMap<>();
|
||||
```
|
||||
The mapped list of entities to component data indicies.
|
||||
@@ -0,0 +1,125 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [component](./dir.md) | ComponentManager[]().md*
|
||||
# Component Array
|
||||
| **In this Section** |
|
||||
|-|
|
||||
| [About](#about) |
|
||||
| [Implementation](#implementation) |
|
||||
| [Constructors](#constructors) |
|
||||
| [Methods](#methods) |
|
||||
| [Fields](#fields) |
|
||||
| [Examples](#examples)|
|
||||
| [Notes](#notes)|
|
||||
|
||||
## About
|
||||
The `ComponentArray` class defines the a common structure that all component data is stored in.
|
||||
|
||||
## Implementation
|
||||
Associatively maps an entity to the index position of its component data.
|
||||
|
||||
See [ComponentManager.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/ComponentManager.java) for the full implementation.
|
||||
|
||||
## Constructors
|
||||
Default constructor
|
||||
``` java
|
||||
public ComponentManager(){}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
|
||||
### addComponentToEntity
|
||||
``` java
|
||||
protected void addComponentToEntity(Type componentType, Object componentData, int entity);
|
||||
```
|
||||
Adds the specified component to the provided entity. Returns `true` if successful, `false` if the component is already associated to the entity.
|
||||
|
||||
<br>
|
||||
|
||||
### entityDestroyed
|
||||
``` java
|
||||
public void entityDestroyed(int entity);
|
||||
```
|
||||
Signals to the `ComponentManager` the entity was destroyed. All component data references should be removed.
|
||||
|
||||
<br>
|
||||
|
||||
### getComponent
|
||||
``` java
|
||||
public Object getComponent(Type componentType, int entity);
|
||||
```
|
||||
Gets the component data associated with the entity, or `null` if it was not found.
|
||||
* The result of this operation should be cast back to the specified `Type`
|
||||
|
||||
<br>
|
||||
|
||||
### getComponentIndex
|
||||
``` java
|
||||
protected Integer getComponentIndex(Type type);
|
||||
```
|
||||
Gets the registration index of the provided component type. Returns the index, or `-1` if the component isn't registered.
|
||||
|
||||
<br>
|
||||
|
||||
### getComponentType
|
||||
``` java
|
||||
protected Type getComponentType(Integer index);
|
||||
```
|
||||
Gets the registration type of the provided component index. Returns the index, or `null` if the component isn't registered.
|
||||
|
||||
<br>
|
||||
|
||||
### moveComponentData
|
||||
``` java
|
||||
protected void moveComponentData(int sourceEntity, int destinationEntity, Type component);
|
||||
```
|
||||
Moves a single component data from one entity to another. Returns `true` if the component was moved successfully, else `false`.
|
||||
|
||||
<br>
|
||||
|
||||
### moveAllComponentData
|
||||
``` java
|
||||
protected void moveAllComponentData(int sourceEntity, int destinationEntity, BitSet sourceRegistrations);
|
||||
```
|
||||
Moves all component data from one entity to another.
|
||||
|
||||
<br>
|
||||
|
||||
### registerComponent
|
||||
``` java
|
||||
protected boolean registerComponent(Type type);
|
||||
```
|
||||
Registers the component type. Returns `true` if successful, else `false`.
|
||||
|
||||
<br>
|
||||
|
||||
### removeComponentFromEntity
|
||||
``` java
|
||||
public boolean removeComponentFromEntity(Type componentType, int entity);
|
||||
```
|
||||
Removes the specified component from the entity. Returns `true` if successful, else `false`.
|
||||
|
||||
<br>
|
||||
|
||||
## Fields
|
||||
### componentArrays
|
||||
``` java
|
||||
private Map<Type, ComponentArray> componentArrays = new HashMap<>();
|
||||
```
|
||||
Maps the component `Type` to its [ComponentArray](./ComponentArray.md)
|
||||
|
||||
<br>
|
||||
|
||||
### componentPosIndex
|
||||
``` java
|
||||
private Map<Type, Integer> componentPosIndex = new HashMap<>();
|
||||
```
|
||||
The mapped list of component types to the registration indices.
|
||||
|
||||
<br>
|
||||
|
||||
### indexComponentType
|
||||
``` java
|
||||
private Map<Integer, Type> indexComponentType = new HashMap<>();
|
||||
```
|
||||
The mapped list of registration indices to component types.
|
||||
@@ -1,4 +1,10 @@
|
||||
*| [JavaECS](../README.md) | [docs](../overview.md) | component*
|
||||
# Overview
|
||||
### In this folder
|
||||
[component.md](./component.md)
|
||||
* [Component.md](./Component.md)
|
||||
* [componentArray.md](./ComponentArray.md)
|
||||
* [componentManager.md](./ComponentManager.md)
|
||||
|
||||
### See source files:
|
||||
* [componentArray.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/ComponentArray.java)
|
||||
* [componentManager.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/ComponentManager.java)
|
||||
@@ -1,4 +1,4 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [entity](./dir.md) | entity[]().md*
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [entity](./dir.md) | Entity[]().md*
|
||||
# Entity
|
||||
|
||||
### Contents
|
||||
@@ -22,7 +22,7 @@ e.g. character, vehicle, effect etc.
|
||||
|
||||
___An entity contains no further data.___
|
||||
|
||||
In order to be useful, its identifier must be registered to one or more [components](../component/component.md).
|
||||
In order to be useful, its identifier must be registered to one or more [components](../component/Component.md).
|
||||
|
||||
|
||||
Entities are also initialised with a Java [BitSet](https://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html). Each bit represents the index of a component, to determine which component an entity is registered to.
|
||||
@@ -34,6 +34,6 @@ void todo();
|
||||
```
|
||||
|
||||
## Notes
|
||||
* The only requirement for a Entity is that it has a unique ID. A more advanced [entity manager](../manager/entity_manager.md) could implement an ID system with ID regions, or using named IDs.
|
||||
* The only requirement for a Entity is that it has a unique ID. A more advanced [entity manager](./EntityManager.md) could implement an ID system with ID regions, or using named IDs.
|
||||
Another approach could be to use the first byte as a grouping, in a similar way to how Bethesda Softworks' Skyrim utilises the first byte as a mod index
|
||||
* The maximum number of entities is limited by the size of the container used to store it. E.g., for a 32-bit unsigned integer, there are ~4.3 billion ID's available. But keep in mind that such a large amount of IDs will take significant time for each system to consider.
|
||||
@@ -0,0 +1,136 @@
|
||||
*| [JavaECS](../../README.md) | [docs](../overview.md) | [entity](./dir.md) | EntityManager[]().md*
|
||||
# Entity Manager
|
||||
| **In this Section** |
|
||||
|-|
|
||||
| [About](#about) |
|
||||
| [Implementation](#implementation) |
|
||||
| [Constructors](#constructors) |
|
||||
| [Methods](#methods) |
|
||||
| [Fields](#fields) |
|
||||
| [Examples](#examples)|
|
||||
| [Notes](#notes)|
|
||||
|
||||
## About
|
||||
Controls adding and removing entities, and registration and unregistration of components to specific entities.
|
||||
|
||||
## 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.
|
||||
|
||||
See [EntityManager.java](/BrychanD/JaveECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/EntityManager.java)
|
||||
|
||||
## Constructors
|
||||
``` java
|
||||
protected EntityManager(){}
|
||||
```
|
||||
The default constructor initialises [unusedEntities](#unusedentities) to a new queue containing [maxSize](#maxsize) (`1024`) unique integers.
|
||||
|
||||
<br>
|
||||
|
||||
``` java
|
||||
protected EntityManager(int maxEntities){}
|
||||
```
|
||||
Initialises [unusedEntities](#unusedEntities) to a new queue containing `maxEntities` unique integers.
|
||||
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
### addEntity
|
||||
``` java
|
||||
protected Integer addEntity();
|
||||
```
|
||||
Pops the next available entity index off the queue, and returns its value.
|
||||
|
||||
Returns `-1` if there is no remaining unused entities.
|
||||
|
||||
<br>
|
||||
|
||||
### getMaxSize
|
||||
``` java
|
||||
protected Integer getMaxSize();
|
||||
```
|
||||
Gets the current maximum entity count.
|
||||
|
||||
<br>
|
||||
|
||||
### getRegistrations
|
||||
``` java
|
||||
protected BitSet getRegistrations(int entity);
|
||||
```
|
||||
Returns the `BitSet` of registrations the `entity` has.
|
||||
|
||||
If the call results in an `IndexOutOfBoundsError`, then returns a new BitSet();
|
||||
|
||||
<br>
|
||||
|
||||
### registerComponent
|
||||
``` java
|
||||
protected void registerComponent(int component, int entity);
|
||||
```
|
||||
Sets the bit `component` in [entityRegistrations](#entityRegistrations) for `entity` to `true`.
|
||||
|
||||
<br>
|
||||
|
||||
### removeEntity
|
||||
``` java
|
||||
protected void removeEntity(int entity);
|
||||
```
|
||||
Adds the entity's index back to the unused queue, and clears the assigned registration bits
|
||||
#### Note
|
||||
>This function should not be called directly. Doing so will leave component data in memory, and will cause desynchronisation of the system registrations.
|
||||
|
||||
<br>
|
||||
|
||||
### resize
|
||||
``` java
|
||||
protected boolean resize(int newSize, SystemManager systemManager, ComponentManager componentManager);
|
||||
```
|
||||
Resizes the currentSize of the entity manager. Moves elements above `newSize` if space is available.
|
||||
|
||||
If the current defined elements won't fit, the operation returns `false` and the previous state is maintained.
|
||||
|
||||
<br>
|
||||
|
||||
### setRegistrations
|
||||
``` java
|
||||
protected void setRegistrations(int entity, BitSet registrations);
|
||||
```
|
||||
Sets the entity's registrations to the provided BitSet
|
||||
|
||||
<br>
|
||||
|
||||
### unregisterComponent
|
||||
``` java
|
||||
protected void unregisterComponent(int component, int entity);
|
||||
```
|
||||
Sets the bit `component` in [entityRegistrations](#entityRegistrations) for `entity` to `false`.
|
||||
|
||||
Returns `true` if successful.
|
||||
|
||||
<br>
|
||||
|
||||
## Fields
|
||||
### entityRegistrations
|
||||
``` java
|
||||
List<BitSet> entityRegistrations;
|
||||
```
|
||||
The BitSet of registrations for each entity
|
||||
|
||||
<br>
|
||||
|
||||
### maxSize
|
||||
``` java
|
||||
private int maxSize = 1024;
|
||||
```
|
||||
The current maximum entity count.
|
||||
|
||||
Default `1024`
|
||||
|
||||
|
||||
### unusedEntities
|
||||
``` java
|
||||
Queue<Integer> unusedEntities;
|
||||
```
|
||||
The queue of unused entity values
|
||||
|
||||
+5
-1
@@ -1,4 +1,8 @@
|
||||
*| [JavaECS](../README.md) | [docs](../overview.md) | entity*
|
||||
# Overview
|
||||
### In this folder
|
||||
[entity.md](./entity.md)
|
||||
* [Entity.md](./Entity.md)
|
||||
* [EntityManager.md](./EntityManager.md)
|
||||
|
||||
### See source file:
|
||||
* [EntityManager.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/EntityManager.java)
|
||||
+2
-2
@@ -10,5 +10,5 @@
|
||||
|[Entity](./entity/Entity.md) |
|
||||
|[Component](./component/Component.md)|
|
||||
|[System](./system/System.md)|
|
||||
|[event](./)|
|
||||
|[GameEngine](./)|
|
||||
|<span style="color:red">[event](./)</span>|
|
||||
|<span style="color:red">[GameEngine](./)</span>|
|
||||
|
||||
@@ -30,19 +30,20 @@ public ECSSystem(){}
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
> These two functions are labelled as abstract (must be implemented) to indicate the type of implementation required.
|
||||
> It is not required to add functionality to them. Parametrised versions can also be added.
|
||||
### init
|
||||
``` java
|
||||
public void init(){}
|
||||
abstract 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(){}
|
||||
abstract void update();
|
||||
```
|
||||
Functionality that needs to be called regularly should be defined here
|
||||
* `update()` is intended to be called regularly
|
||||
|
||||
@@ -18,63 +18,68 @@ 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.
|
||||
|
||||
See [SystemManager.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/SystemManager.java) for the full implementation.
|
||||
|
||||
## Constructors
|
||||
Default constructor
|
||||
``` java
|
||||
public SystemManager(){}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Methods
|
||||
|
||||
### entityDestroyed
|
||||
``` java
|
||||
public void entityDestroyed(int entity);
|
||||
protected void entityDestroyed(int entity);
|
||||
```
|
||||
Removes the specified entity from every system, if it was associated
|
||||
Signals the SystemManager that an entity was destroyed. Removes the entity from each system's tracked entities
|
||||
|
||||
<br>
|
||||
|
||||
### entitySignatureChanged
|
||||
``` java
|
||||
public void entitySignatureChanged(int entity, BitSet entitySignature);
|
||||
protected void entityRegistrationsChanged(int entity, BitSet entityRegistrations);
|
||||
```
|
||||
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.
|
||||
Signals the SystemManager that an entity had its registrations changed; iterates through each system validating the entities list
|
||||
|
||||
<br>
|
||||
|
||||
### registerSystem
|
||||
``` java
|
||||
public boolean registerSystem(String systemName, ECSSystem system);
|
||||
protected boolean registerSystem(Type systemType, ECSSystem system);
|
||||
```
|
||||
Registers the specified system name and system reference to this manager.
|
||||
|
||||
*adds a `systemName:system` pair to [systems](#systems)*
|
||||
*adds a `systemType:system` pair to [systems](#systems)*
|
||||
|
||||
*and a `systemName:new BitSet()` pair to [signatures](#signatures)*
|
||||
*adds a `systemType:new BitSet()` pair to [registrationSignatures](#registrationSignatures)*
|
||||
|
||||
<br>
|
||||
|
||||
### setSignature
|
||||
``` java
|
||||
public void setSignature(String system, BitSet registrations);
|
||||
protected void setRegistrationSignature(Type systemType, BitSet registrations);
|
||||
```
|
||||
Sets the required signature of the `system`
|
||||
Sets the registrations the system requires
|
||||
|
||||
<br>
|
||||
|
||||
## Fields
|
||||
### signatures
|
||||
### registrationSignatures
|
||||
``` java
|
||||
Map<String, BitSet> signatures = new HashMap<>();
|
||||
private Map<Type, BitSet> registrationSignatures = new HashMap<>()
|
||||
```
|
||||
The mapped list of required registrations
|
||||
|
||||
<br>
|
||||
|
||||
### systems
|
||||
``` java
|
||||
Map<String, ECSSystem> systems = new HashMap<>();
|
||||
private Map<Type, ECSSystem> systems = new HashMap<>();
|
||||
```
|
||||
The mapped list of system instances
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+8
-5
@@ -1,7 +1,10 @@
|
||||
*| [JavaECS](../README.md) | [docs](../overview.md) | system*
|
||||
# Overview
|
||||
| **In this folder** |
|
||||
|-|
|
||||
| [ECSSystem.md](./ECSSystem.md) |
|
||||
| [System.md](./System.md) |
|
||||
| [SystemManager.md](./SystemManager.md) |
|
||||
### In this folder
|
||||
* [ECSSystem.md](./ECSSystem.md)
|
||||
* [System.md](./System.md)
|
||||
* [SystemManager.md](./SystemManager.md)
|
||||
|
||||
### See source files:
|
||||
* [ECSSystem.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/ECSSystem.java)
|
||||
* [SystemManager.java](/BrychanD/JavaECS/src/branch/master/javaecs/src/main/java/nz/ac/massey/javaecs/SystemManager.java)
|
||||
Reference in New Issue
Block a user