Estoy creando un juego que utiliza objetos de juego basados en componentes, y estoy teniendo dificultades para implementar una forma para que cada componente se comunique con su objeto de juego. En lugar de explicar todo de una vez, explicaré cada parte del código de muestra relevante:
class GameObjectManager {
public:
//Updates all the game objects
void update(Time dt);
//Sends a message to all game objects
void sendMessage(Message m);
private:
//Vector of all the game objects
std::vector<GameObject> gameObjects;
//vectors of the different types of components
std::vector<InputComponent> input;
std::vector<PhysicsComponent> ai;
...
std::vector<RenderComponent> render;
}
El GameObjectManager
tiene todos los objetos del juego y sus componentes. También es responsable de actualizar los objetos del juego. Lo hace actualizando los vectores componentes en un orden específico. Utilizo vectores en lugar de matrices para que prácticamente no haya límite en la cantidad de objetos de juego que pueden existir a la vez.
class GameObject {
public:
//Sends a message to the components in this game object
void sendMessage(Message m);
private:
//id to keep track of components in the manager
const int id;
//Pointers to components in the game object manager
std::vector<Component*> components;
}
La GameObject
clase sabe cuáles son sus componentes y puede enviarles mensajes.
class Component {
public:
//Receives messages and acts accordingly
virtual void handleMessage(Message m) = 0;
virtual void update(Time dt) = 0;
protected:
//Calls GameObject's sendMessage
void sendMessageToObject(Message m);
//Calls GameObjectManager's sendMessage
void sendMessageToWorld(Message m);
}
La Component
clase es puramente virtual, de modo que las clases para los diferentes tipos de componentes pueden implementar cómo manejar los mensajes y actualizarlos. También puede enviar mensajes.
Ahora surge el problema de cómo los componentes pueden llamar a las sendMessage
funciones en GameObject
y GameObjectManager
. Se me ocurrieron dos posibles soluciones:
- Dar
Component
un puntero a suGameObject
.
Sin embargo, dado que los objetos del juego están en un vector, los punteros podrían invalidarse rápidamente (lo mismo podría decirse del vector en GameObject
, pero es de esperar que la solución a este problema también pueda resolverlo). Podría poner los objetos del juego en una matriz, pero luego tendría que pasar un número arbitrario para el tamaño, que fácilmente podría ser innecesariamente alto y desperdiciar memoria.
- Dar
Component
un puntero a laGameObjectManager
.
Sin embargo, no quiero que los componentes puedan llamar a la función de actualización del administrador. Soy la única persona que trabaja en este proyecto, pero no quiero acostumbrarme a escribir código potencialmente peligroso.
¿Cómo puedo resolver este problema mientras mantengo mi código seguro y amigable con la caché?