How to structure this without introducing circular includes? - c++

I am trying to figure out how to structure my game. I want to pass my "managers" down the hiearchy instead of making them global. But I ran into a problem. One of my managers updates scenes. It needs to pass Application reference to scenes, as application contains quit method. But my Application holds and updates this SceneManager. So my Application now includes SceneManager as it needs to update it, and my SceneManager includes Application as it needs to pass Application reference to scenes.
Basically Application holds all managers, SceneManager passes Application reference to Scenes, Scenes use managers obtained from Application reference.
// In application
sceneManager.updateScenes(*this);
// In SceneManager
currentScene.update(application)
// In scene
application.getSceneManager().doSomething()
Could anyone suggest me how to elegantly structure this part of my game? I know about forward declarations, but I would like to know if there is a solution without the need to make forward declarations.
I could use globals, but I would rather not.

One common (but not the only) solution to this problem is to have Scene communicate with Application through an interface which Application implements, rather than by direct reference.
This has the additional benefit of more clearly expressing what exactly Scene (and other dependencies) need to call out to.
For example:
interface ISceneHandler {
void Quit(); // Request that we quit the game.
}
class Application : ISceneHandler {
private SceneManager sceneManager;
public Application() {
// Pass ourself as the handler.
sceneManager = new SceneManager(this);
}
public void Quit() { ... }
}
class SceneManager {
private ISceneHandler handler;
public SceneManager(ISceneHandler handler) {
this.handler = handler;
}
public void SomeEvent() {
this.handler.Quit();
}
}

Related

Global variables in a GUI?

I am designing an immediate gui using C++ and SDL2. As I was starting to design my framework, I noticed that basically everything needs a renderer or some sort of event or other relevant information (Fonts, Themes, etc.). Does it make sense to put these is global static object that only the gui functions have access to, or just keep passing everything in.
Would this be ok?
This could be the header:
struct GuiForm {
GuiId active_id;
GuiId hot_id;
std::vector<Window> windows;
Renderer* renderer;
};
Then this could be the .cpp file:
static GuiForm* gui_form;
void SomeGuiWidget() {
GuiId current_hot_id = gui_form.hot_id;
/* Whatever the widget is going to do */
}

