2010-08-06 75 views
1

升壓信號允許通過連接成員功能暫時阻止連接。但是,我有一個單一的信號與許多連接。連接由各自的聽衆存儲和維護。現在廣播公司決定暫時停止發送信號。似乎沒有辦法迭代信號的所有連接或臨時禁用整個信號。這對我來說似乎很奇怪,因爲這種機制肯定必須存在於內部,以便信號在發出信號時到達所有用戶......
我是否錯過了什麼?我怎樣才能暫時禁用信號?阻止連接到升壓信號的所有連接

回答

2

我不知道有什麼辦法直接做到這一點。如果您願意永久斷開所有插槽,則可以使用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; 
}