Skip to content

Instantly share code, notes, and snippets.

@maxov
Last active August 29, 2015 14:06
Show Gist options
  • Save maxov/804ed227f979603b3c37 to your computer and use it in GitHub Desktop.
Save maxov/804ed227f979603b3c37 to your computer and use it in GitHub Desktop.
An example of a simple sponge-based Component-Entity-System.
package org.spongepowered.api.
import java.util.*;
public class Hello {
public static void main(String[] args) {
EntityComponentSystem ecs = new EntityComponentSystem();
Entity e1 = new Entity("John");
Entity e2 = new Entity("Jane");
ecs.register(e1, new HealthComponent(10.5));
ecs.register(e2, new HealthComponent(6.0));
ecs.register(e1, new HealthComponent(9.4));
ecs.register(e2, new PositionComponent(0.0));
assert ecs.lookup(e1, HealthComponent.class).getHealth() == 9.4;
assert ecs.lookup(e2, HealthComponent.class).getHealth() == 6.0;
assert ecs.lookup(e2, PositionComponent.class).getPosition() == 0.0;
assert !ecs.has(e1, PositionComponent.class);
assert ecs.has(e2, PositionComponent.class);
ecs.remove(e2, PositionComponent.class);
assert !ecs.has(e2, PositionComponent.class);
}
public static interface Component<H> {
}
public static interface ComponentHolder<C> {
}
public static interface ComponentSystem {
public <T extends Component> T lookup(ComponentHolder<? super T> holder, Class<T> clazz);
public <T extends Component> boolean has(ComponentHolder<? super T> holder, Class<T> clazz);
public <T extends Component> void remove(ComponentHolder<? super T> holder, Class<T> clazz);
public <T extends Component> void register(ComponentHolder<? super T> holder, T component);
}
static class Entity implements ComponentHolder<EntityComponent> {
private String name;
Entity(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
static interface EntityComponent extends Component<Entity> {
}
static class HealthComponent implements EntityComponent {
private double health;
private Entity holder;
HealthComponent(double health) {
this.health = health;
}
public double getHealth() {
return health;
}
public void setHealth(double health) {
this.health = health;
}
public Entity getHolder() {
return holder;
}
public void setHolder(Entity holder) {
this.holder = holder;
}
}
static class PositionComponent implements EntityComponent {
private double position;
private Entity holder;
PositionComponent(double position) {
this.position = position;
}
public double getPosition() {
return position;
}
public void setPosition(double position) {
this.position = position;
}
public Entity getHolder() {
return holder;
}
public void setHolder(Entity holder) {
this.holder = holder;
}
}
static class EntityComponentSystem implements ComponentSystem {
private Map<ComponentHolder, List<Component>> registry = new HashMap<ComponentHolder, List<Component>>();
public <T extends Component> T lookup(ComponentHolder<? super T> holder, Class<T> clazz) {
if(registry.containsKey(holder)) {
for(Component c: registry.get(holder)) {
if(clazz.isInstance(c)) return (T) c;
}
return null;
} else {
return null;
}
}
public <T extends Component> boolean has(ComponentHolder<? super T> holder, Class<T> clazz) {
if(registry.containsKey(holder)) {
for(Component c: registry.get(holder)) {
if(clazz.isInstance(c)) return true;
}
return false;
} else {
return false;
}
}
public <T extends Component> void register(ComponentHolder<? super T> holder, T component) {
if(registry.containsKey(holder)) {
Class<? extends Component> clazz = component.getClass();
Iterator<Component> it = registry.get(holder).iterator();
while(it.hasNext()) {
Component c = it.next();
if(clazz.isInstance(c)) {
it.remove();
break;
}
}
registry.get(holder).add(component);
} else {
List<Component> components = new LinkedList<Component>();
components.add(component);
registry.put(holder, components);
}
}
public <T extends Component> void remove(ComponentHolder<? super T> holder, Class<T> clazz) {
if(registry.containsKey(holder)) {
Iterator<Component> it = registry.get(holder).iterator();
while(it.hasNext()) {
Component c = it.next();
if(clazz.isInstance(c)) {
it.remove();
break;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment