Last active
August 29, 2015 14:06
-
-
Save maxov/804ed227f979603b3c37 to your computer and use it in GitHub Desktop.
An example of a simple sponge-based Component-Entity-System.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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