Entity Component System

This library implements the entity-component-system pattern in EcmaScript6. This library
was originally based on yagl/ecs, but has been modified
for performance and a focus on assemblages and mixins.
In this ECS implementation components are not only dumb data containers, but are full
mixins that can add functionality to an entity. The method of creating a prototype chain
based on the mixins was derived from this article. Maybe this is more of an
Entity-Mixin-System (EMS)...
Features
- ES6: The library is written entirely in ES6.
- Flexible: You can subclass the Entity or UIDGenerator classes to implement your
own logic.
- Fast: Intelligently batches entities and systems so that the minimum amount
of time is spent on pure iteration.
- Since the eligibility to systems is computed only when the components list
change, and in most cases the overhead of systems eligibility will be computed once
per entity, when added. Therefore there is no overhead for most iterations.
Iteration is often considered as a flaw of ecs pattern.
Getting started
Here is a "minimalist" example of what you can do with this library:
import ECS from '@fae/ecs';
const PositionComponent = (Base) => class extends Base {
constructor() {
super(...arguments);
this._x = 0;
this._y = 0;
}
get x() { return this._x; }
set x(v) { this._x = Math.floor(v); }
get y() { return this._y; }
set y(v) { this._y = Math.floor(v); }
}
const TextureComponent = (Base) => class extends Base {
constructor() {
super(...arguments);
this.texture = new Image();
}
}
class Sprite extends ECS.Entity.with(PositionComponent, TextureComponent) {
constructor(imageUrl) {
super();
this.texture.src = imageUrl;
}
}
class SpecializedSprite extends Sprite.with(SpecialComponent) {}
class RenderSystem extends ECS.System {
constructor(ctx) {
this.ctx = ctx;
}
test(entity) {
return entity.hasComponents(PositionComponent, TextureComponent);
}
update(entity) {
this.ctx.drawImage(entity.texture, entity.x, entity.y);
}
}
const canvas = document.getElementById('renderer');
const ctx = canvas.getContext('2d');
const ecs = new ECS();
ecs.addSystem(new RenderingSystem(ctx));
ecs.addEntity(new Sprite('/img/something.png'));
(function update() {
requestAnimationFrame(update);
canvas.clearRect(0, 0, canvas.width, canvas.height);
ecs.update();
})();