diff options
Diffstat (limited to 'include/libcamera/base')
-rw-r--r-- | include/libcamera/base/bound_method.h | 239 | ||||
-rw-r--r-- | include/libcamera/base/event_dispatcher.h | 35 | ||||
-rw-r--r-- | include/libcamera/base/event_dispatcher_poll.h | 58 | ||||
-rw-r--r-- | include/libcamera/base/log.h | 130 | ||||
-rw-r--r-- | include/libcamera/base/meson.build | 10 | ||||
-rw-r--r-- | include/libcamera/base/message.h | 71 | ||||
-rw-r--r-- | include/libcamera/base/object.h | 71 | ||||
-rw-r--r-- | include/libcamera/base/semaphore.h | 34 | ||||
-rw-r--r-- | include/libcamera/base/signal.h | 132 | ||||
-rw-r--r-- | include/libcamera/base/thread.h | 76 | ||||
-rw-r--r-- | include/libcamera/base/timer.h | 49 |
11 files changed, 905 insertions, 0 deletions
diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h new file mode 100644 index 00000000..282f9b58 --- /dev/null +++ b/include/libcamera/base/bound_method.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * bound_method.h - Method bind and invocation + */ +#ifndef __LIBCAMERA_BASE_BOUND_METHOD_H__ +#define __LIBCAMERA_BASE_BOUND_METHOD_H__ + +#include <memory> +#include <tuple> +#include <type_traits> +#include <utility> + +namespace libcamera { + +class Object; + +enum ConnectionType { + ConnectionTypeAuto, + ConnectionTypeDirect, + ConnectionTypeQueued, + ConnectionTypeBlocking, +}; + +class BoundMethodPackBase +{ +public: + virtual ~BoundMethodPackBase() = default; +}; + +template<typename R, typename... Args> +class BoundMethodPack : public BoundMethodPackBase +{ +public: + BoundMethodPack(const Args &... args) + : args_(args...) + { + } + + std::tuple<typename std::remove_reference_t<Args>...> args_; + R ret_; +}; + +template<typename... Args> +class BoundMethodPack<void, Args...> : public BoundMethodPackBase +{ +public: + BoundMethodPack(const Args &... args) + : args_(args...) + { + } + + std::tuple<typename std::remove_reference_t<Args>...> args_; +}; + +class BoundMethodBase +{ +public: + BoundMethodBase(void *obj, Object *object, ConnectionType type) + : obj_(obj), object_(object), connectionType_(type) + { + } + virtual ~BoundMethodBase() = default; + + template<typename T, typename std::enable_if_t<!std::is_same<Object, T>::value> * = nullptr> + bool match(T *obj) { return obj == obj_; } + bool match(Object *object) { return object == object_; } + + Object *object() const { return object_; } + + virtual void invokePack(BoundMethodPackBase *pack) = 0; + +protected: + bool activatePack(std::shared_ptr<BoundMethodPackBase> pack, + bool deleteMethod); + + void *obj_; + Object *object_; + +private: + ConnectionType connectionType_; +}; + +template<typename R, typename... Args> +class BoundMethodArgs : public BoundMethodBase +{ +public: + using PackType = BoundMethodPack<R, Args...>; + +private: + template<std::size_t... I> + void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) + { + PackType *args = static_cast<PackType *>(pack); + args->ret_ = invoke(std::get<I>(args->args_)...); + } + +public: + BoundMethodArgs(void *obj, Object *object, ConnectionType type) + : BoundMethodBase(obj, object, type) {} + + void invokePack(BoundMethodPackBase *pack) override + { + invokePack(pack, std::make_index_sequence<sizeof...(Args)>{}); + } + + virtual R activate(Args... args, bool deleteMethod = false) = 0; + virtual R invoke(Args... args) = 0; +}; + +template<typename... Args> +class BoundMethodArgs<void, Args...> : public BoundMethodBase +{ +public: + using PackType = BoundMethodPack<void, Args...>; + +private: + template<std::size_t... I> + void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) + { + /* args is effectively unused when the sequence I is empty. */ + PackType *args [[gnu::unused]] = static_cast<PackType *>(pack); + invoke(std::get<I>(args->args_)...); + } + +public: + BoundMethodArgs(void *obj, Object *object, ConnectionType type) + : BoundMethodBase(obj, object, type) {} + + void invokePack(BoundMethodPackBase *pack) override + { + invokePack(pack, std::make_index_sequence<sizeof...(Args)>{}); + } + + virtual void activate(Args... args, bool deleteMethod = false) = 0; + virtual void invoke(Args... args) = 0; +}; + +template<typename T, typename R, typename... Args> +class BoundMethodMember : public BoundMethodArgs<R, Args...> +{ +public: + using PackType = typename BoundMethodArgs<R, Args...>::PackType; + + BoundMethodMember(T *obj, Object *object, R (T::*func)(Args...), + ConnectionType type = ConnectionTypeAuto) + : BoundMethodArgs<R, Args...>(obj, object, type), func_(func) + { + } + + bool match(R (T::*func)(Args...)) const { return func == func_; } + + R activate(Args... args, bool deleteMethod = false) override + { + if (!this->object_) { + T *obj = static_cast<T *>(this->obj_); + return (obj->*func_)(args...); + } + + auto pack = std::make_shared<PackType>(args...); + bool sync = BoundMethodBase::activatePack(pack, deleteMethod); + return sync ? pack->ret_ : R(); + } + + R invoke(Args... args) override + { + T *obj = static_cast<T *>(this->obj_); + return (obj->*func_)(args...); + } + +private: + R (T::*func_)(Args...); +}; + +template<typename T, typename... Args> +class BoundMethodMember<T, void, Args...> : public BoundMethodArgs<void, Args...> +{ +public: + using PackType = typename BoundMethodArgs<void, Args...>::PackType; + + BoundMethodMember(T *obj, Object *object, void (T::*func)(Args...), + ConnectionType type = ConnectionTypeAuto) + : BoundMethodArgs<void, Args...>(obj, object, type), func_(func) + { + } + + bool match(void (T::*func)(Args...)) const { return func == func_; } + + void activate(Args... args, bool deleteMethod = false) override + { + if (!this->object_) { + T *obj = static_cast<T *>(this->obj_); + return (obj->*func_)(args...); + } + + auto pack = std::make_shared<PackType>(args...); + BoundMethodBase::activatePack(pack, deleteMethod); + } + + void invoke(Args... args) override + { + T *obj = static_cast<T *>(this->obj_); + return (obj->*func_)(args...); + } + +private: + void (T::*func_)(Args...); +}; + +template<typename R, typename... Args> +class BoundMethodStatic : public BoundMethodArgs<R, Args...> +{ +public: + BoundMethodStatic(R (*func)(Args...)) + : BoundMethodArgs<R, Args...>(nullptr, nullptr, ConnectionTypeAuto), + func_(func) + { + } + + bool match(R (*func)(Args...)) const { return func == func_; } + + R activate(Args... args, [[maybe_unused]] bool deleteMethod = false) override + { + return (*func_)(args...); + } + + R invoke(Args...) override + { + return R(); + } + +private: + R (*func_)(Args...); +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_BOUND_METHOD_H__ */ diff --git a/include/libcamera/base/event_dispatcher.h b/include/libcamera/base/event_dispatcher.h new file mode 100644 index 00000000..045df27f --- /dev/null +++ b/include/libcamera/base/event_dispatcher.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * event_dispatcher.h - Event dispatcher + */ +#ifndef __LIBCAMERA_BASE_EVENT_DISPATCHER_H__ +#define __LIBCAMERA_BASE_EVENT_DISPATCHER_H__ + +#include <vector> + +namespace libcamera { + +class EventNotifier; +class Timer; + +class EventDispatcher +{ +public: + virtual ~EventDispatcher(); + + virtual void registerEventNotifier(EventNotifier *notifier) = 0; + virtual void unregisterEventNotifier(EventNotifier *notifier) = 0; + + virtual void registerTimer(Timer *timer) = 0; + virtual void unregisterTimer(Timer *timer) = 0; + + virtual void processEvents() = 0; + + virtual void interrupt() = 0; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_EVENT_DISPATCHER_H__ */ diff --git a/include/libcamera/base/event_dispatcher_poll.h b/include/libcamera/base/event_dispatcher_poll.h new file mode 100644 index 00000000..ae2a3f04 --- /dev/null +++ b/include/libcamera/base/event_dispatcher_poll.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * event_dispatcher_poll.h - Poll-based event dispatcher + */ +#ifndef __LIBCAMERA_BASE_EVENT_DISPATCHER_POLL_H__ +#define __LIBCAMERA_BASE_EVENT_DISPATCHER_POLL_H__ + +#include <list> +#include <map> +#include <vector> + +#include <libcamera/base/event_dispatcher.h> + +struct pollfd; + +namespace libcamera { + +class EventNotifier; +class Timer; + +class EventDispatcherPoll final : public EventDispatcher +{ +public: + EventDispatcherPoll(); + ~EventDispatcherPoll(); + + void registerEventNotifier(EventNotifier *notifier); + void unregisterEventNotifier(EventNotifier *notifier); + + void registerTimer(Timer *timer); + void unregisterTimer(Timer *timer); + + void processEvents(); + void interrupt(); + +private: + struct EventNotifierSetPoll { + short events() const; + EventNotifier *notifiers[3]; + }; + + int poll(std::vector<struct pollfd> *pollfds); + void processInterrupt(const struct pollfd &pfd); + void processNotifiers(const std::vector<struct pollfd> &pollfds); + void processTimers(); + + std::map<int, EventNotifierSetPoll> notifiers_; + std::list<Timer *> timers_; + int eventfd_; + + bool processingEvents_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_EVENT_DISPATCHER_POLL_H__ */ diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h new file mode 100644 index 00000000..b93c947a --- /dev/null +++ b/include/libcamera/base/log.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018, Google Inc. + * + * log.h - Logging infrastructure + */ +#ifndef __LIBCAMERA_BASE_LOG_H__ +#define __LIBCAMERA_BASE_LOG_H__ + +#include <chrono> +#include <sstream> + +#include <libcamera/base/class.h> +#include <libcamera/base/utils.h> + +namespace libcamera { + +enum LogSeverity { + LogInvalid = -1, + LogDebug = 0, + LogInfo, + LogWarning, + LogError, + LogFatal, +}; + +class LogCategory +{ +public: + explicit LogCategory(const char *name); + + const char *name() const { return name_; } + LogSeverity severity() const { return severity_; } + void setSeverity(LogSeverity severity); + + static const LogCategory &defaultCategory(); + +private: + const char *name_; + LogSeverity severity_; +}; + +#define LOG_DECLARE_CATEGORY(name) \ +extern const LogCategory &_LOG_CATEGORY(name)(); + +#define LOG_DEFINE_CATEGORY(name) \ +const LogCategory &_LOG_CATEGORY(name)() \ +{ \ + /* The instance will be deleted by the Logger destructor. */ \ + static LogCategory *category = new LogCategory(#name); \ + return *category; \ +} + +class LogMessage +{ +public: + LogMessage(const char *fileName, unsigned int line, + const LogCategory &category, LogSeverity severity); + + LogMessage(LogMessage &&); + ~LogMessage(); + + std::ostream &stream() { return msgStream_; } + + const utils::time_point ×tamp() const { return timestamp_; } + LogSeverity severity() const { return severity_; } + const LogCategory &category() const { return category_; } + const std::string &fileInfo() const { return fileInfo_; } + const std::string msg() const { return msgStream_.str(); } + +private: + LIBCAMERA_DISABLE_COPY(LogMessage) + + void init(const char *fileName, unsigned int line); + + std::ostringstream msgStream_; + const LogCategory &category_; + LogSeverity severity_; + utils::time_point timestamp_; + std::string fileInfo_; +}; + +class Loggable +{ +public: + virtual ~Loggable(); + +protected: + virtual std::string logPrefix() const = 0; + + LogMessage _log(const LogCategory *category, LogSeverity severity, + const char *fileName = __builtin_FILE(), + unsigned int line = __builtin_LINE()) const; +}; + +LogMessage _log(const LogCategory *category, LogSeverity severity, + const char *fileName = __builtin_FILE(), + unsigned int line = __builtin_LINE()); + +#ifndef __DOXYGEN__ +#define _LOG_CATEGORY(name) logCategory##name + +#define _LOG1(severity) \ + _log(nullptr, Log##severity).stream() +#define _LOG2(category, severity) \ + _log(&_LOG_CATEGORY(category)(), Log##severity).stream() + +/* + * Expand the LOG() macro to _LOG1() or _LOG2() based on the number of + * arguments. + */ +#define _LOG_MACRO(_1, _2, NAME, ...) NAME +#define LOG(...) _LOG_MACRO(__VA_ARGS__, _LOG2, _LOG1)(__VA_ARGS__) +#else /* __DOXYGEN___ */ +#define LOG(category, severity) +#endif /* __DOXYGEN__ */ + +#ifndef NDEBUG +#define ASSERT(condition) static_cast<void>(({ \ + if (!(condition)) \ + LOG(Fatal) << "assertion \"" #condition "\" failed in " \ + << __func__ << "()"; \ +})) +#else +#define ASSERT(condition) static_cast<void>(false && (condition)) +#endif + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_LOG_H__ */ diff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build index 2db756c5..7a858dcb 100644 --- a/include/libcamera/base/meson.build +++ b/include/libcamera/base/meson.build @@ -3,7 +3,17 @@ libcamera_base_include_dir = libcamera_include_dir / 'base' libcamera_base_headers = files([ + 'bound_method.h', 'class.h', + 'event_dispatcher.h', + 'event_dispatcher_poll.h', + 'log.h', + 'message.h', + 'object.h', + 'semaphore.h', + 'signal.h', + 'thread.h', + 'timer.h', 'utils.h', ]) diff --git a/include/libcamera/base/message.h b/include/libcamera/base/message.h new file mode 100644 index 00000000..5d2a9f04 --- /dev/null +++ b/include/libcamera/base/message.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * message.h - Message queue support + */ +#ifndef __LIBCAMERA_BASE_MESSAGE_H__ +#define __LIBCAMERA_BASE_MESSAGE_H__ + +#include <atomic> + +#include <libcamera/base/bound_method.h> + +namespace libcamera { + +class BoundMethodBase; +class Object; +class Semaphore; +class Thread; + +class Message +{ +public: + enum Type { + None = 0, + InvokeMessage = 1, + ThreadMoveMessage = 2, + DeferredDelete = 3, + UserMessage = 1000, + }; + + Message(Type type); + virtual ~Message(); + + Type type() const { return type_; } + Object *receiver() const { return receiver_; } + + static Type registerMessageType(); + +private: + friend class Thread; + + Type type_; + Object *receiver_; + + static std::atomic_uint nextUserType_; +}; + +class InvokeMessage : public Message +{ +public: + InvokeMessage(BoundMethodBase *method, + std::shared_ptr<BoundMethodPackBase> pack, + Semaphore *semaphore = nullptr, + bool deleteMethod = false); + ~InvokeMessage(); + + Semaphore *semaphore() const { return semaphore_; } + + void invoke(); + +private: + BoundMethodBase *method_; + std::shared_ptr<BoundMethodPackBase> pack_; + Semaphore *semaphore_; + bool deleteMethod_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_MESSAGE_H__ */ diff --git a/include/libcamera/base/object.h b/include/libcamera/base/object.h new file mode 100644 index 00000000..5c385ab4 --- /dev/null +++ b/include/libcamera/base/object.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * object.h - Base object + */ +#ifndef __LIBCAMERA_BASE_OBJECT_H__ +#define __LIBCAMERA_BASE_OBJECT_H__ + +#include <list> +#include <memory> +#include <vector> + +#include <libcamera/base/bound_method.h> + +namespace libcamera { + +class Message; +template<typename... Args> +class Signal; +class SignalBase; +class Thread; + +class Object +{ +public: + Object(Object *parent = nullptr); + virtual ~Object(); + + void deleteLater(); + + void postMessage(std::unique_ptr<Message> msg); + + template<typename T, typename R, typename... FuncArgs, typename... Args, + typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> + R invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type, + Args... args) + { + T *obj = static_cast<T *>(this); + auto *method = new BoundMethodMember<T, R, FuncArgs...>(obj, this, func, type); + return method->activate(args..., true); + } + + Thread *thread() const { return thread_; } + void moveToThread(Thread *thread); + + Object *parent() const { return parent_; } + +protected: + virtual void message(Message *msg); + +private: + friend class SignalBase; + friend class Thread; + + void notifyThreadMove(); + + void connect(SignalBase *signal); + void disconnect(SignalBase *signal); + + Object *parent_; + std::vector<Object *> children_; + + Thread *thread_; + std::list<SignalBase *> signals_; + unsigned int pendingMessages_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_OBJECT_H__ */ diff --git a/include/libcamera/base/semaphore.h b/include/libcamera/base/semaphore.h new file mode 100644 index 00000000..c8e62e3e --- /dev/null +++ b/include/libcamera/base/semaphore.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * semaphore.h - General-purpose counting semaphore + */ +#ifndef __LIBCAMERA_BASE_SEMAPHORE_H__ +#define __LIBCAMERA_BASE_SEMAPHORE_H__ + +#include <condition_variable> + +#include <libcamera/base/thread.h> + +namespace libcamera { + +class Semaphore +{ +public: + Semaphore(unsigned int n = 0); + + unsigned int available(); + void acquire(unsigned int n = 1); + bool tryAcquire(unsigned int n = 1); + void release(unsigned int n = 1); + +private: + Mutex mutex_; + std::condition_variable cv_; + unsigned int available_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_SEMAPHORE_H__ */ diff --git a/include/libcamera/base/signal.h b/include/libcamera/base/signal.h new file mode 100644 index 00000000..c2521769 --- /dev/null +++ b/include/libcamera/base/signal.h @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * signal.h - Signal & slot implementation + */ +#ifndef __LIBCAMERA_BASE_SIGNAL_H__ +#define __LIBCAMERA_BASE_SIGNAL_H__ + +#include <functional> +#include <list> +#include <type_traits> +#include <vector> + +#include <libcamera/base/bound_method.h> +#include <libcamera/base/object.h> + +namespace libcamera { + +class SignalBase +{ +public: + void disconnect(Object *object); + +protected: + using SlotList = std::list<BoundMethodBase *>; + + void connect(BoundMethodBase *slot); + void disconnect(std::function<bool(SlotList::iterator &)> match); + + SlotList slots(); + +private: + SlotList slots_; +}; + +template<typename... Args> +class Signal : public SignalBase +{ +public: + ~Signal() + { + disconnect(); + } + +#ifndef __DOXYGEN__ + template<typename T, typename R, typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> + void connect(T *obj, R (T::*func)(Args...), + ConnectionType type = ConnectionTypeAuto) + { + Object *object = static_cast<Object *>(obj); + SignalBase::connect(new BoundMethodMember<T, R, Args...>(obj, object, func, type)); + } + + template<typename T, typename R, typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr> +#else + template<typename T, typename R> +#endif + void connect(T *obj, R (T::*func)(Args...)) + { + SignalBase::connect(new BoundMethodMember<T, R, Args...>(obj, nullptr, func)); + } + + template<typename R> + void connect(R (*func)(Args...)) + { + SignalBase::connect(new BoundMethodStatic<R, Args...>(func)); + } + + void disconnect() + { + SignalBase::disconnect([]([[maybe_unused]] SlotList::iterator &iter) { + return true; + }); + } + + template<typename T> + void disconnect(T *obj) + { + SignalBase::disconnect([obj](SlotList::iterator &iter) { + return (*iter)->match(obj); + }); + } + + template<typename T, typename R> + void disconnect(T *obj, R (T::*func)(Args...)) + { + SignalBase::disconnect([obj, func](SlotList::iterator &iter) { + BoundMethodArgs<R, Args...> *slot = + static_cast<BoundMethodArgs<R, Args...> *>(*iter); + + if (!slot->match(obj)) + return false; + + /* + * If the object matches the slot, the slot is + * guaranteed to be a member slot, so we can safely + * cast it to BoundMethodMember<T, Args...> to match + * func. + */ + return static_cast<BoundMethodMember<T, R, Args...> *>(slot)->match(func); + }); + } + + template<typename R> + void disconnect(R (*func)(Args...)) + { + SignalBase::disconnect([func](SlotList::iterator &iter) { + BoundMethodArgs<R, Args...> *slot = + static_cast<BoundMethodArgs<R, Args...> *>(*iter); + + if (!slot->match(nullptr)) + return false; + + return static_cast<BoundMethodStatic<R, Args...> *>(slot)->match(func); + }); + } + + void emit(Args... args) + { + /* + * Make a copy of the slots list as the slot could call the + * disconnect operation, invalidating the iterator. + */ + for (BoundMethodBase *slot : slots()) + static_cast<BoundMethodArgs<void, Args...> *>(slot)->activate(args...); + } +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_SIGNAL_H__ */ diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h new file mode 100644 index 00000000..2ed18d49 --- /dev/null +++ b/include/libcamera/base/thread.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * thread.h - Thread support + */ +#ifndef __LIBCAMERA_BASE_THREAD_H__ +#define __LIBCAMERA_BASE_THREAD_H__ + +#include <memory> +#include <mutex> +#include <sys/types.h> +#include <thread> + +#include <libcamera/base/message.h> +#include <libcamera/base/signal.h> +#include <libcamera/base/utils.h> + +namespace libcamera { + +class EventDispatcher; +class Message; +class Object; +class ThreadData; +class ThreadMain; + +using Mutex = std::mutex; +using MutexLocker = std::unique_lock<std::mutex>; + +class Thread +{ +public: + Thread(); + virtual ~Thread(); + + void start(); + void exit(int code = 0); + bool wait(utils::duration duration = utils::duration::max()); + + bool isRunning(); + + Signal<Thread *> finished; + + static Thread *current(); + static pid_t currentId(); + + EventDispatcher *eventDispatcher(); + + void dispatchMessages(Message::Type type = Message::Type::None); + +protected: + int exec(); + virtual void run(); + +private: + void startThread(); + void finishThread(); + + void postMessage(std::unique_ptr<Message> msg, Object *receiver); + void removeMessages(Object *receiver); + + friend class Object; + friend class ThreadData; + friend class ThreadMain; + + void moveObject(Object *object); + void moveObject(Object *object, ThreadData *currentData, + ThreadData *targetData); + + std::thread thread_; + ThreadData *data_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_THREAD_H__ */ diff --git a/include/libcamera/base/timer.h b/include/libcamera/base/timer.h new file mode 100644 index 00000000..e79e85f1 --- /dev/null +++ b/include/libcamera/base/timer.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * timer.h - Generic timer + */ +#ifndef __LIBCAMERA_BASE_TIMER_H__ +#define __LIBCAMERA_BASE_TIMER_H__ + +#include <chrono> +#include <stdint.h> + +#include <libcamera/base/object.h> +#include <libcamera/base/signal.h> + +namespace libcamera { + +class Message; + +class Timer : public Object +{ +public: + Timer(Object *parent = nullptr); + ~Timer(); + + void start(unsigned int msec) { start(std::chrono::milliseconds(msec)); } + void start(std::chrono::milliseconds duration); + void start(std::chrono::steady_clock::time_point deadline); + void stop(); + bool isRunning() const; + + std::chrono::steady_clock::time_point deadline() const { return deadline_; } + + Signal<Timer *> timeout; + +protected: + void message(Message *msg) override; + +private: + void registerTimer(); + void unregisterTimer(); + + bool running_; + std::chrono::steady_clock::time_point deadline_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_BASE_TIMER_H__ */ |