我正在考虑移植 java 库Artemis。一个实体系统框架。我还没有开始。相反,我一直在分析 java 代码如何组合在一起的内部工作。我知道有一半的CPP 端口。
我查看了这两个代码并注意到 java 代码更优雅地放置了某些东西。主要有以下几点:
package com.artemis;
import java.util.HashMap;
public class ComponentTypeManager {
private static HashMap<Class<? extends Component>, ComponentType> componentTypes = new HashMap<Class<? extends Component>, ComponentType>();
public static final ComponentType getTypeFor(Class<? extends Component> c){
ComponentType type = componentTypes.get(c);
if(type == null){
type = new ComponentType();
componentTypes.put(c, type);
}
return type;
}
public static long getBit(Class<? extends Component> c){
return getTypeFor(c).getBit();
}
public static int getId(Class<? extends Component> c){
return getTypeFor(c).getId();
}
}
和componentType“对象”
package com.artemis;
public class ComponentType {
private static long nextBit = 1;
private static int nextId = 0;
private long bit;
private int id;
public ComponentType() {
init();
}
private void init() {
bit = nextBit;
nextBit = nextBit << 1;
id = nextId++;
}
public long getBit() {
return bit;
}
public int getId() {
return id;
}
}
基本上 componentTypeManager 所做的是将 componentType 映射到类类型。这使它在添加新组件时变得动态。
C++移植方案如下:
#ifndef __COMPONENT_TYPE_H__
#define __COMPONENT_TYPE_H__
namespace SGF
{
enum ComponentType
{
CT_TRANSFORM = 0,
CT_HEALTH,
CT_RENDERABLE,
CT_RIGID_BODY,
CT_JOINT,
CT_LAST
};
// Component type bits. Used by the entity systems to determine if an entity is compatible.
const unsigned int CT_TRANSFORM_BIT = 1 << CT_TRANSFORM;
const unsigned int CT_HEALTH_BIT = 1 << CT_HEALTH;
const unsigned int CT_RENDERABLE_BIT = 1 << CT_RENDERABLE;
const unsigned int CT_RIGID_BODY_BIT = 1 << CT_RIGID_BODY;
const unsigned int CT_JOINT_BIT = 1 << CT_JOINT;
};
#endif
这里 ComponentManager 完全被忽略了。而是使用枚举。我的问题是您必须将新的组件类型添加到枚举器和常量作为“类型”标识符。java 框架允许你传递一个组件类类型来识别它的 id。
我的问题是,如果没有为每个新组件硬编码枚举器类型,我将如何获得类似的效果,即传递一个类型来映射它的 id,就像 Java 代码一样?我知道 C++ 不支持类类型作为参数。所以这对我来说是相当令人难以置信的。