1 #ifndef _library__dispatch__hpp__included__
2 #define _library__dispatch__hpp__included__
13 threads::lock
& global_init_lock();
15 template<typename
... T
> struct source
;
18 * Dispatch target handler.
20 template<typename
... T
> struct target
23 * Create a new target handler.
31 * Destroy a target, detaching it from source.
35 * Connect a target to given source and give a handler.
37 * Parameter d: The source to connect to.
38 * Parameter _fn: The function to use as handler.
40 inline void set(source
<T
...>& d
, std::function
<void(T
...)> _fn
);
42 static void dummy(T
... args
) {};
43 void set_source(source
<T
...>* d
) { src
= d
; }
44 void call(T
... args
) { fn(args
...); }
46 std::function
<void(T
...)> fn
;
47 friend class source
<T
...>;
51 * Dispatch source (event generator).
53 template<typename
... T
> struct source
56 * Create a new event source.
58 * Parameter _name: The name of the event.
60 source(const char* _name
)
66 * Destory an event source.
68 * All targets are disconnected.
79 * Parameter args: The arguments to send.
81 void operator()(T
... args
)
85 typename
std::map
<uint64_t, target
<T
...>*>::iterator i
;
87 i
= targets().lower_bound(k
);
88 while(i
!= targets().end()) {
90 target
<T
...>* t
= i
->second
;
94 } catch(std::exception
& e
) {
95 (*errstrm
) << name
<< ": Error in handler: " << e
.what() << std::endl
;
98 i
= targets().lower_bound(k
);
103 * Connect a new target.
105 * Parameters target: The target to connect.
107 void connect(target
<T
...>& target
)
110 threads::alock
h(*lck
);
111 targets()[next_cbseq
++] = &target
;
112 target
.set_source(this);
115 * Disconnect a target.
117 * Parameters target: The target to disconnect.
119 void disconnect(target
<T
...>& target
)
124 threads::alock
h(*lck
);
125 for(auto i
= targets().begin(); i
!= targets().end(); i
++)
126 if(i
->second
== &target
) {
130 target
.set_source(NULL
);
133 * Set stream to send error messages to.
135 * Parameter to: The stream (if NULL, use std::cerr).
137 void errors_to(std::ostream
* to
)
139 errstrm
= to
? to
: &std::cerr
;
146 threads::alock
h(global_init_lock());
149 errstrm
= &std::cerr
;
153 lck
= new threads::lock
;
157 std::map
<uint64_t, target
<T
...>*>& targets()
159 if(!_targets
) _targets
= new std::map
<uint64_t, target
<T
...>*>;
162 std::map
<uint64_t, target
<T
...>*>* _targets
;
164 std::ostream
* errstrm
;
167 source(const source
<T
...>&);
168 source
<T
...>& operator=(const source
<T
...>&);
171 template <typename
... T
> target
<T
...>::~target()
174 src
->disconnect(*this);
177 template <typename
... T
> void target
<T
...>::set(source
<T
...>& d
, std::function
<void(T
...)> _fn
)