I have a bit of a quandary in terms of dependencies and interfaces.
I have Rebirth ( http://triangularpixels.net/games/tools/rebirth/ ) which handles all game resources (images, sounds, etc. ). Resources all implement the Resource interface:
public interface Resource
{
public void setName(String name);
public String getName();
public void setIO(ResourceIO io);
public void setFileMonitor(FileMonitor fileMonitor);
public void destroy();
public void parse(Element element, List<Resource> outChildResources);
public void create(ResourceHandleList resources);
public boolean mainCreate();
}
It’s a bit wider than it needs to be, but that can be changed. One of the main things Rebirth does is hot-reloading when files change on disk. To do that resources are accessed via a ResourceHandle, eg:
// Find resource (init time)
ResourceHandle<DiskImageResource> icon = resources.get(“icon.image”);
// Usage - get actual image and use to draw
DiskImageResource actualIcon = icon.get();
screen.draw(actualIcon, x, y);
So you might end up with DiskImageResource which looks something like:
class DiskImageResource implements Resource
{
// .. stuff ..
public void create(ResourceHandleList resources)
{
this.image = ImageIO.load(imagePath);
}
}
This works great until I have to start passing resources into other sub systems. For example I want my Screen to have something like:
public void draw(IImage image);
where IImage is just a bare-bones image with rgb data and width/height.
The problem: I can’t have a Resource since ResourceHandle is defined as ResourceHandle.
Possible solutions:
-
Make IImage extend Resource. Works, but now I’ve got resource dependancies in my graphics subsystem (or whatever). Also not great because really IImage isn’t a Resource, it’s just doing that to play nice with another part of the code.
-
Change to ResourceHandle so resource handle can hold any object. Removes the awkward dependency, but means I have to do odd casts and/or instanceof inside the resource manager and possibly loose some type safety.
-
Kill off ResourceHandle completely and instead do scary voodoo with java.lang.Proxy. Doesn’t necessarily solve the problem of having a root Resource interface though.
-
Something else I’ve not thought off.
It’s the kind of thing that really needs proper python-style duck typing to work I guess. I don’t mind other subsystems being dependant on ResourceHandle because that’s a tiny concrete class (it really just has get() and that’s it), but I don’t like forcing everything else to use an external base class.
Thoughts?