• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Document/View sample for Boost.Signals2.
2 // Expands on doc_view_acm.cpp example by using boost::signals2::deconstruct
3 // as a post-constructing factory function.
4 //
5 // Copyright Keith MacDonald 2005.
6 // Copyright Frank Mori Hess 2009.
7 //
8 // Use, modification and
9 // distribution is subject to the Boost Software License, Version
10 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 // For more information, see http://www.boost.org
13 
14 #include <iostream>
15 #include <string>
16 #include <boost/bind.hpp>
17 #include <boost/ref.hpp>
18 #include <boost/signals2/deconstruct.hpp>
19 #include <boost/signals2/signal.hpp>
20 #include <boost/shared_ptr.hpp>
21 
22 class Document
23 {
24 public:
25   typedef boost::signals2::signal<void ()>  signal_t;
26 
27 public:
Document()28   Document()
29   {}
30 
31   /* Connect a slot to the signal which will be emitted whenever
32     text is appended to the document. */
connect(const signal_t::slot_type & subscriber)33   boost::signals2::connection connect(const signal_t::slot_type &subscriber)
34   {
35     return m_sig.connect(subscriber);
36   }
37 
append(const char * s)38   void append(const char* s)
39   {
40     m_text += s;
41     m_sig();
42   }
43 
getText() const44   const std::string& getText() const
45   {
46     return m_text;
47   }
48 
49 private:
50   signal_t    m_sig;
51   std::string m_text;
52 };
53 
54 class TextView
55 {
56 public:
57   /* This adl_postconstruct function will be found
58   via argument-dependent lookup when using boost::signals2::deconstruct. */
59   template<typename T>
adl_postconstruct(const boost::shared_ptr<T> & view_sp,TextView * view,Document & doc)60     friend void adl_postconstruct(const boost::shared_ptr<T> &view_sp, TextView *view, Document& doc)
61   {
62     view->m_document = &doc;
63     {
64       typedef Document::signal_t::slot_type slot_type;
65       slot_type myslot(&TextView::refresh, view);
66       doc.connect(myslot.track(view_sp));
67     }
68   }
69 
refresh() const70   void refresh() const
71   {
72     std::cout << "TextView: " << m_document->getText() << std::endl;
73   }
74 private:
75   // give boost::signals2::deconstruct access to private constructor
76   friend class boost::signals2::deconstruct_access;
77   // private constructor to force use of deconstruct
TextView()78   TextView() : m_document(0)
79   {}
80 
81   Document*               m_document;
82 };
83 
84 class HexView
85 {
86 public:
87   /* This adl_postconstruct function will be found
88   via argument-dependent lookup when using boost::signals2::deconstruct. */
89   template<typename T>
adl_postconstruct(const boost::shared_ptr<T> & view_sp,HexView * view,Document & doc)90     friend void adl_postconstruct(const boost::shared_ptr<T> &view_sp, HexView *view, Document& doc)
91   {
92     view->m_document = &doc;
93     {
94       typedef Document::signal_t::slot_type slot_type;
95       slot_type myslot(&HexView::refresh, view);
96       doc.connect(myslot.track(view_sp));
97     }
98   }
99 
refresh() const100   void refresh() const
101   {
102     const std::string&  s = m_document->getText();
103 
104     std::cout << "HexView:";
105 
106     for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
107       std::cout << ' ' << std::hex << static_cast<int>(*it);
108 
109     std::cout << std::endl;
110   }
111 private:
112   // give boost::signals2::deconstruct access to private constructor
113   friend class boost::signals2::deconstruct_access;
114   // private constructor to force use of deconstruct
HexView()115   HexView(): m_document(0)
116   {}
117 
118   Document*               m_document;
119 };
120 
121 namespace bs2 = boost::signals2;
122 
main(int argc,char * argv[])123 int main(int argc, char* argv[])
124 {
125   Document    doc;
126   boost::shared_ptr<TextView> v1 = bs2::deconstruct<TextView>().postconstruct(boost::ref(doc));
127   boost::shared_ptr<HexView> v2 = bs2::deconstruct<HexView>().postconstruct(boost::ref(doc));
128 
129   doc.append(argc >= 2 ? argv[1] : "Hello world!");
130 
131   v2.reset(); // destroy the HexView, automatically disconnecting
132   doc.append("  HexView should no longer be connected.");
133 
134   return 0;
135 }
136