/*
* This file is part of the Haven & Hearth game client.
* Copyright (C) 2009 Fredrik Tolf <fredrik@dolda2000.com>, and
* Björn Johannessen <johannessen.bjorn@gmail.com>
*
* Redistribution and/or modification of this file is subject to the
* terms of the GNU Lesser General Public License, version 3, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Other parts of this source tree adhere to other copying
* rights. Please see the file `COPYING' in the root directory of the
* source tree for details.
*
* A copy the GNU Lesser General Public License is distributed along
* with the source tree of which this file is a part in the file
* `doc/LPGL-3'. If it is missing for any reason, please see the Free
* Software Foundation's website at <http://www.fsf.org/>, or write
* to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
*/
package haven;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.util.*;
import java.lang.reflect.Constructor;
public abstract class Sprite implements Rendered {
public final Resource res;
public final Owner owner;
public static List<Factory> factories = new LinkedList<Factory>();
static {
factories.add(SkelSprite.fact);
factories.add(AnimSprite.fact);
factories.add(StaticSprite.fact);
factories.add(AudioSprite.fact);
}
public interface Owner {
public Random mkrandoom();
public Resource.Neg getneg();
public Glob glob();
}
public static class FactMaker implements Resource.PublishedCode.Instancer {
public Factory make(Class<?> cl) throws InstantiationException, IllegalAccessException {
if(Factory.class.isAssignableFrom(cl))
return(cl.asSubclass(Factory.class).newInstance());
if(Sprite.class.isAssignableFrom(cl))
return(mkdynfact(cl.asSubclass(Sprite.class)));
return(null);
}
}
@Resource.PublishedCode(name = "spr", instancer = FactMaker.class)
public interface Factory {
public Sprite create(Owner owner, Resource res, Message sdt);
}
public static Factory mkdynfact(Class<? extends Sprite> cl) {
try {
final Constructor<? extends Sprite> cons = cl.getConstructor(Owner.class, Resource.class);
return(new Factory() {
public Sprite create(Owner owner, Resource res, Message sdt) {
return(Utils.construct(cons, owner, res));
}
});
} catch(NoSuchMethodException e) {}
try {
final Constructor<? extends Sprite> cons = cl.getConstructor(Owner.class, Resource.class, Message.class);
return(new Factory() {
public Sprite create(Owner owner, Resource res, Message sdt) {
return(Utils.construct(cons, owner, res, sdt));
}
});
} catch(NoSuchMethodException e) {}
throw(new RuntimeException("Could not find any suitable constructor for dynamic sprite"));
}
public static class ResourceException extends RuntimeException {
public Resource res;
public ResourceException(String msg, Resource res) {
super(msg + " (" + res + ", from " + res.source + ")");
this.res = res;
}
public ResourceException(String msg, Throwable cause, Resource res) {
super(msg + " (" + res + ", from " + res.source + ")", cause);
this.res = res;
}
}
protected Sprite(Owner owner, Resource res) {
this.res = res;
this.owner = owner;
}
public static int decnum(Message sdt) {
if(sdt == null)
return(0);
int ret = 0, off = 0;
while(!sdt.eom()) {
ret |= sdt.uint8() << off;
off += 8;
}
return(ret);
}
public static Sprite create(Owner owner, Resource res, Message sdt) {
{
Factory f = res.getcode(Factory.class, false);
if(f != null)
return(f.create(owner, res, sdt));
}
for(Factory f : factories) {
Sprite ret = f.create(owner, res, sdt);
if(ret != null)
return(ret);
}
throw(new ResourceException("Does not know how to draw resource " + res.name, res));
}
public void draw(GOut g) {}
public abstract boolean setup(RenderList d);
public boolean tick(int dt) {
return(false);
}
public void dispose() {
}
}