How to Acess a singleton from everywhere?

Started by
36 comments, last by Jay Pascua 9 years, 1 month ago

I have this:

core--->manager1

--->manager2 --->class 1 --->class 2 ---> class 3

...(etc)

managerX is a member of core class

So, if i have to call "manager1" from class 3.cpp (class3 referenced to class 2, 2 referenced to 1, and 1 to Manager2), what's the correct way of doing this?

should I define all managers like static objects and included their h file in "core", or define them inside my "core" class?

Advertisement

So, if i have to call "manager1" from class 3.cpp (class3 referenced to class 2, 2 referenced to 1, and 1 to Manager2), what's the correct way of doing this?

Don't structure your code this way in the first place.

Seriously. You are all leaning heavily on globals (or equivalently, singletons) to band-aid underlying architectural flaws.

If class3 actually needs to access manager1, then pass a bloody reference to manager1 into class3's constructor. More likely, class3 needs to access some subset of the functionality in manager1, in which case, factor that common functionality out, and stop naming things catch-all phrases like 'manager', so that you stop violating the single responsibility principle...

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]


If class3 actually needs to access manager1, then pass a bloody reference to manager1 into class3's constructor. More likely, class3 needs to access some subset of the functionality in manager1, in which case, factor that common functionality out, and stop naming things catch-all phrases like 'manager', so that you stop violating the single responsibility principle...

I'm totally agree with you, I don't want to have statics everywhere (only I have 5),

this is what happend:

Initially i had a core object(which was static = m_Core pointer) and their class private members (renderer, objectmanager, Scene,...).

the situation: I needed to call some manager inside SceneInit function from scene.cpp (basically the same example as my previous post).

Inside InitScene() I created the triangle. Once the gameobject is created is added to the objmanager list (a vector) (every gameobject had a reference to this objmanager).

Scene.cpp


void SceneManager::SceneInit()
{
    GameObject* obj1;
    //set the gameobject
    m_Core->getObjmanager()->AddGameObject(obj1);
   //added to objectmanager vector

   //a lot of code, set shader, and stuff

}

The application simply didn't work (application-->Show a green triangle), it showed a colored background (without triangle).

I assumed that the object did not created, maybe it did, so I decided to pass a manager (objectmanager pointer) to the sceneInit function and check if the manager contain the object:

Scene Init changed


void SceneManager::SceneInit(objmanager* m_objmanager)
{
GameObject* obj1;
//set the gameobject
m_objmanager->AddGameObject(obj1);
//added to objectmanager vector

//a lot of code, set shader, and stuff

}

It worked, So i decided to pass every manager as arguments to the function that needed them (and to be clear, this is what I want)----->here the problems appeared. I had troubles to render, because i was passing "renderer" to a component of a gameobject that was on a vector of a manager, and that renderer to the meshrenderer, to the material, to the shader ... huh.png

Two ways 1) review every line of code (which i did) and try to figure out what was the problem (which i didn't) .....and 2) try another method...

then I discover the singletons ---> the result: everything works!, even now, So, are they pureee evill? ...happy.png

What is the difference in the above code? i mean, why it worked when passing the pointer?

Maybe look at it like this.

If I ask you for a ten dollar bill, you don't hand me your wallet containing the bill, the rest of your money, all your credit cards and ID, ask me to remove the bill, then return your wallet. That would be crazy, right?

Global state is effectively doing this to your whole program. Your physics code can touch your renderer. Your sound system can touch your mesh loader. And so on.

Its not a moral issue here. Using global state, whether disguised as OO with a Singleton or not, means you lose all control of which parts of your program can access which state. Irrelevant in a small project, maybe irrelevant to you, but people have discovered over the last few decades that this is a bad way to organise code.

(sorry for double post)

Maybe look at it like this.

If I ask you for a ten dollar bill, you don't hand me your wallet containing the bill, the rest of your money, all your credit cards and ID, ask me to remove the bill, then return your wallet. That would be crazy, right?

Global state is effectively doing this to your whole program. Your physics code can touch your renderer. Your sound system can touch your mesh loader. And so on.

Its not a moral issue here. Using global state, whether disguised as OO with a Singleton or not, means you lose all control of which parts of your program can access which state. Irrelevant in a small project, maybe irrelevant to you, but people have discovered over the last few decades that this is a bad way to organise code.

great example! at least you didn't came out with the "muaahaha" and "the pure evil" sh&$t

I'll slowly killing all singletons ph34r.png


here the problems appeared. I had troubles to render, because i was passing "renderer" to a component of a gameobject that was on a vector of a manager, and that renderer to the meshrenderer, to the material, to the shader

Effectively I would consider you to have your architecture reversed here. GameObject should never need an instance of Renderer. Instead, Renderer should take a list of GameObject and operate on them. The same for the other classes mentioned.

It's advantageous to separate data (GameObject, Shader, etc), from subsystems (Renderer, Physics, AI, etc). Subsystems should own data, never the other way round.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Effectively I would consider you to have your architecture reversed here. GameObject should never need an instance of Renderer. Instead, Renderer should take a list of GameObject and operate on them. The same for the other classes mentioned."

It's advantageous to separate data (GameObject, Shader, etc), from subsystems (Renderer, Physics, AI, etc). Subsystems should own data, never the other way round.


Sorry I know it's off topic, but I've definitely been doing this all wrong. Always pays off to read any random thread.

This topic is closed to new replies.

Advertisement