2

我正在考虑移植 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++ 不支持类类型作为参数。所以这对我来说是相当令人难以置信的。

4

1 回答 1

2

只要您不打算在给定组件类型的情况下实例化组件,并假设Component具有一个或多个virtual功能,使用RTTI就足以满足您的目的。您可以使用unordered_map代替HashMap,并将 替换Class<C>type_info

我不确定的一件事是如何ComponentType知道要返回的确切位:ComponentType当在地图中找不到一个时,代码在没有参数的情况下实例化,但假设不同的实例将返回不同的设置和未设置位模式。我认为这是因为您的哈希映射已预先填充已知组件类型。

于 2012-06-23T17:36:56.140 回答