]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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: | |
28 | Document() | |
29 | {} | |
30 | ||
31 | /* Connect a slot to the signal which will be emitted whenever | |
32 | text is appended to the document. */ | |
33 | boost::signals2::connection connect(const signal_t::slot_type &subscriber) | |
34 | { | |
35 | return m_sig.connect(subscriber); | |
36 | } | |
37 | ||
38 | void append(const char* s) | |
39 | { | |
40 | m_text += s; | |
41 | m_sig(); | |
42 | } | |
43 | ||
44 | 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> | |
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 | ||
70 | 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 | |
92f5a8d4 | 78 | TextView() : m_document(0) |
7c673cae FG |
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> | |
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 | ||
100 | 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 | |
92f5a8d4 | 115 | HexView(): m_document(0) |
7c673cae FG |
116 | {} |
117 | ||
118 | Document* m_document; | |
119 | }; | |
120 | ||
121 | namespace bs2 = boost::signals2; | |
122 | ||
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 | } |