c++ - 连接未知类的成员函数以 boost 信号

标签 c++ boost signals pointer-to-member

我知道围绕此有很多主题,但我就是无法弄清楚。

我正在为我的游戏使用信号驱动的输入管理器,因为我需要控制多个玩家,所以我需要将 PlayerController 实例的成员函数连接到我的信号 vector 。

问题是,不仅会有一个 PlayerController,还有一个 MenuController 等。所以我还需要将 MenuController 的成员函数连接到信号。

我很确定我已经接近解决方案,但我似乎无法弄清楚。

有人可以帮助我了解 registerEvent 函数签名以及如何调用 connect 方法吗?

输入管理器.tcc

#include "boost/function.hpp"
template<class T>
void InputManager::registerEvent(SDL_Keycode key,KeyState state,boost::function<void ()> const& function)
{
    auto &inputEvents = (state == KeyState::Up) ? m_keyUpEvents : m_keyDownEvents;

    if(inputEvents.find(key) == inputEvents.end())
    {
        inputEvents.insert(std::make_pair(key, boost::signals2::signal<void()>()));
        m_keyStates[key] = KeyState::Up;
    }

    inputEvents[key].connect(boost::bind(T::function, instance));
}

InputManager.hpp:

#ifndef SSB_INPUTMANAGER_HPP
#define SSB_INPUTMANAGER_HPP

#include <functional>
#include <algorithm>
#include <vector>
#include <map>
#include <SDL_keycode.h>
#include <SDL_events.h>
#include <boost/signals2.hpp>

enum KeyState{
    Down,
    Up
};

class InputManager
{
public:
    InputManager();
    template<class T>
    void registerEvent(SDL_Keycode key,KeyState state, boost::function<void ()> const& function);
void pollEvent(SDL_Event event);

private:
    std::map<SDL_Keycode, boost::signals2::signal<void ()>> m_keyDownEvents;
    std::map<SDL_Keycode, boost::signals2::signal<void ()>> m_keyUpEvents;
    std::map<SDL_Keycode, KeyState> m_keyStates;
};

#include "InputManager.tcc"

#endif //SSB_INPUTMANAGER_HPP

PlayerController.hpp

#ifndef SSB_PLAYERCONTROLLER_HPP
#define SSB_PLAYERCONTROLLER_HPP

class PlayerController
{
public:
    void jump();
private:
    Player m_player;
};

#endif //SSB_PLAYERCONTROLLER_HPP

然后我想在游戏中的某个地方调用初始化方法:

PlayerController playerController;
InputManager inputController;

inputController.registerEvent(SDLK_0, KeyState::Down, playerController.jump());

最佳答案

两者boost::function<>std::function<>已经进行了类型删除。这意味着它们“抽象”掉任何绑定(bind)参数。

this*参数实际上只是:一个参数。所以,同样如此。

Live On Coliru (c++11)

#include <boost/function.hpp>
#include <boost/signals2.hpp>
#include <map>
#include <iostream>

enum SDL_Keycode { K_A, K_B, K_C, K_Up, K_Down, K_Right, K_Left, K_LCtrl, /*etc....*/ };
enum KeyState { Down, Up };

struct InputManager {
  void registerEvent(SDL_Keycode key, KeyState state, boost::function<void()> const &function) {
      auto& map = state == Up? m_keyUpEvents : m_keyDownEvents;
      map[key].connect(function);
  }

  void poll_event() {
      // hardcoded for demo
      m_keyDownEvents[K_B]();
  }

private:
  std::map<SDL_Keycode, boost::signals2::signal<void()>> m_keyDownEvents;
  std::map<SDL_Keycode, boost::signals2::signal<void()>> m_keyUpEvents;
  std::map<SDL_Keycode, KeyState> m_keyStates;
};

struct Player {};

class PlayerController {
public:
  void jump() {
      std::cout << "Player jumped\n";
  }

private:
  Player m_player;
};

class CowController {
public:
  void moo() {
      std::cout << "Cow mooed\n";
  }
};

int main() {
    InputManager inputController;
    PlayerController p;

    inputController.poll_event(); // nothing

    inputController.registerEvent(K_B, Down, [&] { p.jump(); });

    inputController.poll_event(); // player jumps

    CowController c;
    inputController.registerEvent(K_B, Down, [&] { c.moo(); });

    inputController.poll_event(); // player jumps, cow moos
}

打印

Player jumped
Player jumped
Cow mooed

C++03

如果您没有 lambda,则可以使用 Boost Bind(或 std::tr1::bind ):

inputController.registerEvent(K_B, Down, boost::bind(&PlayerController::jump, boost::ref(p)));

inputController.poll_event(); // player jumps

CowController c;
inputController.registerEvent(K_B, Down, boost::bind(&CowController::moo, boost::ref(c)));

查看 Live On Coliru

关于c++ - 连接未知类的成员函数以 boost 信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42370720/

相关文章:

c - 信号函数返回类型的真正用途是什么

c++ - 从模板化父类访问继承变量

c++ - WSARecv 的 dsBytes、dwFlags 参数

c++ - 没有匹配函数调用 "constructor"

c++ - 我如何知道 Windows 7 中是否启用了原始套接字?

linux - 在 Linux 上构建 Boost - 库名称

c++ - 使用 Boost::Test 并行代码

c++ - 使用来自 const 成员函数的每个类 boost::log::sources::logger

计算 parent 向 child 发送信号的次数

linux - ctrl+c 不杀死后台功能