我正在为Java游戏引擎制作一个基于组件的系统。
我有不同的系统类来处理不同的事情,例如PhysicsSystem,RenderSystem,EditorSystem等。所有类都继承自BaseSystem,而BaseSystem又实现了一个接口ISystem。
我希望我的所有系统类都有一个ArrayList,但每个系统类中的类型可能不同,这意味着RenderSystem可能有一个RenderComponents列表,而PhysicsSystem有一个PhysicsBodyComponents列表。
是否可以在BaseSystem类或ISystem接口中定义所有派生类随后实现的泛型或抽象列表?我对泛型有一点经验,所以我对此感到有点困惑。
这是我目前的代码。如您所见,我为派生类创建了第二个列表,这是一种浪费。
interface ISystem
{
boolean AddToSystem(Component c);
}
abstract class BaseSystem implements ISystem
{
// can I make this list generic, so it can store any type in derived classes?
// e.g., Component, IRenderable, IPhysics, etc.
protected List<Component> _componentList;
}
class RenderSystem extends BaseSystem
{
// need to make a second list that stores the specific render components
List<IRenderable> _renderList = new ArrayList<IRenderable>();
void Update()
{
for (IRenderable r : _renderList)
r.Render(); // this code is specific to the IRenderable components
}
@Override
public boolean AddToSystem(Component c)
{
boolean succesfullyAdded = false;
if (c instanceof IRenderable)
{
succesfullyAdded = true;
_renderList.add((IRenderable) c);
} else
throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");
return succesfullyAdded;
}
}
答案 0 :(得分:3)
当然,假设所有组件都实现IComponent
,请使用以下内容:
interface ISystem<ComponentType extends IComponent> {
public boolean AddToSystem(ComponentType c);
}
如果您不想拥有硬类型依赖项,则可以删除extends IComponent
,但这会使处理系统列表更加困难。
答案 1 :(得分:1)
我认为你需要这样的东西
private static abstract class AbstractClass<T> {
final List<T> objects = new ArrayList<T>();
}
private static class ComponentHolder extends AbstractClass<Component> {
public void add(final Component c) {
objects.add(c);
}
public Component getComponent(final int index) {
return objects.get(index);
}
}
在您的示例中,它将是这样的:
abstract class BaseSystem<T> implements ISystem
{
protected List<T> _componentList = new ArrayList<T>();
}
class RenderSystem extends BaseSystem<IRenderable>
{
void Update()
{
for (IRenderable r : _componentList)
r.Render(); // this code is specific to the IRenderable components
}
@Override
public boolean AddToSystem(Component c)
{
boolean succesfullyAdded = false;
if (c instanceof IRenderable)
{
succesfullyAdded = true;
_componentList.add((IRenderable) c);
} else
throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");
return succesfullyAdded;
}
}