Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Error when using Thor event connect within a class [SOLVED]  (Read 1228 times)

0 Members and 1 Guest are viewing this topic.

Caronte

  • Newbie
  • *
  • Posts: 3
    • View Profile
Error when using Thor event connect within a class [SOLVED]
« on: September 06, 2017, 11:15:09 am »
Hi,

I'm really new to SFML and it's been years since I've coded in C++ so excluse my code if its terrible.

What I want is to make a Key Binding Menu where the player can change the keys used to move and such things.

Here is my problem, I have a class that takes care of all the settings (resolution, volume, that kind of stuff), so I want to pass the key press to that class.

My approach is to handle the event in the main class where the game loop is.


Here is some minimal code.

GameSystem.h
enum GameStates
{
        PAUSE,
        RUN,
        EXIT
};

enum GameEvents
{
        MENU,
        QUIT,
        KEY
};

class GameSystem
{
public:
        GameSystem();
        ~GameSystem();
       

        void initilize();
       
        bool isRunning();
        void update();


private:
        Settings _settings;
        thor::ActionMap<GameEvents> _events;
        thor::ActionMap<GameEvents>::CallbackSystem _systemEvents;
        sf::RenderWindow _window;
        GameStates _state;
        void onKeyPress(thor::ActionContext<GameEvents> context);
       
}
 

Now the problematic part.
GameSystem.cpp:
void GameSystem::initilize()
{
        _settings.loadSettings();
        _window.create(sf::VideoMode(_settings.get_width(), _settings.get_height()), "Title");
        _state = RUN;

        _events[QUIT] = thor::Action(sf::Event::Closed);
        _events[MENU] = thor::Action(_settings.get_menu(), thor::Action::PressOnce);
        _events[KEY] = thor::Action(sf::Event::KeyReleased);

       
        _systemEvents.connect(KEY, &GameSystem::onKeyPress);
}

void GameSystem::onKeyPress(thor::ActionContext<GameEvents> context)
{
        sf::Event event = *context.event;
        _settings.set_menu(event.key.code);

}
 

In the example I don't show neither the loop nor the events trigger, but that's because the events fire just fine when I don't try to use the callback. If I do the event callback from outside a class and just pass a function (as in the example) everything works correctly, but then I don't have access to the _settings instance.

I'm pretty sure this is a very C++ fundamental lack of knowledge on my part but I've searched for a couple days now and I just don't find how to do this or if this is a terrible idea alltoghether.

The compiler error is:

Severity        Code    Description     Project File    Line    Suppression State
Error   C2664   'thor::Connection thor::EventSystem<thor::ActionContext<ActionId>,ActionId>::connect(const EventId &,std::function<void (const Event &)>)': cannot convert argument 2 from 'void (__cdecl GameSystem::* )(thor::ActionContext<ActionId>)' to 'std::function<void (const Event &)>'      Project2        d:\programacion\sfml\project2\gamesystem.cpp    25     
 


Excuse my grammar, english is not my mother languaje
« Last Edit: September 06, 2017, 03:40:46 pm by Caronte »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Error when using Thor event connect within a class
« Reply #1 on: September 06, 2017, 12:41:19 pm »
You're passing the wrong arguments to the connect function. Check the documentation of your version of Thor to see what can be passed.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Caronte

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Error when using Thor event connect within a class
« Reply #2 on: September 06, 2017, 01:49:27 pm »
Thx for your comment, the thing is that what I have to pass is the function reference within the class.

For example, this code:

Main.cpp
void onKeyPress(thor::ActionContext<GameEvents> context);

int main(int argc, char** argv)
{
        sf::RenderWindow renderWindow(sf::VideoMode(800, 600), "Title");

        GameSystem game(renderWindow);
        game.initilize();
       
        thor::ActionMap<GameEvents>::CallbackSystem systemEvents;
        thor::ActionMap<GameEvents> events;
        events[GameEvents::KEY] = thor::Action(sf::Event::KeyReleased);
        systemEvents.connect(GameEvents::KEY, &onKeyPress); //<-- this is the "problematic" line

        while (game.isRunning())
        {
                events.update(renderWindow);
                events.invokeCallbacks(systemEvents, &renderWindow);
               
        }
}
void onKeyPress(thor::ActionContext<GameEvents> context)
{
        sf::Event event = *context.event;
        std::cout << "KEY " << event.key.code;
}
 

This works like a charm. I know it doesn't have window render and  all that but the event works just fine.

What I just can't figure out is how to make the event function reference within the same class so I have access to private methods and variables.

All this is just to make the key binding options so the player can choos if "fire" is on the mouse or on the space or whatever key. It might be easier if done differently... I'm up for suggestions too.

Thx

Edit: typo

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Error when using Thor event connect within a class
« Reply #3 on: September 06, 2017, 02:36:43 pm »
Did you read the documentation as I mentioned?
Thor accepts a unary listener as std::function object with the signature void(const Event &).

You may want to use std::bind for your class function.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Caronte

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Error when using Thor event connect within a class
« Reply #4 on: September 06, 2017, 03:40:13 pm »
Thx for the answer again. My lack of knowledge is so great that I didn't quite get your point until you gave me the tip fo std::bind.

After some searching I did:

_systemEvents.connect(GameEvents::KEY, std::tr1::bind(&GameSystem::onKeyPress, this, std::placeholders::_1));
 

And it works like a charm. I'm still on the fence as far as if this is the best way to allow the user to choose the keys for the game, but at least now works and I can keep trying stuff.

Thx again