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