代码之家  ›  专栏  ›  技术社区  ›  BuschnicK

阻断所有连接到增压信号的连接

  •  1
  • BuschnicK  · 技术社区  · 15 年前

    升压信号允许通过连接成员函数暂时阻断连接。然而,我有一个单一的信号与许多连接。连接由各自的侦听器存储和维护。现在广播公司决定暂时停止发送信号。似乎没有一种方法可以迭代一个信号的所有连接或暂时禁用整个信号。这对我来说似乎很奇怪,因为肯定这样一种机制必须在内部存在,以便信号在发出信号时到达其所有用户。。。
    我错过什么了吗?如何临时禁用信号?

    1 回复  |  直到 15 年前
        1
  •  2
  •   JRM    15 年前

    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;
    }