blob: 38ceaec174e6c3edfae8b4e587f4cb82dbcda3e8 [file] [log] [blame]
#ifndef _AOS_EVENTS_RAW_EVENT_LOOP_H_
#define _AOS_EVENTS_RAW_EVENT_LOOP_H_
#include <atomic>
#include <memory>
#include <string>
#include "aos/common/queue.h"
#include "aos/common/time.h"
// This file contains raw versions of the classes in event-loop.h.
//
// Users should look exclusively at event-loop.h. Only people who wish to
// implement a new IPC layer (like a fake layer for example) may wish to use
// these classes.
namespace aos {
// Raw version of fetcher. Contains a local variable that the fetcher will
// update.
// It is the job of the typed version to cast this to the appropriate type.
class RawFetcher {
public:
class FetchValue;
RawFetcher() {}
virtual ~RawFetcher() {}
virtual bool Fetch() = 0;
const FetchValue *most_recent() { return most_recent_; }
protected:
RawFetcher(const RawFetcher &) = delete;
RawFetcher &operator=(const RawFetcher &) = delete;
void set_most_recent(const FetchValue *most_recent) {
most_recent_ = most_recent;
}
private:
const FetchValue *most_recent_ = nullptr;
};
// Raw version of sender. Sending a message is a 3 part process. Fetch an opaque
// token, cast that token to the message type, populate and then calling one of
// Send() or Free().
class RawSender {
public:
class SendContext;
RawSender() {}
virtual ~RawSender() {}
virtual SendContext *GetContext() = 0;
virtual void Free(SendContext *context) = 0;
virtual bool Send(SendContext *context) = 0;
// Call operator that calls Free().
template <typename T>
void operator()(T *t) {
Free(reinterpret_cast<SendContext *>(t));
}
protected:
RawSender(const RawSender &) = delete;
RawSender &operator=(const RawSender &) = delete;
};
// Opaque Information extracted from a particular type passed to the underlying
// system so that it knows how much memory to allocate etc.
struct QueueTypeInfo {
// Message size:
size_t size;
// This should be a globally unique identifier for the type.
int hash;
// Config parameter for how long the queue should be.
int queue_length;
template <typename T>
static QueueTypeInfo Get() {
QueueTypeInfo info;
info.size = sizeof(T);
info.hash = T::kHash;
info.queue_length = T::kQueueLength;
return info;
}
};
// Virtual base class for all event queue-types.
class RawEventLoop {
public:
virtual ~RawEventLoop() {}
// Current time.
virtual monotonic_clock::time_point monotonic_now() = 0;
// The passed in function will be called when the event loop starts.
// Use this to run code once the thread goes into "real-time-mode",
virtual void OnRun(std::function<void()> on_run) = 0;
bool is_running() const { return is_running_.load(); }
// Starts receiving events.
virtual void Run() = 0;
// Stops receiving events.
virtual void Exit() = 0;
protected:
void set_is_running(bool value) { is_running_.store(value); }
// Will send new messages from (path, type).
virtual std::unique_ptr<RawSender> MakeRawSender(
const std::string &path, const QueueTypeInfo &type) = 0;
// Will fetch new messages from (path, type).
virtual std::unique_ptr<RawFetcher> MakeRawFetcher(
const std::string &path, const QueueTypeInfo &type) = 0;
// Will watch (path, type) for new messages
virtual void MakeRawWatcher(
const std::string &path, const QueueTypeInfo &type,
std::function<void(const Message *message)> watcher) = 0;
private:
std::atomic<bool> is_running_{false};
};
} // namespace aos
#endif // _AOS_EVENTS_RAW_EVENT_LOOP_H_