How to remove this circular dependency? [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 3 years ago.
What am I trying to do?
I am trying to make game. Instead of having global "managers"
, I decided that I could pass all managers down the hiearchy. My plan was to make "Application" class, that would hold all "manager" objects, like Window, Asset Manager, etc... Application would then pass it's reference to SceneManager, SceneManager would pass Application reference to Scene and Scene whould then pass it to GameObjects, so it would be possible to call any manager from any level of hiearchy.
The problem is, my Application holds SceneManager. And SceneManager needs to pass Application reference to Scene.
Diagram:
Code: (Simplified)
Application:
Application relies on SceneManager, because it needs to hold it and update it.
#include "SceneManager"
class Application {
public:
SceneManager& getSceneManager();
void update();
void quit();
enter code here
private:
SceneManager sceneManager;
// Input, Window, Asset loaders etc
};
SceneManager:
SceneManager relies on Application, because it needs to pass Application reference to the current Scene.
#include "Application"
class SceneManager {
public:
void updateCurrentScene(Application& application);
// Handling scene switching etc.
enter code here
private:
Scene currentScene;
};
In scene it would be then possible to:
void onUpdate(Application& application) {
application.getSceneManager().doSomething();
}
Is it possible to remove circular reference and still have this "passing the managers down"?
How would you do it?
You can “forward declare” the classes in the header files.
class Application;
Instead of the full #include.
You will need the #include in the cpp file (or really before you do anything with the forward declared class).

Clean OOP design when making a GUI

Say I have two main classes, Application and ApplicationGUI. Application does lots of things and can happily run without any knowledge that ApplicationGUI exists. ApplicationGUI is linked to Application in many ways, it has maybe 50 or 100 different knobs that can change Application's behavior.
ApplicationGUI is a hierarchical structure such that it has many instances of ControlGroup, each containing an arbitrary number of Buttons and Knobs, or even another ControlGroup.
Current design: Upon instantiation of the ApplicationGUI (Application was already running with some set of default parameters), I pass pointers of Application's parameters to various components of the GUI. For example:
my_gui.sound_controlgroup.knob.link_to_param(&(my_application.volume));
If I need to do something more complex, say call a member function of Application, my_application.update_something(), how is this done?
The easy answer is to pass a pointer to my_application to my_gui.sound_controlgroup.knob, but if I only ever need to call one of my_application's functions, it seems like I am giving my knob an option to change all kinds of things that it should even know about (my_application.update_something_unrelated(), for instance). What is the cleanest thing to do in this case?
Additionally, this either requires making all subcomponents of ApplicationGUI public or having a function at each stage of the hierarchy to forward that pointer to the bottom level. This leads to quite a lot of functions. Is this a necessary consequence of a UI with a lot of knobs?
Quick Short Answer
In order to implement interaction between your non GUI related Application object and your GUIApplication object I suggest apply the "Property and Method and Event Handler" paradigm.
Extended Complex Answer
G.U.I. development is one of the most practical implementation of the O.O.P. theory.
What is the "Property and Method and Event Handler" paradigm ?
That means build, both Non GUI Classes, and GUI Classes, should have:
Properties
Methods
Event handlers
"Events" (Handlers) are also called "Signals", and are implemented with functions pointers. Not sure, but, I think your "knob" (s) are like Event Handlers.
It's a technique to apply the my_application.update_something_unrelated(), you have in your question.
Since, C++, like Java, does not have property syntax, you may use "getter" and "setter" methods, or use a "property" template.
For example, if your application has a Close method, you may declare something like the following examples.
Note: They are not full programs, just an idea:
// Applications.hpp
public class BaseApplicationClass
{
// ...
};
public class BaseApplicationClientClass
{
// ...
};
typedef
void (BaseApplicationClientClass::*CloseFunctor)
(BaseApplicationClass App);
public class ApplicationClass: public BaseApplicationClass
{
// ...
public:
Vector<BaseApplicationClientClass::CloseFunctor>
BeforeCloseEventHandlers;
Vector<BaseApplicationClientClass::CloseFunctor>
AfterCloseEventHandlers;
protected:
void ConfirmedClose();
public:
virtual void Close();
} Application;
// Applications.cpp
void ApplicationClass::ConfirmedClose()
{
// do close app. without releasing from memory yet.
} // void ApplicationClass::ConfirmedClose()
void ApplicationClass::Close()
{
// Execute all handlers in "BeforeCloseEventaHandlers"
this.ConfirmedClose();
// Execute all handlers in "AfterCloseEventaHandlers"
} // void ApplicationClass::Close()
// AppShells.cpp
public class AppShell: public BaseApplicationClientClass
{
// ...
};
void AppShell::CloseHandler(ApplicationClass App)
{
// close GUI
} // void AppShell.CloseHandler(ApplicationClass App)
void AppShell::setApp(ApplicationClass App)
{
App->BeforeCloseEventHandlers->add(&this.CloseHandler);
} // void AppShell.setApp(ApplicationClass App)
void main (...)
{
ApplicationClass* AppKernel = new ApplicationClass();
ApplicationGUIClass* AppShell = new ApplicationGUIClass();
AppShell.setApp(App);
// this executes "App->Run();"
AppShell->Run();
free AppShell();
free AppKernel();
}
UPDATE: Fixed type declaration from global function pointer (a.k.a. "global functor") to object function pointer (a.k.a. "method functor").
Cheers.
Do you know about the model-view-controller (MVC) paradigm? Think of the Application class as the model, the entire hierarchy of GUI controls as the view, and the ApplicationGUI class as the controller. You don't want Application to know about the controls, and you don't want the controls to know about Application; they should both talk only to the controller, ApplicationGUI.
Using ApplicationGUI as the conduit for communication between controls and Application means that you can test either Application or controls by replacing the other with a mock object, for example. More importantly, you can change either the controls or Application without impacting the other. Individual controls don't need to know anything about Application -- they only need to know where to send their value when it changes. And Application shouldn't care whether an input comes from a knob or a slider or a text field. Keeping those two areas separate will simplify each of them.
Additionally, this either requires making all subcomponents of
ApplicationGUI public or having a function at each stage of the
hierarchy to forward that pointer to the bottom level. This leads to
quite a lot of functions. Is this a necessary consequence of a UI with
a lot of knobs?
A given control shouldn't care what value it manages. It doesn't need to know whether the value determines the number of alien invaders on the screen or the coolant level in a nuclear reactor. It does needs to know things like the minimum and maximum values, label to display, scale to use (linear, log, etc.), and other things that directly impact the way the control works. It also needs to know who to tell when something changes, and it might need some way to identify itself.
With that in mind, ApplicationGUI doesn't need to expose accessors for every possible parameter of Application. Instead, it should have a general method that lets controls send it updates. When a control changes, it should send a message to ApplicationGUI containing the new value(s) along with its identifier, and ApplicationGUI takes care of mapping that identifier to some particular parameter of Application. A control's identifier could be some identifying number that's given to it, or it could just be a pointer to the control.
Of course, sometimes communication has to go the other way, too... a GUI usually has both inputs and outputs, so you'll want some means for ApplicationGUI to get updates from Application and update the state of the GUI. For the same reasons described above, Application should send those updates to ApplicationGUI and let the latter find the actual UI components that need to be changed.

Passing application objects into lower level classes

I wasn't really sure how to search for this question.
I'm doing an embedded system design with the following scenario.
I have a main application class that needs to create a bunch of hardware interfaces such as a keypad, display, communication ports, etc... a whole slew of stuff
Now I have all these objets in the main application that I can use which is great
The application class contains a few sub classes that it can go into and stay for a while. One example is a menu class that it enters and runs inside that class until the menu is closed
I need the menu class to also interact with a lot of a hardware objects that were created at the application level
What is the best way to go about this without using global variables? Is there a good solution to this problem?
I could pass each object into the menu class, but I don't want to create a constructor with 20 arguments. My current solution is to put all the objects into a structure and pass that structure into the sub-class constructor. That way they also have access.
The part that bugs me about this approach is that I have to define the structure outside of the application which I don't really like. Something just keeps telling me it's not the best solution.
Open to any suggestions.
Presumably, there is ONE keypad - thus only one "Keypad Interface Object", right? Similarly with Display [ok, there may be two displays, but still].
So my suggestion would be to have a registration and a "container" that holds the registered interfaces something like this:
class KeyPad
{
public:
int getKeyPressed();
};
class Display
{
public:
OutputText(std::string msg);
};
... bunch of other stuff ...
class HardwareRegistry
{
priviate:
Keypad *keypad;
Display *display;
static HardwareRegistry *myself;
public:
Keypad* GetKeypad() { return keypad; }
Display* GetDisplay() { return display; }
void RegisterKeypad(Keypad *akeypad) { keypad = akeypad; }
void RegisterDisplay(Display *adisplay) { display = adisplay; }
static HardwareRegistry* GetHwRegistry()
{
if (!myself) myself = new HardwareRegistry;
ASSERT(myself); // If we don't have a pointer now, panic!
return myself;
}
};
Then you just have a Singleton Pattern to provide your HardwareRegistry, and register the devices as you create them during hardware initialization.
Of course, if you support different kinds of Keypads, Displays, etc, then you would implement those with a "interface baseclass", and the registry returns the KeypadBase type, for example.

Accessing variable from one project to another in visual studio c++

I have a solution and it has two projects in it. When I got the code they told one project handles the visual part and the other has the logic part. Now I added one button to the window. To do that i edited the project which handles the visual part. I am very new to this but creating and adding buttons is fairly straightforward in visual studio 2010. Now the problem is I want to detect if the button is pressed from the other project. I am sure that the projects are sharing some data, but I am not being able to capture it. For now I am changing a value in a file and reading the same data from the other project to check if the button is pressed. But I think there is a better way to do it. Can anyone help?
I don't think the two projects are sharing automatically. You will have to define the interface that the two projects communicates. For instance, in your solution above the "a value in a file" is the "interface" you have defined. What sounds like you are trying to achieve is to separate the controller (logic part) and view (visual part) separately, which seems to indicate that your project is using MVC model.
I would suggest defining an abstract class (interface) that defines the interaction you want between the two projects. All they have to share is a single header file.
For example:
// Solution A (Controller - logic part)
// MyUIHandler.h
class IMyUIHandler //You can also use microsoft's interface keyword for something similar.
{
public:
HRESULT onButtonPressed() = 0; // Note that you can also add parameters to onButtonPressed.
};
HRESULT getMyUIHandler(IMyUIHandler **ppHandler);
Then implement this interface:
// Solustion A (Controller - logic part)
// MyUIHandler.cpp
#include "MyUIHandler.h"
class CMyUIHandler : public IMyUIHandler
{
private:
// Add your private parameter here for anything you need
public:
HRESULT onButtonPressed();
}
HRESULT getMyUIHandler(IMyUIHandler **ppHandler)
{
// There are many ways to handle it here:
// 1. Define a singleton object CMyUIHandler in your project A. Just return a pointer
// to that object here. This way the client never releases the memory for this
// object.
// 2. Create an instance of this object and have the client release it. The client
// would be responsible for releasing the memory when it's done with the object.
// 3. Create an instance of this object and have a class/method in Solution A release
// the memory.
// 4. Reference count the object, for example, make IUnknown the parent class of
// IMyUIHandler, and implement the IUnknown interace (which is boiler plate code).
// Since I don't know your project it's hard for me to pick the most suitable one.
...
*ppHandler = myNewHandler;
...
return S_OK;
}
CMyUIHandler can simply be your existing class that already handles some of the logic.
In solution B you should will call getMyUIHandler in some initialize function, for example the controller of the UI class, save that as your member. Then "Button clicked" event handler that VS creates for you.
// Solution B (View - visual part)
// MyUIView.h
class MyUIView
{
protected:
IMyUIHandler *m_pHandler;
}
// MyUIView.cpp
CMyUIView::CMyUIView(...)
{
...
hr = getMyUIHandler(&m_pHandler);
// error handler, etc...
...
}
// In the function that is created for you when button is clicked (I'm not sure if I get the signature right below.
void OnClick(EventArgs^ e)
{
...
hr = m_pHandler->onButtonPressed();
...
}
Then you can pass any parameter you define for the function onButtonPressed as soon as the button is clicked.