summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/signals2/example/doc_view_acm.cpp
blob: ffc79082673bb6d9c93769e31a7e8cae0cc874ac (plain)
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
// Document/View sample for Boost.Signals2.
// Expands on doc_view.cpp example by using automatic
// connection management.
//
// 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/io/ios_state.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:
  // static factory function that sets up automatic connection tracking
  static boost::shared_ptr<TextView> create(Document& doc)
  {
    boost::shared_ptr<TextView> new_view(new TextView(doc));
    {
      typedef Document::signal_t::slot_type slot_type;
      slot_type myslot(&TextView::refresh, new_view.get());
      doc.connect(myslot.track(new_view));
    }
    return new_view;
  }

  void refresh() const
  {
    std::cout << "TextView: " << m_document.getText() << std::endl;
  }
private:
    // private constructor to force use of static factory function
    TextView(Document &doc): m_document(doc)
    {}

    Document&               m_document;
};

class HexView
{
public:
  // static factory function that sets up automatic connection tracking
  static boost::shared_ptr<HexView> create(Document& doc)
  {
    boost::shared_ptr<HexView> new_view(new HexView(doc));
    {
      typedef Document::signal_t::slot_type slot_type;
      slot_type myslot(&HexView::refresh, new_view.get());
      doc.connect(myslot.track(new_view));
    }
    return new_view;
  }

  void refresh() const
  {
    boost::io::ios_flags_saver ifs(std::cout);
    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:
  // private constructor to force use of static factory function
  HexView(Document& doc): m_document(doc)
  {}

  Document&               m_document;
};

int main(int argc, char* argv[])
{
  Document    doc;
  boost::shared_ptr<TextView> v1 = TextView::create(doc);
  boost::shared_ptr<HexView> v2 = HexView::create(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;
}