@@ -94,12 +94,41 @@ auto Port<void>::typed_inward_binding() const noexcept -> Port<void>* {
9494}
9595
9696void Port<void >::set() {
97- validate (!has_inward_binding (), " set() may only be called on a ports that do not have an inward "
97+ validate (!has_inward_binding (), " set() may only be called on ports that do not have an inward "
9898 " binding!" );
9999
100100 auto * scheduler = environment ()->scheduler ();
101101 scheduler->set_port (this );
102102 this ->present_ = true ;
103103}
104104
105+ // This function can be used to chain two callbacks. This mechanism is not
106+ // very efficient if many callbacks are registered on the same port. However,
107+ // it is more efficient than, e.g., a vector of callbacks if usually only one
108+ // callback is registered. At the moment, we use at most two callbacks on the
109+ // same port (one if the port is in a multiport, and one if it is upstream of
110+ // a delayed connection).
111+ auto compose_callbacks (const PortCallback& callback1, const PortCallback& callback2) -> PortCallback {
112+ return [=](const BasePort& port) {
113+ callback1 (port);
114+ callback2 (port);
115+ };
116+ }
117+
118+ void BasePort::register_set_callback (const PortCallback& callback) {
119+ if (set_callback_ == nullptr ) {
120+ set_callback_ = callback;
121+ } else {
122+ set_callback_ = compose_callbacks (set_callback_, callback);
123+ }
124+ }
125+
126+ void BasePort::register_clean_callback (const PortCallback& callback) {
127+ if (clean_callback_ == nullptr ) {
128+ clean_callback_ = callback;
129+ } else {
130+ clean_callback_ = compose_callbacks (clean_callback_, callback);
131+ }
132+ }
133+
105134} // namespace reactor
0 commit comments