Может быть, я старшеклассник, но я действительно не вижу значения в универсальных компонентах, потому что не вижу их замены во время выполнения.
struct GameObject
{
Ai* ai;
Transform* transform;
Renderable* renderable;
Collision* collision;
Health* health;
};
Это работает для всего: от игрока до врагов, скайбоксов и триггеров; просто оставьте «компоненты», которые вам не нужны, в данном объекте NULL. Вы хотите поместить все ИИ в список? Тогда просто сделай это во время строительства. С полиморфизмом вы можете использовать все виды различного поведения (например, «ИИ» игрока транслирует ввод контроллера), и кроме этого нет необходимости в базовом базовом классе для всего. Во всяком случае, что это будет делать?
Ваше «обновить все» должно было бы явно вызывать каждый из списков, но это не меняет количество набираемых вами текстов, оно просто перемещает его. Вместо того, чтобы запутанно настраивать наборы, для которых требуются глобальные операции, вы явно перечисляете наборы, для которых нужны операции в момент выполнения операций.
ИМХО, дело не в том, что виртуальные звонки медленные. Дело в том, что «компоненты» игровой сущности не являются однородными. Все они делают совершенно разные вещи, поэтому имеет смысл относиться к ним по-разному. Действительно, между ними нет никакого совпадения, поэтому я снова спрашиваю: какой смысл в базовом классе, если вы не можете использовать указатель на этот базовый класс каким-либо осмысленным образом, не приводя его к чему-то другому?