Should I use static classes in an ECS? - c++

Hey I am currently working on a small entity component system where there are classes like EntityManager, ComponentManager and SystemManager that are only instantiated once and heavily communicate with each other.
I created a class world which owns all the managers and acts as the center for all communication between the managers. Making all the Managers static would make a lot of things much easier, more understandable and I wouldn't even need the world class.
I know though that static classes (I know "static classes" don't exist but I mean classes with only static members) act as if they were global and global variables are Bad®.
So I wonder what is recommended to do in this case
Thanks for your answers
Che
Edit:
The World class looks like this:
class World
{
public:
EntityManager* entityManager;
ComponentManager<PositionComponent>* componentManager;
MovementSystem* movementSystem;
Entity e;
public:
World(sf::RenderWindow& window);
void update();
};
To communicate each Manager needs a pointer to the world to access the other managers. Like this world->entityManager->getEntitys()

(I suggest that the project is a game or something close to it)
I don't suggest you to make all members static. The main problem with it that you're loosing control on object's lifetime. You can't destroy and create new object at runtime easily because there is no object. For example, if you want to change a manager at runtime you'll have to implement cleanup code manually. In case of C++ objects C++ helps you with errors/warnings, default values and class members by value.
There are few popular ways to implement and use managers in gamedev:
Use Singleton pattern. In this case class have one static method that returns link to non-static object.
Pass dependencies that method requires during the method call manually.
Singleton pattern, I think, is the best way in terms of price-quality ratio for you. Despite on all criticism of this pattern it does its job well (most of game projects I saw used Singleton approach to implement manager classes).
There is an important thing I want to suggest you about this pattern. Don't use default implementation of Singleton pattern. Create methods for creating and destroying object instead of hiding it inside of getter. Here's simple example of glue code for a manager:
class Manager {
private:
static Manager* ms_manager;
public:
static void CreateManager() { ms_manager = new Manager(); }
static void DestroyManager() { delete ms_manager; }
static Manager* GetInstance() { return ms_manager; }
};
Usage is:
Manager::GetInstance()->SomeMethod();
Passing dependencies approach has its own advantages. It may sounds too difficult to pass everything in every Update method but it's not. You can create context class, set all dependencies there and pass it to every method that needs it. It's almost like your World class but it must be structure with minimum of code and no dependencies. Don't store there any game objects by value (only primitives, geometry vectors and stuff like this). It may be something like this:
struct Context {
EntityManager* entityManager;
ComponentManager<PositionComponent>* componentManager;
MovementSystem* movementSystem;
Entity* rootEntity;
};
Usage is:
GameObject::Update(Context& context) { context.entityManager->SomeMethod(); }
The point of this approach that you can tune context for some objects at runtime. For example, if you have LODs you can save in context current LOD level and change it at runtime for some objects depends on distance to the camera.

Related

Preventing unauthorised use of components

I'm building a component system where an abstract type Component is inherited from to make components. So far, I have drawable, physical, movable and other components. All seems to go well, and in the Game class I perform the following:
void Game::init()
{
pPlayer->addComponent(pMovable);
}
void Game::processEvents()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
pMovable->moveUp(2.f);
// etc..
pPlayer->setVelocity(pMovable->getVelocity());
}
void Game::update()
{
pPlayer->update(0);
}
void Game::play()
{
while (pWindow->isOpen())
{
// ...
processEvents();
}
}
So far, the component system is really basic and simple. The player is of type Object and whenever I call the player's update function, I also have the Object's update function also called. This should really be automated, but that will change in the future. What the real problem is this:
pPlayer can still access pMovable's velocity even if it has not added pMovable as a component. This is problematic because it means anyone can simply get the velocity from pMovable and then plug it into their object without having to add pMovable as part of their component. Now, what does tend to happen is that the movement becomes unmanaged since there is no movable component to regulate it. I term this unauthorised use of the component, and I want to develop a way by which a component can 'deny' usage of its functionality to an object it is not owned by. There are many solutions to this problem, and I need one which is efficient and practical for use. Here are mine:
Throw an exception if the client attempts to allocate a component function into its own without adding it;
Create a system by which objects and components are identified and the component keeps track of the objects it is owned by, and the objects keep track of the components it owns. Because this is a many-to-many relationship, an intermediate class that manages all this would have to be created; it also avoids a circular header inclusion.
Have a function NOT part of an object simply 'deactivated'. This would require the use of a boolean like 'componentAdded' and all functions would have to check whether the component was added or not, else the function won't do what it ought to be doing.
If you have other solutions to prevent the unauthorised use of components, please share them as I'm keen to learn from others as to how they implemented/or would implement a component system as I have done here.
You can't prevent specific classes from inheritance. It's an all or nothing proposition: any class inherits from the base or none.
The best you can hope for is to narrow the interface. For example, instead of allowing decendents of Object in a function, you may want to have a class Stationary_Object or Enemy_Object to refine the interface. This allows you to write functions that take any Enemy_Object and won't take a Stationary_Object (like a tree or wall).
Edit 1: Cheating with friends
You can allow member access by declaring the members as private and granting access to specific classes using the friend class. The problem is that the class with data will need to be modified whenever a new type of friend is created. I believe this use of friendship defeats the purpose of reusability.
Edit 2: detecting ownership
Let's say we have three classes:
class Engine;
class Car
{
Engine car_engine;
};
class Boat
{
Engine boat_engine;
};
And a function:
void Fix_Car_Engine(Engine& e)
{
}
There is no method in C++ for the Fix_Car_Engine to know that it is fixing a car engine or a boat engine. The function only knows that it has been given a generic engine to fix (or it only knows about the common Engine stuff of the variable).
This issue can be mitigated by refining or narrowing the interface:
class Car_Engine : public Engine;
class Boat_Engine : public Engine;
class Car
{
Car_Engine diesel_engine;
};
class Boat
{
Boat_Engine propellor_engine;
};
In the above example, the Engine class has two specializations: Car_Engine and Boat_Engine. The Car now has a Car_Engine member and the Boat has a Boat_Engine.
The functions can now be created to operate on special engines:
void fix_boat_engine(Boat_Engine& be);
void fix_car_engine(Car_Engine& ce);
The fix_car_engine will now only work with Car Engines. You could say that it works on any class that has-a Car Engine (as long as you pass the Car Engine member). Likewise, the fix_boat_engine function only operates on Boat Engines.
Given:
class Rocket_Engine : public Engine;
Also, this specialization prevents a Rocket_Engine from being passed to either function. The functions require specific engine types.

