Если вы новичок в доступе к памяти и использовании кэша, я добавлю ссылку Николая «Что должен знать каждый программист о памяти».
Что касается вопроса:
Я бы рекомендовал хранить каждый тип компонента в своих собственных пулах, где они будут храниться в смежных массивах. например:
ComponentPool<CollisionComponent> mCollisionComponents;
ComponentPool<MeshComponent> mMeshComponents;
...
Когда вы выделяете GameObject
(он же извлекает его из пула), выделяйте определенные компоненты, необходимые для объекта.
Теперь вам следует избегать этого с компонентами:
void SomeCollisionWork() {
for each object {
if(object.hasCollisionComponent()) {
DoCollisionWork(object.collisionComponent)
}
}
}
Вместо этого вы можете подойти к нему так:
void SomeCollisionWork() {
for each allocated component in mCollisionComponents {
DoCollisionWork(component)
}
}
Если вы действительно нуждались в исходном GameObject
(или других компонентах для этого объекта), вы можете хранить некоторые данные (например, индекс GameObject) в каждом компоненте. С помощью индекса объекта вы можете получить доступ к другим его компонентам в других ComponentPool
s.
Какой смысл всего этого? Становится довольно легко разделить функциональность на отдельные части или «задания». Затем, если у вас есть компоненты, которые не зависят друг от друга, вы можете работать с ними параллельно (важно для «будущей» производительности).
Более подробно об этом я бы порекомендовал посмотреть на эту презентацию о динамической системе компонентов, разработанной Insomniac Games (обязательно прочитайте заметки докладчика): https://docs.google.com/present/edit?id=0ATIohmzo6z7TZGhjbmhidnFfMTg1MWNkcTJmcWZ4&hl=en