klepto2 Posted November 4, 2023 Share Posted November 4, 2023 while developing the PBR Texture generator I have found some flaw with the current hook system. It is somewhat inflexible. Soi tried to add my own Hook Manager: enum class HookState { IDLE, PENDING, RUNNING, FINISHED, }; class HookManager; class Hook : public Object { friend class HookManager; private: void* _function; shared_ptr<Object> _extra; HookState _currentState; bool _stopping = false; bool _repeating = false; shared_ptr<HookManager> _manager; public: Hook(shared_ptr<HookManager> manager, void callback(const UltraEngine::Render::VkRenderer&, shared_ptr<Object>), shared_ptr<Object> extra, bool repeat = false) { _function = callback; _extra = extra; _currentState = HookState::IDLE; _repeating = repeat; _manager = manager; } void Start() { _currentState = HookState::PENDING; } void Stop() { _stopping = true; } HookState GetState() { return _currentState; } void SetExtra(shared_ptr<Object> extra) { _extra = extra; } }; class HookManager : public Object { friend class Hook; private: static void UpdateDispatch(const UltraEngine::Render::VkRenderer& renderer, shared_ptr<Object> extra) { auto hookManager = extra->As<HookManager>(); if (hookManager != NULL) { for (auto hook : hookManager->_hooks) { if (hook->_stopping) { hook->_currentState = HookState::IDLE; hook->_stopping = false; } if (hook->GetState() != HookState::FINISHED) { if (hook->GetState() == HookState::PENDING) { hook->_currentState = HookState::RUNNING; auto f = (void(*)(const UltraEngine::Render::VkRenderer&, shared_ptr<Object>))hook->_function; f(renderer, hook->_extra); } else if (hook->GetState() == HookState::RUNNING) { if (!hook->_repeating) { hook->_currentState = HookState::FINISHED; } else { hook->_currentState = HookState::PENDING; } } } } } } inline static map<HookID,map<shared_ptr<World>, shared_ptr<HookManager>>> _mapWorldHookManager; vector<shared_ptr<Hook>> _hooks; shared_ptr<World> _world; HookID _hookId; public: static shared_ptr<HookManager> Get(shared_ptr<World> world, HookID hookId) { if (_mapWorldHookManager.size() == 0) { _mapWorldHookManager[HOOKID_RENDER] = {}; _mapWorldHookManager[HOOKID_TRANSFER] = {}; } if (HookManager::_mapWorldHookManager[hookId][world] == NULL) { auto mgr = std::make_shared<HookManager>(world, hookId); mgr->StartDispatching(); HookManager::_mapWorldHookManager[hookId][world] = mgr; } return HookManager::_mapWorldHookManager[hookId][world]; } void StartDispatching() { _world->AddHook(HookID::HOOKID_TRANSFER, HookManager::UpdateDispatch, Self(), true); } void Start(shared_ptr<Hook> hook) { auto position = std::find(_hooks.begin(), _hooks.end(), hook); if (position != _hooks.end()) { hook->Start(); } } void Stop(shared_ptr<Hook> hook) { auto position = std::find(_hooks.begin(), _hooks.end(), hook); if (position != _hooks.end()) { hook->Stop(); } } HookManager(shared_ptr<World> world, HookID hookId) { _world = world; _hookId = hookId; } shared_ptr<Hook> AddHook(void callback(const UltraEngine::Render::VkRenderer&, shared_ptr<Object>), shared_ptr<Object> extra , bool repeat = false) { auto hook = std::make_shared<Hook>(Self()->As<HookManager>(), callback, extra, repeat); _hooks.push_back(hook); return hook; } void RemoveHook(shared_ptr<Hook> hook) { auto position = std::find(_hooks.begin(), _hooks.end(), hook); if (position != _hooks.end()) _hooks.erase(position); } }; It allows to dispatch, Start/Stop hooks like a thread and also adds the ability check the state of a hook. static void checkCallback(const UltraEngine::Render::VkRenderer&, shared_ptr<Object>) { } auto hookManager = HookManager::Get(_world, HOOKID_TRANSFER); auto checkHook = _hookManager->AddHook(checkCallback, _world, false); hookManager->Start(checkHook); while(checkHook->GetState() != HookState::Finished) { world->Update(); world->Render(); } This makes it a bit easier to watch the Hook execution. I use it in my PBRTextureGen and in my current state of Computeshader Implementation. It makes it much easier to manage the hooks. It might stll have a few bugs in it as i haven't fully tested every usecase, but for the basics it works Quote Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.