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

100 lines
3.8 KiB
C++

/* @file AbstractSource.hpp */
#pragma once
#include "AbstractEventProcessor.hpp"
#include "xo/reflect/TypeDescr.hpp"
#include "xo/callback/CallbackSet.hpp"
#include "xo/refcnt/Refcounted.hpp"
#include <string>
namespace xo {
namespace web { class StreamEndpointDescr; }
namespace reactor {
class AbstractSink;
template<typename T>
class Sink1;
/* abstract api for a source of events.
* Event representation is left open: Sources and Sinks
* need to have compatible event representations,
* and coordination is left to such (Source, Sink) pairs.
*
* See ReactorSource, for example
*
* Typically a Source will have one or more .add_callback()
* methods, for listening to source events
*/
class AbstractSource : public virtual AbstractEventProcessor {
public:
using StreamEndpointDescr = web::StreamEndpointDescr;
using TypeDescr = reflect::TypeDescr;
using CallbackId = fn::CallbackId;
public:
/* identify datatype for items delivered by this source */
virtual TypeDescr source_ev_type() const = 0;
/* if true: event objects (see .source_ev_type())
* may be overwritten between callbacks.
* A sink that wants to capture events
* (e.g. EventStore<>) will need to deep-copy them
* if false: event objects are preserved between callbacks.
*
* A source that stores events received from elsewhere (e.g. FifoQueue)
* is probably volatile.
*
* A source that remembers (in explicit memory) every event it produces
* is not volatile
*/
virtual bool is_volatile() const = 0;
/* counts #of outbound events ready for delivery,
* but not yet sent */
virtual uint32_t n_queued_out_ev() const = 0;
/* counts lifetime #of events delivered.
* see also AbstractSink.n_in_ev
*/
virtual uint32_t n_out_ev() const = 0;
/* if true, simulator will report interaction with this source */
virtual bool debug_sim_flag() const = 0;
/* set .trace_sim_flag */
virtual void set_debug_sim_flag(bool x) = 0;
virtual CallbackId attach_sink(ref::rp<AbstractSink> const & sink) = 0;
virtual void detach_sink(CallbackId id) = 0;
/* endpoint for a websocket subscriber;
* subscriber delivers events produced by this source
*/
StreamEndpointDescr stream_endpoint_descr(std::string const & url_prefix);
/* typically expect events to be delivered using a reactor or simulator.
* (for example see reactor/Reactor, simulator/Simulator);
* reactor allocates cpu, and controls event ordering across sources
* when there are multiple sources.
*
* However, also possible for user code to invoke .deliver_one() directly.
* Beware, may get unpredictable results if attempt to do this on a source
* that's also attached to a reactor.
*/
virtual std::uint64_t deliver_one() = 0;
/* convenience: call .deliver_one() n times, return sum of results */
std::uint64_t deliver_n(uint64_t n);
/* convenience: call .deliver_one() until it returns 0
* (beware of inexhaustible sources!)
*/
std::uint64_t deliver_all();
}; /*AbstractSource*/
using AbstractSourcePtr = ref::rp<AbstractSource>;
} /*namespace reactor*/
} /*namespace xo*/
/* end AbstractSource.hpp */