Does it make a sense to create an Abstract Factory for factories?

I was googling around this patterns and found that we could create a Factory for Abstract factories and it would really make a sense. To me I make the following example leaned from some C++ book.
Imagine that we have two abstract classes in a game-application: Monster and SuperMonster.
Depedning on the difficult level we also have their implementations:
SillyMonster, MediumMonster and HardMonster and so for SuperMonsters.
So now we can create three object factories with the same base class:
class AbstractEnemyFactory
{
public:
virtual Soldier* MakeSoldier() = 0;
virtual Monster* MakeMonster() = 0;
virtual SuperMonster* MakeSuperMonster() = 0;
};
class EasyLevelEnemyFactory : public AbstractEnemyFactory
{
public:
Monster* MakeMonster()
{
return new SillyMonster;
}
SuperMonster* MakeSuperMonster()
{
return new SillySuperMonster;
}
};
//The other two factories
And it seems quite naturally to me if we create AbstractEnemyFactoryFactory which is going to create an appropriate AbstractEnemyFactory implementation depending on what level was choosen by a gamer in runtime.
Question: Does it make sense to encapsulate an ObjectFactory into an AbstractFactory?
I mean we create an Abstract Factory which itself is going to create Object Factories rather than concrete objects which in turn are creating concrete objects. I couldn't find more or less sensible example...
If you use an AbstractEnemyFactoryFactory to create an AbstractEnemyFactory then you'll find yourself again in the problem of "Who is going to take care of creating the approriate AbstractEnemyFactoryFactory"? And then you might try to create another AbstractEnemyFactoryFactoryFactory and so on....
Having an AbstractFactory patterns means that somewhere, in you application, you'll need a sort of switch (usually driven by GUI inputs) that creates the approriate ConcreteFactory when the player selects the game difficulty in your case.
What I'm saying is that it is not generally wrong to incapsulate the ObjectFactory in an AbstractFactoryFactory, but this should be done in situations where the ObjectFactory is not the only one to be created (for example you might have a factory for trees that will create concrete trees differently if the player selects hard or easy mode). In this case AbstractFactoryFactory will handle multiple Object factory creation and it might be useful.
But if the creation of the EnemyFactory is directly controlled by high-level modules (GUI) then just keep it simple and create the EasyLevelEnemyFactory or the HardLevelEnemyFactory
EDIT:
To clarify: Following the tree and the enemy example, MediumGameFactory creates MediumEnemyFactory factory and MediumTreeFactory, while EasyGameFactory creates EasyEnemyFactory and EasyTreeFactory. This way, at the top of your application you just have to create either MediumGameFactory or EasyGameFactory according to the game difficulty (here comes the switch) and these two factories will handle all the rest. Hence, you don't have to manually create all the smaller factories across the application.

