2012-06-23 28 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