25 Eylül 2017 Pazartesi

signals2 signal Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/signals2.hpp>
signals2 ve diğer yöntemleri karşılaştıran bir tablo şöyle. signals2 hız çok önemliyse biraz ağır kaçabilir.
Benchmark                                       Duration (normalized)
    ---------------------------------------------------------------------
    Direct function call                            1
    Function pointer call                           1
    Virtual function call                           1
    std::function call                              1.5
    std::vector<std::function> call                 2
    boost::signals signal invocation                78
    boost::signals2 signal invocation (dummy mutex) 43
    boost::signals2 signal invocation               92

Tanımlama
Parametre almayan bir signal için şöyle yaparız.
typedef boost::signals2::signal<void ()> signal_t;
int alan bir signal için şöyle yaparız.
boost::signals2::signal<void(int)> m_sig;
unique_ptr alan bir signal için şöyle yaparız.
boost::signals2::signal<void(std::unique_ptr<int> const&)> m_sig;
Parametre 
signals sınıfı operator() metoduna geçilen parametreyi move edemez. Şöyle yapamayız.
auto ptr = std::make_unique<int>(20);
signal(std::move(ptr));
Constructor
Şöyle yaparız.
signal_t mysignal;
connect metodu
Bir connection nesnesi döner.
Örnek
Parametre almayan bir metodu bağlamak için şöyle yaparız.
const signal_t::slot_type& subscriber = boost::bind(&Foo:foo, &f);
return mysignal.connect (subscriber);
Örnek
Parametre almayan bir metodu template olarak bağlamak için şöyle yaparız.
template <typename slot_t>
boost::signals2::connection addSlot(slot_t slot) {
 return mysignal.connect(slot);
}
Örnek
Tek parametre alan bir metodu bağlamak için şöyle yaparız.
boost::signals2::connection c = 
mysignal.connect(boost::bind(myfunc, myobj, _1));
Örnek
unique_ptr alan bir metodu bağlamak için şöyle yaparız.
struct MySlot
{
  void operator()(std::unique_ptr<int> const& input) const
  {
     std::cout << "Signaled " << *input.get();
  }
};

boost::signals2::signal<void(std::unique_ptr<int> const&)> signal;
signal.connect(MySlot());
operator () metodu
Parametre almayan signalı çağırmak için şöyle yaparız.
mysignal ();
Tek parametre alan bir signalı çağırmak için şöyle yaparız.
m_sig (42);
unique_ptr alan bir metodu çağırmak için şöyle yaparız.
auto ptr = std::make_unique<int>(20);
m_sign (ptr);
slot_type tipi
typdef tanımlamak için şöyle yaparız.
typedef boost::signals2::signal<void(bool)> signal_t;
typedef signal_t::slot_type OnTriggeredSlot;
Örnek - Map of Signal
Elimizde şöyle bir sınıf olsun.
enum SDL_Keycode { K_A, K_B, K_C, K_Up, K_Down, K_Right, K_Left, K_LCtrl,};
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;
};
Lambda ile birşey bağlamak için şöyle yaparız.
inputController.registerEvent(K_B, Down, [&] { p.jump(); });
bind ile birşey bağlamak için şöyle yaparız.
inputController.registerEvent(K_B, Down,
  boost::bind(&PlayerController::jump, boost::ref(p)));
inputController.registerEvent(K_B, Down,
  boost::bind(&CowController::moo, boost::ref(c)));

Hiç yorum yok:

Yorum Gönder