xo-expression2/xo-reactor/include/xo/reactor/PolyAdapterSink.hpp

92 lines
3.4 KiB
C++

/* file PolyAdapterSink.hpp
*
* author: Roland Conybeare, Sep 2022
*/
#pragma once
#include "Sink.hpp"
#include "xo/reflect/Reflect.hpp"
namespace xo {
namespace reactor {
/* adapter between a source that delivers a particular event type T,
* and a sink that accepts arbitrarily-typed events via .notify_ev_tp()
* Use this to connect to a polymorphic sink.
*
* Require:
* - .poly_sink.allow_polymorphic_source()
* (ofc. otherwise no point in using PolyAdapterSink<T>)
* - .poly_sink.allow_volatile_source()
* need this bc will be wrapping event with TaggedPtr,
* which doesn't manage event lifetime
*/
template<typename T>
class PolyAdapterSink : public reactor::Sink1<T> {
public:
using Reflect = reflect::Reflect;
using TaggedPtr = reflect::TaggedPtr;
public:
/* named ctor idiom */
static rp<PolyAdapterSink> make(rp<AbstractSink> poly_sink) {
//xo::scope lscope("PolyAdapterSink::make");
rp<PolyAdapterSink> retval(new PolyAdapterSink(poly_sink));
//lscope.log("adapter", (void*)retval.get());
return retval;
} /*make*/
// ----- Inherited from Sink1<T> -----
virtual void notify_ev(T const & ev) override {
//xo::scope lscope("PolyAdapterSink::notify_ev");
//lscope.log(xo::xtag("ev", ev));
TaggedPtr ev_tp = Reflect::make_tp(const_cast<T *>(&ev));
this->notify_ev_tp(ev_tp);
} /*notify_ev*/
// ----- Inherited from AbstractSink -----
virtual bool allow_volatile_source() const override { return true; }
virtual uint32_t n_in_ev() const override { return this->poly_sink_->n_in_ev(); }
/* note: ok to do this, however if expecting to use this entry point,
* maybe don't need to interpose PolyAdapterSink<T> ahead of .poly_sink
*/
virtual void notify_ev_tp(TaggedPtr const & ev_tp) override {
//xo::scope lscope("PolyAdapterSink::notify_ev_tp");
return this->poly_sink_->notify_ev_tp(ev_tp);
}
// ----- Inherited from AbstractEventProcessor -----
virtual std::string const & name() const override { return this->poly_sink_->name(); }
virtual void set_name(std::string const & x) override { this->poly_sink_->set_name(x); }
virtual void visit_direct_consumers(std::function<void (bp<AbstractEventProcessor> ep)> const & fn) override {
this->poly_sink_->visit_direct_consumers(fn);
}
virtual void display(std::ostream & os) const override {
using xo::xtag;
os << "<PolyAdapterSink"
<< xtag("addr", (void*)this)
<< xtag("T", reflect::type_name<T>())
<< xtag("poly", this->poly_sink_)
<< ">";
} /*display*/
private:
PolyAdapterSink(rp<AbstractSink> poly_sink) : poly_sink_{std::move(poly_sink)} {}
private:
/* mandate: .poly_sink.allow_polymorphic_source() is true */
rp<AbstractSink> poly_sink_;
}; /*PolyAdapterSink*/
} /*namespace reactor*/
} /*namespace xo*/
/* end PolyAdapterSink.hpp */