#pragma once #include "emulator.hpp" class scoped_hook { public: scoped_hook() = default; scoped_hook(emulator& emu) : emu_(&emu) { } scoped_hook(emulator& emu, emulator_hook* hook) : scoped_hook(emu, std::vector{hook}) { } scoped_hook(emulator& emu, std::vector hooks) : emu_(&emu), hooks_(std::move(hooks)) { } ~scoped_hook() { this->remove(); } scoped_hook(const scoped_hook&) = delete; scoped_hook& operator=(const scoped_hook&) = delete; scoped_hook(scoped_hook&& obj) noexcept { this->operator=(std::move(obj)); } scoped_hook& operator=(scoped_hook&& obj) noexcept { if (this != &obj) { this->remove(); this->emu_ = obj.emu_; this->hooks_ = std::move(obj.hooks_); obj.hooks_ = {}; } return *this; } scoped_hook& operator=(emulator_hook* hook) { this->replace({hook}); return *this; } void replace(std::vector hooks) { if (!this->emu_) { throw std::runtime_error("Invalid scoped hook"); } this->remove(); this->hooks_ = std::move(hooks); } void remove() { auto hooks = std::move(this->hooks_); this->hooks_ = {}; for (auto* hook : hooks) { try { this->emu_->delete_hook(hook); } catch (...) { } } } private: emulator* emu_{}; std::vector hooks_{}; };