#ifndef SOPHIAR2_GLOBAL_OBJ_HELPER_HPP #define SOPHIAR2_GLOBAL_OBJ_HELPER_HPP #include "core/small_obj.hpp" #include "core/sophiar_manager.h" #include "utility/coro_signal2.hpp" namespace sophiar { template class global_obj_delegate { public: using pointer_type = typename SmallObjType::pointer; global_obj_delegate(sophiar_manager &_manager, global_obj_index_type _obj_index) : manager(_manager), watcher(_manager.request_global_obj_update_watcher(_obj_index)), obj_index(_obj_index) {} global_obj_delegate(sophiar_manager &_manager, const std::string &obj_name) : global_obj_delegate(_manager, _manager.register_global_obj(obj_name)) {} global_obj_delegate(global_obj_delegate &other) noexcept : manager(other.manager), watcher(std::move(other.watcher)), obj_index(other.obj_index), obj_ptr(std::move(other.obj_ptr)) {} void set_value(const pointer_type &ptr, timestamp_type ts = current_timestamp()) { assert(ptr.get() != nullptr); manager.update_global_obj(obj_index, ptr, ts); } pointer_type get_value() { if constexpr (AutoSync) { if (watcher.try_wait()) { // new value available obj_ptr = manager.get_global_obj(obj_index); } } return obj_ptr; } bool empty() { return get_value() == nullptr; } timestamp_type get_last_update_ts() const { return watcher.get_last_update_ts(); } global_obj_delegate &operator=(const pointer_type &ptr) { set_value(ptr); return *this; } const SmallObjType &operator*() { assert(!empty()); return *get_value(); } const SmallObjType *operator->() { assert(!empty()); return get_value().get(); } boost::asio::awaitable coro_wait_update(bool auto_sync = true) { co_await watcher.coro_wait(auto_sync); obj_ptr = manager.get_global_obj(obj_index); co_return; } private: global_obj_index_type obj_index; pointer_type obj_ptr; signal_watcher watcher; sophiar_manager &manager; }; template using global_obj_auto_sync_delegate = global_obj_delegate; template using global_obj_manual_sync_delegate = global_obj_delegate; } #endif //SOPHIAR2_GLOBAL_OBJ_HELPER_HPP