【问题标题】:Removing all instances of object from a complex data structure从复杂数据结构中删除对象的所有实例
【发布时间】:2012-01-22 20:25:36
【问题描述】:

我正在为一个小型游戏框架的实体组件系统编写一个简单的实体管理器。我的实体管理器类处理分配给实体(一个简单的最终对象,只不过是一个 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;

是否有更好的结构我可以使用而不会牺牲查找速度,或者添加另一个结构以轻松检查实体是否在上述结构中没有引用?

我不想向实体类添加任何内容,因为它本身不应该包含任何数据。

编辑:为了澄清一点混乱,我还希望能够从实体中删除一个组件,如果这是对单个实体的唯一引用,我想删除它。 但如果不线性遍历所有三个结构,我无法判断是否有对实体的任何引用

【问题讨论】:

  • 我将首先在此代码中将 entity 重命名为 groupEntitiesList&lt;Entity&gt; entity : groups.values()
  • 另一种选择是在将实体引用插入/添加到结构时保留它们的列表。基本上你是在重写 GC,所以同样的策略也适用。
  • 另一种选择是添加一个成员变量active,您可以在删除时将其设置为false。然后您的代码可以检查isActive。不是很漂亮,但只是一个替代品。

标签: java data-structures


【解决方案1】:

您可以尝试保留一个数据结构,将每个实体映射到包含它的 List 和 Map 结构:

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

另一个想法是使用更通用的图形数据结构,其中节点可以是实体、组、标签等。然后完全删除一个实体只是删除它在图中的节点;如果您想查询一个实体属于哪些组,您只需遍历其边以查找组的边。

【讨论】:

    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2019-11-28
    相关资源
    最近更新 更多