заблокировать все соединения, подключенные к сигналу повышения - PullRequest
1 голос
/ 06 августа 2010
Повышенные сигналы

позволяют временно заблокировать соединение с помощью функции члена соединения. Тем не менее, у меня есть один сигнал со многими соединениями. Соединения хранятся и поддерживаются их соответствующими слушателями. Теперь вещатель решает, что хочет на некоторое время прекратить отправку сигналов. Похоже, нет способа перебрать все соединения сигнала или временно отключить весь сигнал. Это кажется мне странным, поскольку такой механизм должен существовать внутри, чтобы сигнал достигал всех его подписчиков при получении сигнала ...
Я что-то пропустил? Как я могу временно отключить сигнал?

1 Ответ

2 голосов
/ 06 августа 2010

Я не знаю, как сделать это напрямую.Если вы хотите навсегда отключить все слоты, вы можете использовать метод disconnect_all_slots().Например:

boost::signal<int ()> foo;
...
foo.disconnect_all_slots();

Если вам нужно временно заблокировать их, лучший способ обойти это - использовать пользовательский объединитель, имитирующий это поведение.

#include <boost/signals.hpp>
#include <iostream>

//Define a reusable combiner that allows all slots to be blocked
template <typename Combiner>
struct blockable {
   typedef typename Combiner::result_type result_type;

   blockable() : blocked(false), combiner() {}

   //Block or unblock all slots
   void block() {blocked = true;}
   void unblock() {blocked = false;}

   template <typename InputIterator>
   result_type operator()(InputIterator first, InputIterator last) {
      //Either call into inner combiner, or throw if all slots are blocked
      if (!blocked) return combiner(first, last);
      throw std::runtime_error("All slots are blocked");
   }
 private:
   bool blocked;
   Combiner combiner;
};

//Quick and dirty sample using the blockable combiner
int bar() {
   return 1;
}

int main() {
   boost::signal<int (), blockable<boost::last_value<int> > > foo;
   foo.connect(&bar);
   try {
      //show that it works
      int x = foo();
      std::cout << x << std::endl;
      //Now block all slots
      foo.combiner().block();
      int y = foo();
      //This won't run since the last call to foo() should throw
      std::cout << y << std::endl;
   } catch (std::exception& e) {
      //Should get here via 2nd call to foo()
      std::cout << e.what() << std::endl;
   }
   return 0;
}
...