I want to access the engine from inside my eventReceiver object. They are fellow members of the game class, but how do I reach it?
// game.h
class game
{
public:
game();
3dEngine* engine;
eventReceiver* receiver;
};
// eventReceiver.h
class eventReceiver
{
public:
eventReceiver () {}
virtual bool OnEvent (const SEvent& event)
{
...
case QUIT_BUTTON_PRESSED:
>>> engine->quit(); // how to access engine from here??
return true;
...
}
};
Should I use 'this' ? I don't understand why receiver can't see the engine.
Implement the class as a Singleton and write a getter for the engine property. Accessing code could then look like:
game::getInstance()->getEngine()->quit();
I would recommend you though, that you create a quite() method in the game class itself hiding implementation details and allowing you to handle overall application shutdown and not just of the 3dEngine:
game::getInstance()->quit();
If you dont want to implement the game class as singleton you could also pass a reference/pointer of a game object to the constructor of your event handler:
class CloseButtonHandler : public eventHandler {
game& game;
public:
CloseButtonHandler(game& game) : game(game) {
}
virtual bool OnEvent(const SEvent& event){
...
game.getEngine()->quit();
}
}
The eventReceiver shouldn't know anything about the engine. That's a bad design. There are a few solutions. One reasonable solution is to derive game from eventReceiver since game can clearly receive events. You can then implement the game-specific OnEvent handler in game itself. From there you can call engine->quit.
I don't know how elegant this design is, but it works.
I just separated the receiver from the game class and gave its constructor a pointer to the instance of myGame. (Thanks to Paranaix)
class eventReceiver {
public:
eventReceiver (game* gameInstance) : gamei(gameInstance)
virtual bool OnEvent (...)
{...
case QUIT_BUTTON_PRESSED:
gamei.engine->quitGame();
...}
private:
game* gamei;
}
int main() {
game myGame;
eventReceiver receiver (&myGame);
}
Related
I'm experimenting with state machines and the one that I'm trying to implement uses function pointers to represent states
typedef void (*State)(Signal const&)
class StateMachine
{
public:
void exampleState(Signal const&);
private:
State m_currentState;
}
Basically, I want to derive a separate class for each signal and in each state function the state machine must be able to determine which kind of signal has been received and execute the corresponding code. A solution that I came up with is something like
class Signal {};
class MySignal: public Signal {};
void StateMachine::exampleState(Signal const& signal){
if (typeid(signal) == typeid(MySignal)){
//code here
}
// other cases...
}
First of all I'm not sure that using typeid this way is good practice. Also, this only works if Signal has at least one virtual function.
Another solution would be to define a sort of type flag like an enum, and pass the corresponding one in the derived signal constructor
enum signalType{
mySignalType
//other types
}
class Signal {
public:
Signal(signalType sig_type):m_type(sig_type){};
const signalType m_type;
};
class MySignal: public Signal {
public:
MySignal():Signal(mySignalType){};
};
void StateMachine::exampleState(Signal const& signal){
switch (signal.m_type){
case mySignalType:
//code here
break;
// other cases...
}
}
althoug this requires the enum to be extended each time a new signal class is written.
Is there a more elegant way of achieving this? Or maybe another technique that avoids this check at all? I remember having this problem in other scenarios as well, that's why the question in the title is more general than the example above.
What you want to achieve can be done through polymorphism.
Declare a method (or abstract method) in Signal, and implement it in MySignal:
class Signal {
public:
virtual void my_method() const = 0;
};
class MySignal: public Signal {
public:
void my_method() const override {
// do something
}
};
then call your method in exampleState, this will call the implemented method:
void StateMachine::exampleState(Signal const& signal){
signal.my_method();
}
Use dynamic_cast instead of typeid:
class Signal {
public:
virtual ~Signal() {}
};
class MySignal: public Signal {};
void StateMachine::exampleState(Signal const& signal){
if (dynamic_cast<MySignal const *>(&signal)){
//code here
}
// other cases...
}
Lately, I've been pondering about the following problem for a while. For the code bellow, what is the easiest way to modify Game::counter via Event::Perform() method which is called from Game class?
I considered Observer and Command design patterns, but it seems that there is a much simpler way to do this.
class Game
{
public:
Game();
private:
int counter;
vector<Event*> Events;
};
class Event
{
public:
virtual void Perform() = 0;
};
Thank you
Directly from Perform, none. counter is private, so it can only be accessed by Game, as part of one of the functions of the interface it provides.
Calling this function is then just a matter of having access to the right Game instance. You can pass that one as a parameter to Perform:
virtual void Perform(Game &) = 0;
... or inject it into derived Events:
struct MyEvent : Event {
MyEvent(Game &game) : _game{&game} { }
void Perform() const override {
// Do something with *game
}
private:
Game *_game;
};
Since I guess we are talking about the Events referenced by Game::Events, which Game itself will process, the parameter looks like the most cohesive approach.
Following is a simplified header file detailing three Classes. I want to be able to keep the pointer in my "Game" class private, and allow Introduction to modify it. However, as is, this is not working. As Introduction is a derivative of GameState, I thought I would be able to modify this pointer? Examples had shown that this was possible. I don't really want to move this to the Public space within Game.
class Introduction;
class Game;
class GameState;
class GameState
{
public:
static Introduction intro;
virtual ~GameState();
virtual void handleinput(Game& game, int arbitary);
virtual void update(Game& game);
};
class Introduction : public GameState
{
public:
Introduction();
virtual void handleinput(Game& game, int arbitary);
virtual void update(Game& game);
};
class Game
{
public:
Game();
~Game();
virtual void handleinput(int arbitary);
virtual void update();
private:
GameState* state_;
};
The example I was following was here...http://gameprogrammingpatterns.com/state.html
EDIT: I am wanting to do something like this...
void Introduction::handleinput(Game& game, int arbitary)
{
if (arbitary == 1)
std::cout << "switching to playing state" << std::endl;
game.state_ = &GameState::play;
}
EDIT: Thank you for the responses, I think getters and setters are the way to go. And I apologise that the problem was not clear. The problem was that I did not understand the implementation I was trying to follow. I still don't understand it, but clearly there are ways to accomplish the same thing.
I see two possible solutions.
Using Friend class
You can declare friend classes in your Game class.
Something like:
class Game {
public:
// ...
private:
// ...
friend class Introduction;
};
In this way, the class Introduction will be able to access to private member of Game class and modify it.
Getters And Setters
If you want to preserve data hiding principle, you can just provide a public member in order to modify the state of your game.
Here, an example:
class Game {
public:
void setNewState(GameState* setter) noexcept;
const GameState* getCurrentState() const noexcept;
// ...
};
How about a getter and an setter?
class Game
{
public:
....
GameState * getGameState() const { return state_; }
void setGameState(GameState * newState) { state_ = newState; }
....
private:
GameState* state_;
}
You can make the pointer Protected and make Game a friend to GameState, to allow Game to access protected members in GameState.
But as the above comments indicate, its not really clear what you are actually asking.
I am working on a project where there are two player objects and one game object.
The two player objects need to access the game object's function display(), but i have no idea how this could be done.
Below is a snippet highlighting the core issue:
class Game
{
public:
Game() {}
display() {...}
...
};
class Player
{
public:
Player() {}
void input()
{
...
// display();
...
}
};
Please suggest a way to solve this problem. if you find fundamental issue with this design pattern, feel free to correct that!
Why not?
void input()
{
game.Display();
}
but probably, you need to pass a Player object to it. Thus, change it this way:
class Player; // FORWARD declaration
class Game
{
public:
Game() {}
void display(Player& player); // Implement elsewhere not here.
// Another way
void display(Player* player = NULL); // Implement elsewhere not here.
...
};
...
void input()
{
game.Display(*this);
game.Display(this); // another way
}
I'm just trying to understand some tutorial code I'm going through. I'm trying to learn some Dx11 code and the tutorial I'm going through has classes that are designed as event details to be passed to functions when an event occurs, e.g. a mouse button being pressed. There's an empty base class EventArgs defined as follows:
class EventArgs
{
public:
EventArgs() {};
}
Which is the inherited by other event like classes. So for example they have a key pressed event args class as follows:
class KeyEventArgs : public EventArgs
{
public:
typedef EventArgs base;
KeyEventArgs(/**/)
{ }
// Rest of the class
}
I understand the premise that all the events are inheriting a base to say "they are an event type" but I don't understand the typedef base which is in every event class but isn't used by them directly. It seems as if a function that takes a KeyEventArgs parameter uses this base typedef to pass the event on to it's own base class but I don't understand how that works. The example they give is:
class Game
{
virtual void onKeyRelease(KeyEventArgs &e);
}
class Tutorial : public Game
{
void onKeyRelease(KeyEventArgs &e)
{
base::onKeyRelease(e);
/* Above calls Game::onKeyRelease(e) */
}
}
If anyone could shed any light on why/how the above works I'd be very grateful.
Thanks in advance.
The word base is not a keyword so in the class Tutorial example, the line base::onKeyRelease(e); will not compile. Now, if you saw it somewhere and it does compile, you must know that it must be define by a typedef or a using statement somewhere.
The purpose of the using such a typedef is to add another level of abstraction to help people change code safely. Considering the Tutorial example you could just as well write Game::onKeyRelease(e); Let's consider the following example:
class Game
{
virtual void onKeyRelease(KeyEventArgs &e);
}
class AwsomeGame : public Game
{
virtual void onKeyRelease(KeyEventArgs &e);
}
class Tutorial : public Game
{
typedef Game base;
void onKeyRelease(KeyEventArgs &e)
{
base::onKeyRelease(e);
//equivalent to Game::onKeyRelease(e);
}
}
If you change Tutorial base class from Game to AwsomeGame and the typedef also you have successfully changed the code without any bad side effects.
Not using a typedef would force you to write explicit calls to Game, and when the base class changes, you will have to change it in all the places you have used it. Now, if you consider the above example and you change Game to AwsomeGame without changing the typedef the code is valid, but you might run into a logical error later:
class Tutorial : public AwsomeGame //,public Game
{
void onKeyRelease(KeyEventArgs &e)
{
Game::onKeyRelease(e);
//code is valid, but you probably want AwsomeGame::onKeyRelease(e);
}
}
There is nothing magic here. Some other languages will provide a base, or similar, keyword to access the base class.
Obviously the programmers here like that, and simulate this by providing their own base. They could very well have written
class Tutorial : public Game
{
void onKeyRelease(KeyEventArgs &e)
{
Game::onKeyRelease(e);
/* Above calls Game::onKeyRelease(e) */
}
}
and avoided confusion (and a comment on what the code does).