C++ object interaction

I'm having a 2d world in c++ filled with animal-like entities for a program I'm writing. I have a world class, and and entity class (and a cascade of different kinds of entities inheriting from entity).
I want the entity to "know" which world its in and be able to interact well with the 2d array of entities, but I don't want it to inherit from world (after all, entities aren't worlds). So I'm just trying to get some ideas for a good way to implement this. I could of course have each entity contain a pointer to the world it's in, but it seems rather messy. Is there an easier way for an entity in a 2d array to "know" which world object contains it.
Is there any way in c++ for an object that's a member variable for another object to know the object that contains it?
Thanks!
Aggregation (supplying each entity with a world pointer) is the simplest solution. Another solution is to have a third mediator object which maintains pointers to worlds and entities, stores their relationship, and mediates (hence the name) the communication between them. This object could be a global singleton (most programmers will shudder but I don't think a few of these are a bad thing), or else every world and entity will need a pointer to it to communicate, which obviously isn't a big improvement on the first solution.
Assuming I've understood you correctly, an alternative to a world pointer in each entity is to give each world a unique id, then store that id in the entity as it is added to its world.
I have a world class
Oh dear.
That aside, what is your entity's meaningful interaction with its environment? Should it be able to query arbitrary information, see over the horizon, interrogate the state of other entities?
Or is it supposed to have some limited view, based on its location and attributes?
In the first case it is apparently a godlike entity, and mundane concerns such as encapsulation and separation of concerns don't apply.
In the second case, expose an interface (you can make it abstract to reduce coupling) which allows it to see only what it ought.
OK, so the second case could look something like
class World; // is a dumb container of entities
class Environment; // is an entity's window on the world
class Entity {
public:
void take_a_turn(Environment&) = 0;
};
class Environment {
public: // control what an entity can do to (see of) the World
container<const Entity*> visible_entities() const;
result attempt_to_eat(const Entity*);
result attempt_to_mate(const Entity*);
result run_away_from(const Entity*);
};
of course, if your Entity objects are active (ie, they run autonomously and continuously in their own threads), they need to keep a reference or pointer to the world or environment.
However, if you're just invoking them, one at a time, when they have a chance to do something, passing the reference in each time is fine.
For the world maybe you can create some kind of global engine. The engine will have systems and the world could be considered a system inside the engine. You would request from the engine the world system in the constructor of your entity and do what you need to inside there.
class World : public System
{
// info in here
}
class Engine
{
public:
World * getWorldSystem(); // Not as good
System * getSystem( std::string name ); // uses lookup, convert to right type
}
The problem with an engine class is "How do I reference it?" In most cases you would include the .h file for the engine which also has an:
extern Engine * ENGINE;
Inside of it, which is horrible I understand but with the engine/system architecture you have to have it somewhere. Or you use a singleton explicitly.
As for your inheritance tree maybe change your design scheme completely. Component based architecture might be a way for you to solve this problem.
While inheritance makes sense in a lot of situations building a component based entity will help you with the huge chain of weird types that each animal must have.
Take:
class Component
{
public:
Component();
virtual ~Component();
}
class WalkComponent : public Component
{
public:
Walk(); // Something here allows the entity to walk on the ground
}
class FlightComponent : public Component
{
public:
Fly(); // Something in here moves the entity around using flight
}
Right away you can see that you could attach a walk component and a flight component to the entity and it would have both, rather than trying to create an inheritance tree that allows both of those.

Singletons alternative

I have a pretty simple game engine. It uses several singletons(I'll enumerate some of them).
Resource Manager
Render Engine
Events Manager
Factory
etc
These singletons have many calls from one to another. I'll take Events Manager sample usage:
Any object derived from Listener can add itsel as a listener for some events just like this EventsManager->RegisterListener(this, &SomeClass::SomeMethod); (event type is deduced by SomeMethod parameter)
Any other object can fire an event like this EventsManager->PushEvent(SomeEvent);
After some synchronization the event reaches to all listeners. This is very a simple usage for EventsManager when it is singleton.
Similar behavior is with other singletons. I want to remove the singletons, but my main problem is that I want to keep the code simple to use from the "user point of view" as it is now. I read some techniques of doing this, but most of the make the initialization/usage of the classes more complicated. I know this topic was discused many times on SO, but no answer is appropriate for my programming philosophy - to keep everything as simple as possible.
I don't want to have complicated definition/initialization for my classes like:
SomeClass<EventManager, RenderEngine,...>
or
SomeClass::SomeClass(EventsManager, RenderEngine...)
Can you please give me some advice on this topic?
You could have a global "game" object that creates an instance of each of the classes that are currently singletons
For the specific example of your EventManager; your Listener base class could provide implementations of a register method and a push method that derived classes can call.
A skeleton definition:
class Listener
{
public:
virtual void ReceiveMessage( ... ) = 0;
protected:
void Register()
{
GetEventManagerSomehow()->RegisterListener( this, etc );
}
void PushEvent( etc )
{
GetEventManagerSomehow()->PushEvent( etc );
}
}
To solve the specific problem of detecting resource leaks in your singletons, give each singleton class a shutdown method that destroys the instance.
class Singleton
{
// ...
static Singleton * GetInstance()
{
if (instance == NULL)
instance = new Singleton;
return instance;
}
static void Shutdown()
{
delete instance;
instance = NULL;
}
static Singleton * instance;
};
Singleton * Singleton::instance = NULL;
Not really an answer, but maybe too long for a comment.
Dependency injection is a very good alternative to singletons: You create instances in the main function of your program and you pass them to "modules" (which are main classes), so they can use them locally. This means that for these classes you will have the "complicated" constructors that you don't want.
However, The complexity should only be limited to some classes and passing some dependent "modules" are in my point of view not that complex. As a bonus, you can find out dependencies between modules by just looking at the constructors or at the main function.
Dependency injection is used a lot because it does solve the issue that you are seeing (and more, like unit testing) with only a very limited amount of added complexity.

What's the best way to have a variable be accessible from anywhere in your program?

I'm making a game right now and pretty much everything has its own class. The main classes I feel that I have a problem with are my 'Level' and 'Object' class. The level class contains images to every image in the level, and the Object class contains the image for each object on the screen(an object is pretty much anything: your player, an enemy, an item, etc).
The way I have it right now is that the Object class has an Image and when you create a new object, you load a new image into it. So lets say you have two enemies that use the same image, both instances of the object will separately load the image and I'll have two of the same images in memory. This seems like a really bad idea and later when my game gets more complicated it will slow it down a lot.
So what I was thinking about doing is having something like a Resource Manager class that would hold all of the images, and than each object would just ask the resource manager for the image it needs. That way it would only store each image once and save some space.
I could probably easily do this with a static variable in the Object class, but since the Level class also needs to use images it would also need access to the Resource Manager. Would it be best to send a pointer to a resource manager to each instance of an object/level(or any other class I later make that would need it) and access it that way? Or would there be a better way to do this?
You should usually avoid "making variables accessible from anywhere" - see here for why.
In your case, that means it's a bad idea to make the ResourceManager accessible from everywhere. I suggest you do as you say in the post - have every game object keep a pointer to the resource manager.
In the future it may turn out your game objects need to know about other core objects as well. For example your game object may need to call methods on a central game state. Then it makes sense to create a core class like this:
class Core {
public:
...
ResourceManager& resourceManager();
GameState& currentGame();
// and so on
};
And your base GameObject class keep a pointer to just the core. Then you can create game objects like this:
Core core; // performs some initialization
core.startGame();
Enemy enemy(&core); // it's easy to pass the core to the game object
Have the base GameObject class require a Core& in its constructor, and provide a protected Core& GameObject::core() function.
Such problems are generally solved with the singleton pattern. Make sure to review the various issues that pattern has before applying any particular version of it.
I think i would do it this way:
1) Have a resource manager class responsible for loading everything you need.
2) Each object (image or anything else) has an associated string, in order to be able to do something like :
manager->setResource("levelImage");
A registerResource could be used, a freeResource, or whatever else you like.
This way you can easily access everything you need i think :)
I would do this using the singleton pattern. I usually create a generic singleton class that I subclass later. Something like this:
template<class Derived>
class Singleton
{
public:
static Derived& instance();
protected:
Singleton() {};
private:
Singleton(const Singleton&) {};
Singleton& operator=(const Singleton&) { return *this; };
private:
static std::auto_ptr<Derived> _instance;
};
Then the resource class can do:
class ResourceManager : public Singleton<ResourceManager>
{
public:
friend class Singleton<ResourceManager>;
protected:
ResourceManager() {};
};