add observer_handler class

This commit is contained in:
MihailRis 2025-03-18 22:16:26 +03:00
parent b3feb5945b
commit 3beafe953f
6 changed files with 72 additions and 13 deletions

View File

@ -7,6 +7,7 @@
#include "delegates.hpp" #include "delegates.hpp"
#include "typedefs.hpp" #include "typedefs.hpp"
#include "util/observer_handler.hpp"
enum class setting_format { simple, percent }; enum class setting_format { simple, percent };
@ -47,9 +48,8 @@ public:
if (callOnStart) { if (callOnStart) {
callback(value); callback(value);
} }
return std::shared_ptr<int>(new int(id), [this](int* id) { //-V508 return observer_handler([this, id]() {
observers.erase(*id); observers.erase(id);
delete id;
}); });
} }

View File

@ -1,5 +1,3 @@
#include <filesystem>
#include "engine/Engine.hpp" #include "engine/Engine.hpp"
#include "frontend/hud.hpp" #include "frontend/hud.hpp"
#include "frontend/screens/Screen.hpp" #include "frontend/screens/Screen.hpp"
@ -8,6 +6,7 @@
#include "io/io.hpp" #include "io/io.hpp"
#include "libgui.hpp" #include "libgui.hpp"
#include "util/stringutil.hpp" #include "util/stringutil.hpp"
#include "util/observer_handler.hpp"
#include "window/Events.hpp" #include "window/Events.hpp"
#include "window/input.hpp" #include "window/input.hpp"
#include "coders/toml.hpp" #include "coders/toml.hpp"
@ -61,13 +60,13 @@ static int l_add_callback(lua::State* L) {
} }
if (hud) { if (hud) {
hud->keepAlive(handler); hud->keepAlive(std::move(handler));
return 0; return 0;
} else if (lua::gettop(L) >= 3) { } else if (lua::gettop(L) >= 3) {
auto node = get_document_node(L, 3); auto node = get_document_node(L, 3);
if (auto container = if (auto container =
std::dynamic_pointer_cast<gui::Container>(node.node)) { std::dynamic_pointer_cast<gui::Container>(node.node)) {
container->keepAlive(handler); container->keepAlive(std::move(handler));
return 0; return 0;
} }
throw std::runtime_error("owner expected to be a container"); throw std::runtime_error("owner expected to be a container");

View File

@ -4,7 +4,8 @@
#include <stdint.h> #include <stdint.h>
using scriptenv = std::shared_ptr<int>; using scriptenv = std::shared_ptr<int>;
using observer_handler = std::shared_ptr<int>;
class observer_handler;
/// @brief dynamic integer type (64 bit signed integer) /// @brief dynamic integer type (64 bit signed integer)
using integer_t = int64_t; using integer_t = int64_t;

View File

@ -7,6 +7,7 @@
#include "delegates.hpp" #include "delegates.hpp"
#include "typedefs.hpp" #include "typedefs.hpp"
#include "util/observer_handler.hpp"
namespace util { namespace util {
template <class... Types> template <class... Types>
@ -35,13 +36,12 @@ namespace util {
int id = nextid++; int id = nextid++;
handlers[id] = std::move(handler); handlers[id] = std::move(handler);
order.push_back(id); order.push_back(id);
return observer_handler(new int(id), [this](int* id) { //-V508 return observer_handler([this, id]() {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
handlers.erase(*id); handlers.erase(id);
order.erase( order.erase(
std::remove(order.begin(), order.end(), *id), order.end() std::remove(order.begin(), order.end(), id), order.end()
); );
delete id;
}); });
} }

View File

@ -3,20 +3,39 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "util/observer_handler.hpp"
namespace util { namespace util {
/// @brief Keeps shared pointers alive until destruction /// @brief Keeps shared pointers alive until destruction
class ObjectsKeeper { class ObjectsKeeper {
std::vector<std::shared_ptr<void>> ptrs; std::vector<std::shared_ptr<void>> ptrs;
std::vector<observer_handler> handlers;
public: public:
ObjectsKeeper() = default;
ObjectsKeeper(const ObjectsKeeper&) = delete;
ObjectsKeeper(ObjectsKeeper&& keeper) noexcept
: ptrs(std::move(keeper.ptrs)),
handlers(std::move(keeper.handlers)) {
}
ObjectsKeeper& operator=(ObjectsKeeper&& keeper) noexcept = default;
virtual ~ObjectsKeeper() { virtual ~ObjectsKeeper() {
} }
virtual void keepAlive(std::shared_ptr<void> ptr) { virtual void keepAlive(std::shared_ptr<void> ptr) {
ptrs.push_back(ptr); ptrs.push_back(std::move(ptr));
}
virtual void keepAlive(observer_handler&& ptr) {
handlers.emplace_back(std::move(ptr));
} }
virtual void clearKeepedObjects() { virtual void clearKeepedObjects() {
ptrs.clear(); ptrs.clear();
handlers.clear();
} }
}; };
} }

View File

@ -0,0 +1,40 @@
#pragma once
#include <functional>
class observer_handler {
public:
observer_handler() = default;
observer_handler(std::function<void()> destructor)
: destructor(std::move(destructor)) {
}
observer_handler(const observer_handler&) = delete;
observer_handler(observer_handler&& handler) noexcept
: destructor(std::move(handler.destructor)) {
}
~observer_handler() {
if (destructor) {
destructor();
}
}
bool operator==(std::nullptr_t) const {
return destructor == nullptr;
}
observer_handler& operator=(const observer_handler& handler) = delete;
observer_handler& operator=(observer_handler&& handler) noexcept {
if (destructor) {
destructor();
}
destructor = std::move(handler.destructor);
return *this;
}
private:
std::function<void()> destructor;
};