]> Dogcows Code - chaz/yoink/blob - src/moof/dispatcher.cc
begin cleaning up resource management
[chaz/yoink] / src / moof / dispatcher.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #include <map>
13
14 #include "dispatcher.hh"
15
16
17 namespace moof {
18
19
20 class dispatcher::impl
21 {
22 public:
23
24 impl(dispatcher* dispatcher) :
25 dispatcher_(dispatcher),
26 id_(0) {}
27
28 dispatcher::handle getNewHandle()
29 {
30 ++id_;
31 dispatcher::handle handle(dispatcher_->impl_, id_);
32 return handle;
33 }
34
35 typedef std::pair<unsigned,dispatcher::function> callback;
36 typedef std::multimap<std::string,callback> callback_lookup;
37 typedef callback_lookup::iterator callback_it;
38
39 typedef std::multimap<unsigned,std::string> handle_lookup;
40 typedef handle_lookup::iterator handle_it;
41
42
43 handle add_target(const std::string& event,
44 const function& callback,
45 handle handle)
46 {
47 callbacks_.insert(std::make_pair(event, std::make_pair(handle.id(),
48 callback)));
49 handles_.insert(std::make_pair(handle.id(), event));
50
51 return handle;
52 }
53
54 void remove_target(unsigned id)
55 {
56 std::pair<handle_it,handle_it> matching(handles_.equal_range(id));
57
58 for (handle_it it = matching.first; it != matching.second; ++it)
59 {
60 callback_it first = callbacks_.find((*it).second);
61 callback_it last = callbacks_.end();
62
63 for (callback_it jt = first; jt != last; ++jt)
64 {
65 if ((*jt).second.first == id)
66 {
67 callbacks_.erase(jt);
68 break;
69 }
70 }
71 }
72
73 handles_.erase(id);
74 }
75
76 void dispatch(const std::string& event)
77 {
78 std::pair<callback_it,callback_it>
79 callbacks(callbacks_.equal_range(event));
80
81 for (callback_it it = callbacks.first; it != callbacks.second; ++it)
82 {
83 function callback = (*it).second.second;
84 callback();
85 }
86 }
87
88
89 dispatcher* dispatcher_;
90
91 unsigned id_;
92
93 callback_lookup callbacks_;
94 handle_lookup handles_;
95 };
96
97
98 void dispatcher::handle::clear()
99 {
100 boost::shared_ptr<impl> dispatcher;
101 if (id_ && (dispatcher = dispatcher_.lock()))
102 {
103 dispatcher->remove_target(id_);
104 id_ = 0;
105 }
106 }
107
108
109 dispatcher::dispatcher() :
110 impl_(new dispatcher::impl(this)) {}
111
112
113 dispatcher::handle dispatcher::add_target(const std::string& event,
114 const function& callback)
115 {
116 return add_target(event, callback, impl_->getNewHandle());
117 }
118
119 dispatcher::handle dispatcher::add_target(const std::string& event,
120 const function& callback,
121 handle handle)
122 {
123 // pass through
124 return impl_->add_target(event, callback, handle);
125 }
126
127
128 void dispatcher::remove_target(unsigned id)
129 {
130 // pass through
131 return impl_->remove_target(id);
132 }
133
134
135 void dispatcher::dispatch(const std::string& event)
136 {
137 // pass through
138 impl_->dispatch(event);
139 }
140
141
142 dispatcher& dispatcher::global()
143 {
144 static dispatcher dispatcher;
145 return dispatcher;
146 }
147
148
149 } // namespace moof
150
This page took 0.035732 seconds and 4 git commands to generate.