package com.pointcliki.event;
import org.newdawn.slick.Graphics;
import com.pointcliki.core.ISavable;
import com.pointcliki.core.Entity;
import com.pointcliki.core.Entity.RenderEvent;
/**
* A render rogue is a rogue that is attached to a particular entity. When
* the start method is called, the rogue attaches itself to the entity's
* dispatcher and executes "run" whenever the entity is rendered.
*
* This class is important as it allows entities to be moved easily and perform
* other motions without having to override the render class with custom code.
*
* @author Hugheth
* @since 3
*
* @param <T> The type of event to update the rouge's monitor with
*/
public abstract class RenderRogue<T extends Entity> extends Rogue<T> {
/**
* Serial key
*/
private static final long serialVersionUID = 5904008855949875093L;
protected Minion<IEvent> fRenderHook = null;
protected int fRenderPriority;
/**
* Create a new render rogue
* @param entity Parent entity
* @param monitor Monitor to listen to the rogue's progress
* @param renderPriority The priority of the render minion
*/
public RenderRogue(T entity, Minion<ProgressEvent<T>> monitor, int renderPriority) {
super(entity, monitor);
fRenderPriority = renderPriority;
}
/**
* Override this method to perform some operation during the rendering of
* the associated entity
*
* @param graphics
* @param view
* @param currentTime
*/
protected abstract void run(Graphics graphics, long currentTime);
@Override
public void begin() {
super.begin();
// Add to entity
hookRender();
}
protected void hookRender() {
assert fRenderHook == null: "Render hook should be null";
fRenderHook = new Minion<IEvent>(fRenderPriority) {
@Override
public long run(Dispatcher<IEvent> dispatcher, String type, IEvent event) {
RenderEvent re = (RenderEvent) event;
RenderRogue.this.run(re.graphics(), re.currentTime());
return Minion.CONTINUE;
}
};
fParent.dispatcher().addMinion(Entity.RenderEvent.TYPE, fRenderHook);
}
protected void dehookRender() {
assert fRenderHook != null: "Can't dehook render hook as it hasn't been created!";
fParent.dispatcher().removeMinion(Entity.RenderEvent.TYPE, fRenderHook);
fRenderHook = null;
}
@Override
protected void end() {
dehookRender();
super.end();
}
@Override
public void cancel() {
dehookRender();
super.cancel();
}
@Override
public void pause() {
dehookRender();
super.cancel();
}
@Override
public ISavable snapshot(T entity) throws CloneNotSupportedException {
@SuppressWarnings("unchecked")
RenderRogue<T> clone = (RenderRogue<T>) super.snapshot(entity);
// Release the render hook from the old dispatcher
if (fRenderHook != null) {
dehookRender();
hookRender();
}
return clone;
}
}