2012-01-22 16 views
2

我正在爲小型遊戲框架的實體組件系統編寫一個簡單的實體管理器。我的實體管理器類處理分配給實體的組件(簡單數據存儲對象)(僅具有ID屬性的簡單最終對象)。它還處理與這些實體關聯的標記和組(作爲字符串)。從複雜數據結構中刪除對象的所有實例

我有以下方式列出的數據:

private Map<String, Entity> tags = new HashMap<String, Entity>(); 

private Map<String, List<Entity>> groups = new HashMap<String, List<Entity>>(); 

private Map<Class<? extends Component>, Map<Entity, Component>> components = new HashMap<Class<? extends Component>, Map<Entity, Component>>(); 

這樣我可以從哈希地圖部件的一定type非常快速檢索所有實體。其他兩個也一樣。

問題是我想能夠從系統中完全刪除一個實體(並且可能還能夠檢查實體什麼時候沒有更多引用,因此它可能會返回到池中),但是我不知道如何做到這一點,而不需要遍歷所有三個結構。

// find if entity is in a group 
for (List<Entity> entity : groups.values()) { 
    if (entity.contains(e)) return true; 
} 

return false; 

 

// even more complex, find if entity has any behaviors 
for (Map<Entity, Component> entry : components.values()) { 
    if (entry.keySet().contains(entity)) return true; 
} 

return false; 

是否有更好的結構,我可以使用,不會犧牲查找速度,還是有辦法添加其他的結構很容易地檢查,如果一個實體沒有引用在上述結構中?

我不想向實體類添加任何內容,因爲它本身不應包含任何數據。

編輯:爲了澄清一點困惑,我也希望能夠從一個實體中刪除一個組件,如果這是唯一的引用單個實體,我想刪除它。 但我不知道是否有任何引用實體沒有通過所有三個線性結構

+0

我將開始在此代碼中將'entity'重命名爲'groupEntities':'List entity:groups.values()' –

+1

另一個選擇是在插入/添加到結構時保留實體引用的列表。基本上你重寫GC,所以同樣的策略也適用。 –

+0

另一種方法是添加一個成員變量'active',您可以在刪除時將其設置爲false。你的代碼可以檢查'isActive'。不是很漂亮,但只是一個選擇。 –

回答

1

你可以嘗試每個實體保持的數據結構映射到列表中,含有它的地圖結構:

Map<Entity,List<List<Entity>> activeLists; 
// delete function 
for (List<Entity> x : activeLists.get(entity)) 
{ 
    x.remove(entity); 
} 

另一個想法是使用一個更一般的圖形數據結構,其中節點可以是實體,組,標籤, 隨你。然後完全刪除一個實體就是刪除它在圖中的節點;如果你想查詢一個實體屬於哪個組,你只需遍歷它的邊來尋找組邊。