void add(const SubscriberFrom& sf, observer_type o) const { trace_activity().connect(sf, o); std::unique_lock<std::mutex> guard(b->state->lock); switch (b->state->current) { case mode::Casting: { if (o.is_subscribed()) { b->completer = std::make_shared<completer_type>(b->state, b->completer, o); ++b->state->generation; } } break; case mode::Completed: { guard.unlock(); o.on_completed(); return; } break; case mode::Errored: { auto e = b->state->error; guard.unlock(); o.on_error(e); return; } break; default: abort(); } }
void on_error(std::exception_ptr e) const { if (!is_subscribed()) { return; } detacher protect(this); destination.on_error(e); }
void on_completed() const { if (!is_subscribed()) { return; } detacher protect(this); destination.on_completed(); }
void on_next(V&& v) const { if (!is_subscribed()) { return; } detacher protect(this); destination.on_next(std::forward<V>(v)); protect.that = nullptr; }
void add(const SubscriberFrom& sf, observer_type o) const { trace_activity().connect(sf, o); std::unique_lock<std::mutex> guard(b->state->lock); switch (b->state->current) { case mode::Casting: { if (o.is_subscribed()) { std::weak_ptr<binder_type> binder = b; o.add([=](){ auto b = binder.lock(); if (b) { std::unique_lock<std::mutex> guard(b->state->lock); b->completer = std::make_shared<completer_type>(b->state, b->completer); } }); b->completer = std::make_shared<completer_type>(b->state, b->completer, o); } } break; case mode::Completed: { guard.unlock(); o.on_completed(); return; } break; case mode::Errored: { auto e = b->state->error; guard.unlock(); o.on_error(e); return; } break; case mode::Disposed: { guard.unlock(); o.unsubscribe(); return; } break; default: std::terminate(); } }
completer_type(std::shared_ptr<state_type> s, const std::shared_ptr<completer_type>& old, observer_type o) : state(s) { if (old) { observers.reserve(old->observers.size() + 1); std::copy_if( old->observers.begin(), old->observers.end(), std::inserter(observers, observers.end()), [](const observer_type& o){ return o.is_subscribed(); }); } observers.push_back(o); }
// from observable<i_packet_stream_observer<PacketType, Protocol> > virtual void notify_observer(observer_type& aObserver, typename observer_type::notify_type aType, const void* aParameter, const void*) { switch(aType) { case observer_type::NotifyConnectionEstablished: aObserver.connection_established(*this); break; case observer_type::NotifyConnectionFailure: aObserver.connection_failure(*this, *static_cast<const boost::system::error_code*>(aParameter)); break; case observer_type::NotifyPacketSent: aObserver.packet_sent(*this, *static_cast<const packet_type*>(aParameter)); break; case observer_type::NotifyPacketArrived: aObserver.packet_arrived(*this, *static_cast<const packet_type*>(aParameter)); break; case observer_type::NotifyTransferFailure: aObserver.transfer_failure(*this, *static_cast<const boost::system::error_code*>(aParameter)); break; case observer_type::NotifyConnectionClosed: aObserver.connection_closed(*this); break; } }