package chu.engine; import java.util.ArrayList; import java.util.PriorityQueue; import java.util.Stack; import java.util.TreeSet; public abstract class Stage { protected TreeSet<Entity> entities; protected Stack<Entity> addStack; protected Stack<Entity> removeStack; public final String soundTrack; public Stage(String soundTrack) { entities = new TreeSet<Entity>(new SortByUpdate()); addStack = new Stack<Entity>(); removeStack = new Stack<Entity>(); this.soundTrack = soundTrack; } public TreeSet<Entity> getAllEntities() { return entities; } public void addEntity(Entity e) { addStack.push(e); e.willBeRemoved = false; } public void removeEntity(Entity e) { if(e != null) { e.flagForRemoval(); if(removeStack.contains(e)){ return; } removeStack.push(e); } } public void update() { for(Entity e : entities) { e.onStep(); e.beginStep(); } processAddStack(); processRemoveStack(); } public void render() { SortByRender comparator = new SortByRender(); PriorityQueue<Entity> renderQueue = new PriorityQueue<Entity>(entities.size()+1, comparator); renderQueue.addAll(entities); while(!renderQueue.isEmpty()) { renderQueue.poll().render(); } } public Entity instanceAt(int x, int y) { for(Entity e : entities) { if(e.x == x && e.y == y && !e.willBeRemoved()) return e; } return null; } public Entity[] allInstancesAt(int x, int y) { ArrayList<Entity> ans = new ArrayList<Entity>(); for(Entity e : entities) { if(e.x == x && e.y == y && !e.willBeRemoved()) ans.add(e); } for(Entity e : addStack) { if(e.x == x && e.y == y && !e.willBeRemoved()) ans.add(e); } Entity[] ret = new Entity[ans.size()]; for(int i=0; i<ret.length; i++) { ret[i] = ans.get(i); } return ret; } public Collidable[] collideableAt(int x, int y) { ArrayList<Collidable> ans = new ArrayList<Collidable>(); for(Entity e : entities) { if(e instanceof Collidable && e.x == x && e.y == y && !e.willBeRemoved()) ans.add((Collidable)e); } for(Entity e : addStack) { if(e instanceof Collidable && e.x == x && e.y == y && !e.willBeRemoved()) ans.add((Collidable)e); } Collidable[] ret = new Collidable[ans.size()]; for(int i=0; i<ret.length; i++) { ret[i] = ans.get(i); } return ret; } public void processAddStack() { while(!addStack.isEmpty()) { Entity e = addStack.pop(); entities.add(e); e.stage = this; } } public boolean willBeRemoved(Entity e) { return removeStack.contains(e); } public void processRemoveStack() { while(!removeStack.isEmpty()) { Entity e = removeStack.pop(); entities.remove(e); addStack.remove(e); //Otherwise some weird shit happens and entities get stuck in limbo } } public abstract void beginStep(); public abstract void onStep(); public abstract void endStep(); }