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.
Related
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.
I'm using an abstract base class to add logging functionality to all of my classes. It looks like this:
class AbstractLog
{
public:
virtual ~AbstractLog() = 0;
protected:
void LogException(const std::string &);
private:
SingletonLog *m_log; // defined elsewhere - is a singleton object
};
The LogException() method writes the text to the log file defined in the SingletonLog object, and then throws an exception.
I then use this as my base class for all subsequent classes (there can be hundreds/thousands of these over hundreds of libraries/DLLs).
This allows me to call LogException() wherever I would normally throw an exception.
My question is whether or not this is good design/practice.
P.S.: I'm using inheritance simply to add functionality to all of my classes, not to implement any sort of polymorphism. On top of this, the concept of all of my classes having an is-a relationship with the AbstractLog class is arguable (each class is-a loggable object? Well, yes I suppose they are, but only because I've made them so).
What you suggesting will work, I think better is to create log class ( inheriting from this interface ) and use it as in a way composition ( using interface ) than inheritance - composition is weaker connection between your logic class and log class. The best practice is the less class does the better. Additional benefit is that you will be able to extend log functionality any time you want without modification of business logic.
About this singleton, maybe proxy pattern is better ?
Hope, I helped :)
This seems like overkill to me. And inheritance is supposed to express the is a relationship. So, in your case, you are kind of saying that every class in you project is a logger. But really you only want one logger hence the singleton.
It seems to me that the singleton gives you the opportunity to avoid both inheriting from your logger class and storing a logger class as a member. You can simply grab the singleton each time you need it.
class Logger
{
public:
void error(const std::string& msg);
void warning(const std::string& msg);
void exception(const std::string& msg);
// singleton access
static Logger& log()
{
// singleton
static Logger logger;
return logger;
}
};
class Unrelated
{
public:
void func()
{
// grab the singleton
Logger::log().exception("Something exceptional happened");
}
};
I suppose I am saying it seems less obtrusive to grab your singleton through a single static method of your logger than by having every class in the project inherit from the logger class.
I'm not sure you gain anything by having a free function to log the exception. If you have a LogException free function then presumbaly you'd also need free functions for LogError and LogWarning (to replicate Galik's functionality) and the Logger object would either be a non-local static object defined at file scope and instantiated at startup or you would need another free function (similar to the Logger method and called from all the other logging functions) in which the Logger object would be a local static object instantiated the first time the method is called. For me the Logger object captures all this neatly in one go.
Another point to consider is performance - if you're going to have a large number of objects all using a static logging object then the object could potentially struggle with a high rate of writing to the log file and your main business logic could get blocked on a file write. It might be worth considering adding the errors and warning messages to a queue inside the Logger object and then having a separate worker thread going through the queue and do the actual file writes. You would then need thread protection locks around the writing to and reading from this internal queue.
Also if you are using a static logging object then you need to be sure that the entire application including the DLLs is single threaded otherwise you could get multiple threads writing to the same file simultaneously and you'd need to put thread protection locks into the Logger even if you didn't use an internal queue.
Except from the friend relationship, inheritance is the strongest coupling that can be expressed in C++.
Given the principle of louse coupling, high cohesion, I think it is better to use a looser type of coupling if you just want to add functionality to a class.
As the logger is a singleton making LogException a free function is the simplest way to achieve the same goal without having the strong coupling you get with inheritance.
"...use this as my base class for all subsequent classes..." -- "...question is whether or not this is good design / practice."
No it is not.
One thing you usually want to avoid is multiple inheritance issues. If every class in your application is derived from some utility class, and then another utility class, and then another utility class... you get the idea.
Besides, you're expressing the wrong thing -- very few of your classes will actually be specialized loggers, right? (That is what inheritance implies -- is a.)
And since you mentioned DLLs... you are aware of the issues implied in C++ DLLs, namely the fragility of the ABI? You are basically forcing clients to use the very same compiler and -version.
And if your architecture results in (literally) hundreds of libraries, there's something very wrong anyways.
In an attempt to replace the singleton pattern and a general "Resource Manager", I came with a solution. Making a resource static and protected. That resource is shared between all children from the inherited class. It works, but I wasn't sure if it's a good way to proceed.
Here's a bit of code to express what I'm doing(the resource here is the sf::Texture):
class Foo {
public:
Foo() {
if(m_texture == nullptr) {
//Création et chargement de la texture
m_texture = std::unique_ptr<sf::Texture>(new sf::Texture());
m_texture->loadFromFile("...");
}
}
void draw(sf::RenderWindow& window) = 0;
protected:
static std::unique_ptr<sf::Texture> m_texture = nullptr;
};
class Bar : public Foo {
public:
Bar()
: m_sprite(*m_texture) {}
void draw(sf::RenderWindow& window) {
window.draw(m_sprite);
}
private:
sf::Sprite m_sprite;
};
That way my resources is shared through all children, and is only initialized once.
Is it a good solution to replace a singleton or a Resource Manager that I would carry everywhere through reference.
Thank you!
Fundamentally what you are tying to do is correct, a static member will be shared (ie be exactly the same) among all the inherited class, this way you only need a single instance which can save you a ton of memory but heres a couple issues ... Im assuming you are using g++.
You can't initialize non-const member within a class declaration so this.
static std::unique_ptr<sf::Texture> m_texture = nullptr;
would produce this:
error: ISO C++ forbids in-class initialization of non-const static member
you have to initialize it within the source file of your class, but outside the class.
std::unique_ptr<sf::Texture> Foo::m_texture = nullptr;
Second it isn't save to access member fields directly, always use setters and getters, even within the class functions, this makes the code much more maintainable. As such you can have a static function called getTexture
static std::unique_ptr<sf::Texture> getTexture() {
if(m_texture == nullptr) {
//Création et chargement de la texture
m_texture = std::unique_ptr<sf::Texture>(new sf::Texture());
m_texture->loadFromFile("...");
}
return m_texture;
}
while its true that the if statement and function call do add come overhead, this is much more maintainable and safer, and it load the texture at the last minute when its truly needed.
Back to your question, the Singleton design pattern is quite simple and mostly used to save memory since only a single instance of the object is ever created :) Resource managers are a whole different beast their goal is to centralize all the actions that are required loading and managing resources, combining the two you would initialize a single instance of a resource manager, then access it though a static member field, having all the objects make requests for resources, this could be good or bad, depending on what you are trying to achieve.
Software design is hard. The best advice I can give is this, when designing a system ask yourself this, "how many lines of code would I have to write to introduce another similar component" your goal should be to minimize this as much as possible, ie reuse as much as possible what you have already created.
The best programmers are the laziest :) and no I don't mean copy/paste, that should be banned.
The design looks suspicious. I don't see any advantage of using this over the more widely used Singleton pattern (with a function local static instance). You're probably best off initializing the m_texture object with a default Texture at the point of definition (and not within Foo's ctor):
static std::unique_ptr<sf::Texture> m_texture( new sf::Texture() );
Data members are ideally suited for derived classes. Base classes are typically to define interfaces.
I'd suggest that you keep your resource manager class (Foo) separate and instead of inheriting from it, call appropriate member functions to get to the Texture object.
I have probably a quite simple problem but I did not find a proper design decision yet.
Basically, I have 4 different classes and each of those classes has more than 10 methods.
Each of those classes should make use of the same TCP Socket; this object keeps a socket open to the server throughout program execution. My idea was to have the TCP obejct declared as "global" so that all other classes can use it:
classTCP TCPSocket;
class classA
{
private:
public:
classA();
...
};
class classB
{
private:
public:
classB();
...
};
Unfortunately, when declaring it like this my C++ compiler gives me an error message that some initialized data is written in the executable (???). So I am wondering if there is any other way I could declare this TCP object so that it is available for ALL the other classes and its methods?
Many thanks!
I'd suggest you keep the instance in your initialization code and pass it into each of the classes that needs it. That way, it's much easier to substitute a mock implementation for testing.
This sounds like a job for the Singleton design pattern.
The me sounds more for the right time to use Dependency Injection as i tend to avoid Singleton as much as i can (Singleton are just another way for accessing GLOBLAS, and its something to be avoided)
Singleton vs Dependency Injection has been already discussed on SO, check the "dependency injection" tag (sorry for not posting some links, but SO doens't allow me to post more than one link being a new user)
Wikipedia: Dependency Injection
As per your current code example, should be modified to allow injecting the Socket on the constructor of each Class:
class classA
{
private:
public:
classA(TCPSocket socket);
...
};
class classB
{
private:
public:
classB(TCPSocket socket);
...
};
Pass the socket into the constructor of each object. Then create a separate factory class which creates them and passes in the appropriate socket. All code uses the set of objects which are required to have the same socket should then create them via an instance of this factory object. This decouples the classes that should be using the single socket while still allowing the enforcement of the shared socket rule.
The best way to go about doing this is with a Singleton. Here is it's implementation in Java
Singleton Class:
public class SingletonTCPSocket {
private SingletonTCPSocket() {
// Private Constructor
}
private static class SingletonTCPSocketHolder {
private static final SingletonTCPSocket INSTANCE = new SingletonTCPSocket ();
}
public static SingletonTCPSocket getInstance() {
return SingletonTCPSocket.INSTANCE;
}
// Your Socket Specific Code Here
private TCPSocket mySocket;
public void OpenSocket();
}
The class that needs the socket:
public class ClassA {
public ClassA {
SingletonTCPSocket.getInstance().OpenSocket();
}
}
When you have an object which is unique in your program and used in a lot of places, you have several options:
pass a reference to the object everywhere
use a global more or less well hidden (singleton, mono-state, ...)
Each approach have its drawbacks. They are quite well commented and some have very strong opinions on those issues (do a search for "singleton anti-pattern"). I'll just give some of those, and not try to be complete.
passing a reference along is tedious and clutter the code; so you end up by keeping these references in some long lived object as well to reduce the number of parameters. When the time comes where the "unique" object is no more unique, you are ready? No: you have several paths to the unique object and you'll see that they now refer to different objects, and that they are used inconsistently. Debugging this can be a nightmare worse than modifying the code from a global approach to a passed along approach, and worse had not be planned in the schedules as the code was ready.
global like approach problem are even more well known. They introduce hidden dependencies (so reusing components is more difficult), unexpected side-effect (getting the right behaviour is more difficult, fixing a bug somewhere triggers a bug in another components), testing is more complicated, ...
In your case, having a socket is not something intrinsically unique. The possibility of having to use another one in your program or to reuse the components somewhere were that socket is no more unique seems quite high. I'd not go for a global approach but a parametrized one. Note that if your socket is intrinsically unique -- says it is for over the network logging -- you'd better encapsulate it in a object designed for that purpose. Logging for instance. And then it could make sense to use a global like feature.
As everyone has mentioned, globals are bad etc.
But to actually address the compile error that you have, I'm pretty sure it's because you're defining the global in a header file, which is being included in multiple files. What you want is this:
something.h
extern classTCP TCPSocket; //global is DECLARED here
class classA
{
private:
public:
classA();
...
};
something.cpp
classTCP TCPSocket; //global is DEFINED here
Sorry for reposting this, but for some reason I can not add comments to my older
post. Some people wanted to know the exact error message I get when trying to do
the following:
I have probably a quite simple problem but I did not find a proper
design decision yet. Basically, I have 4 different inherited classes and
each of those classes has more than 10 methods.
Each of those classes should make use of the same TCP Socket; this
object keeps a socket open to the server throughout program execution.
My idea was to have the TCP obejct declared as "global" so that all
other classes can use it:
classTCP TCPSocket;
class classA
{
private:
public:
classA();
virtual void method1();
...
};
class classB
{
private:
public:
classB();
virtual void method1();
...
};
and so on for classC and classD...
Unfortunately, when declaring it like this my Symbian GCC-E compiler gives me the
following error message
elf2e32 : Error: E1027: ELF File contains initialized writable data.
So I am wondering if there is any other way I could declare this
TCP object so that it is available for ALL the other classes and its
methods? classA() is the first method that will be called when
initialising this subsystem.
Many thanks!
There is very elegant way to retrieve static instances on demand.
classTCP& SingletonInstance()
{
static classTCP instance;
return instance;
}
Idea is using c++ feature to initialize local static variables only on demand.
You can support a class-wide static member by allowing both classA and classB to inherit from the same parent.
class BaseTCP {
static classTCP tcp;
// ...
};
class classA : BaseTCP {
// ...
};
class classB : BaseTCP {
// ...
};
Now classA and ClassB both share the same static member. The stipulation is that you now have to declare the static member outside of the BaseTCP class someplace, similar to:
classTCP BaseTCP::tcp;
Depending on your situation, this may be overkill...
Instead of using singletons, why don't you just create a classTCP instance and pass references to the other objects, each of which owns a reference (or pointer) to the single instance of classTCP.
This offers a much more flexible design - I think singletons generally suck and have much more limited use that generally believed. If you use a singleton, your classes classA, classB etc... have no option but to use the singleton instance. Using a more standard object composition design, you free the whole thing up.
Ask yourself questions like, what if I want the application to talk to >1 server? or what if I want to write some unit test code for classA? Writing unit test code for networking applications is a lot easier when you don't need to use real sockets but can use dummy ones that simply hold the chunks of data in ram. Add a comment if you want an example, because I'm off for lunch now:)
Doing it the way I suggest does not add significant complexity to the overall design but makes it much more open.
A Singleton pattern.