An improved RDBMS-style
(based on: RDBMS with code in systems)
As per RDBMS + code in Systems, i.e.:
- disallow mixing "code" with your data
- create monolithic, opaque "Systems" which contain all the code necessary for a chunk of functionality
…but with the following improvements:
- an object ("MetaEntity") for each Entity, which makes it much easier and faster to write code that uses the Entity System
NOTE: you shouldn't use Beta unless you're sure you understand what it's based upon - this EntityObject is a dangerous thing. If you even SLIGHTLY misunderstand it, you will break your entire Entity System!
Extensions to this Approach
- (none yet)
Implementation
Concepts
Summary of changes:
- The MetaEntity class is added
- The Component and ComponentType are re-factored into a single class, and we use runtime Class information (available in most languages) - reduces some error-prone code, and makes other code more readable and concise
- The EntityManager gets a bunch of "essential" methods that any "real" Entity System would need:
- "removeComponent" (obvious)
- "getAllComponentsOnEntity" (enables you to quickly debug entities by looking at their components and checking they have the ones you expected)
- "freeze"/"unFreeze" (while frozen, an EntityManager ignores all calls to create, modify, or delete entities)
- … (integer) Entity
- NEW: (class with implementation) MetaEntity
- REMOVED: (enum) ComponentType
- ALTERED: (interface OR empty base-class) Component
- … (interface OR empty base-class) System
- ALTERED: (class with implementation) EntityManager
Data Classes
MetaEntity
This contains only two pieces of data:
- the actual Entity (remember: that's an Integer - nothing more or less)
- the EntityManager which is managing that Entity
This enables you to seamlessly have multiple independent EntityManagers, without ever accidentally writing code that operates on an Entity in the "wrong" EntityManager. Because Entities are merely Integers, that's an easy mistake to make when using multiple EntityManagers…
It also contains a LARGE number of convenience methods, that make your code more concise and easier to maintain.
NOTE: in performance-critical code, you may need to write your code using raw Entity's, and ignoring the MetaEntity, since the MetaEntity is adding the overhead of at least one extra reference per Entity, and in some languages it's adding CONSIDERABLE overhead just for being an OOP Object (Java, for instance, has a substantial per-object overhead).
Entity (unchanged from RDBMS with Code in Systems)
Component
This exists purely to make method-signatures type-safe. We need to know that certain objects are valid instances of a "component" (so we use this superclass to indicate that)
System (unchanged from RDBMS with Code in Systems)
EntitySystem Implementation Classes
Each subclass of Component
ALTERED: No methods needed any more.
System (unchanged from RDBMS with Code in Systems)
EntityManager
Internally, the class has the following variables:
- LIST: all entities in existence (so it never duplicates entity-IDs!)
- MAP: from "Entity + ComponentType" to "concrete Component subclass"
Internally, the class has the following functions:
- … (Component) getComponent( Entity, Component subclass );
- … (List) getAllComponentsOfType( Component subclass );
- … (List) getAllEntitiesPossessingComponent( Component subclass );
- ADDED: (List) getAllComponentsOnEntity( Entity );
- ADDED: (void) removeComponent( Entity, Component instance );
- ADDED: (boolean) hasComponent( Entity, Component subclass)
- … (void) addComponent( Entity, Component instance );
- … (int) createEntity;
- … (void) killEntity( Entity );
- ADDED: (void) freeze();
- ADDED: (void) unFreeze();
Source Code
Java
Change notes
- Because "System" is a reserved classname in Java, the "System" class has been renamed to "SubSystem"; maybe we need a better name for this.
Github
GitHub: https://github.com/adamgit/Entity-System-RDBMS-Beta--Java- - NB: Wikidot SUCKS and they corrupt the URL when you click on it; you MUST copy/paste this URL!
Free Pascal
Change notes
- This is basically a Free Pascal port of the Java implementation.
- Because the "System" unit already exists in Free Pascal, the unit containing the "ISystem" interface is named "EntitySystem" (unit entitysystem.pas).
- This implementation uses the TDictionary class that provides some of the same features as the Delphi class with the same name.
TuxFamily
Git: https://git.tuxfamily.org/pascalecs/pascalecs.git
Subversion: http://websvn.tuxfamily.org/listing.php?repname=fevolution%2Fecs
Objective-C
Change notes
Entity is implemented as a class instead of a plain uint; this is technically incorrect, although the rest of the system works as expected
GitHub
(not created yet)