Заставить объект сохранять указатель на другие объекты, но не добавлять код к объекту напрямую (развязка)

У меня есть система на основе сущностей.

GameObject (сущность) сохраняет все указатели на все связанные GameComponents.
Все GameComponent держать указатель на GameObject,

Если я знаю, что мне нужно часто запрашивать один компонент из другого компонента (Physics<->Graphics), Я буду кешировать указатель другого компонента.

class Physics : public GameComponent {
Graphics* graphic;  //different GameObject
};
class Graphics: public GameComponent {
Physics * physic ;  //different GameObject
};

Стоимость запроса указателя друг от друга (Physics->Graphics а также Graphics->Physics) очень маленький.

Время идет …

хранения Graphicsуказатель в Physics и наоборот становится менее чувствительным и вызывает проблему ремонтопригодности.

Например, если я хочу добавить новое отношение, например, Physics-PlayerМне нужно будет добавить поле в оба класса:

  • добавлять Player* в class Physics
  • добавлять Physic* в class Player

Если я продолжу, совершенно простые компоненты будут забиты множеством полей отношение это трудно отслеживать и поддерживать.

class Physic: public GameComponent {
Graphic* graphicsMain;
Graphic* graphicsSecondary;
Player* playerPtr;
Enemy* enemyPtr;
//10+ as project grow
}

Код для запроса объекта из другого объекта разбросаны во многих местах.

Вопрос: Как решить проблему ремонтопригодности без снижения производительности?

Мой обходной путь

Я создал новый GameComponent названный RelationNode,
Затем создайте новую систему с именем Relation управлять каждым типом отношений в одно место.
Плюсы: Я могу закодировать все утилиты, которые я хочу, и это будет работать для каждого типа отношений.

class Physics : public GameComponent {
//no keep Graphics pointer anymore ... clean :)
};
class Graphics: public GameComponent {
//no keep  Physics pointer anymore ... clean :)
};
public RelationNode : public GameComponent {
//... some code ... cache other component ...
RelationNode* slot01; //shared Physics->Graphics and Graphics->Physics
RelationNode* slot02; //Physic->graphicsSecondary
.......
RelationNode* slot20;
//^ I can reuse same slot of variable if I am sure.
//instead of "RelationNode*" , it can also be "GameObject*"};
class Relation{
Graphics* getGraphicsFromPhysics(Physics* gameComponent){
RelationNode* a = toNode(gameComponent); //waste 1-2 indirection
RelationNode* b = queryGraphicFromPhysics(gameComponent);
Graphics* bCom= fromNode(b);             //waste 1-2 indirection
return bCom;
}
//the real code is more elegant than this, but suffer the same issue
};

Теперь мой код настолько чистый, но страдает от снижения производительности косвенность.
Это стоит около 1-30% (профилировано), зависит от тестового примера.

у меня есть другой сумасшедшая идея о добавлении поля в компонент с помощью макроса, но я не люблю макрос — он вызывает другие проблемы.

Моя старая идея заключается в использовании hashMap например HashMap<Graphics*,Physics*>, но это намного медленнее, чем мой обходной путь (проверено).

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]