2012-06-23 30 views
2

我正在考虑移植Java库Artemis。一个实体系统框架。我还没开始呢。相反,我一直在分析如何将java代码放在一起的内部工作。我知道有一半工作了CPP port移植Java:C++ - >类的类型

我查看了两个代码,并注意到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(); 
    } 
} 

而组件类型“对象”

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确实是一个组件类型映射到一个类类型。 这使得它在添加新组件时具有动态性。

的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。

我的问题是,我将如何获得类似的效果,将类型映射为像Java代码那样的id,而不用为每个新组件编写枚举类型的硬编码? 我知道C++不支持类类型作为参数。所以这对我来说很让人难以置信。

+0

可能'std :: type_info'用作_class类型arguments_的替代品吗? –

+0

@ K-ballo不代表我必须首先创建我的对象才能读取数据吗? – Sidar

回答

2

只要你不打算实例给出自己的组件类型的组件,并假设Component有一个或多个virtual功能,采用RTTI应该足以满足您的目的。您可以使用unordered_map代替HashMap,并用type_info代替Class<C>

我不确定的一件事是ComponentType会知道返回的确切位数:代码在没有参数的情况下实例化ComponentType,但是假设不同的实例会返回不同的模式设置和取消设置位。我认为这是因为你的散列图预先填充了已知的组件类型。

+0

ComponentType在构造函数中调用init。 init函数在内部设置下一个可用的id类型。 “位”意味着与“系统”对象(它是组件本身就是实体数据的每个组件的逻辑)一起工作,该组件根据它们的位标识收集实体,并将其删除或添加它们待处理。 在每个新的ComponentType实例上,静态地添加id和bit 1。 – Sidar

+0

+1。对于ComponentType中的bit/id hack,我建议使用一个bool矢量(这是* one *的情况,其特殊的实现将会有所帮助),或者是一个包装一个bool矢量的对象。它将远远超出Java的64位长度的限制。 – paercebal

+0

@paercebal你可以在矢量布尔上多说一点。代码的哪个方面是你特别讨论的? – Sidar