mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-28 09:14:58 +01:00
Add hook system
This commit is contained in:
99
src/openrct2/scripting/HookEngine.cpp
Normal file
99
src/openrct2/scripting/HookEngine.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2018 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <unordered_map>
|
||||
#include "HookEngine.h"
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
using namespace OpenRCT2::Scripting;
|
||||
|
||||
HOOK_TYPE OpenRCT2::Scripting::GetHookType(const std::string &name)
|
||||
{
|
||||
static const std::unordered_map<std::string, HOOK_TYPE> LookupTable({
|
||||
{ "interval.tick", HOOK_TYPE::INTERVAL_TICK },
|
||||
{ "interval.day", HOOK_TYPE::INTERVAL_DAY },
|
||||
});
|
||||
auto result = LookupTable.find(name);
|
||||
return (result != LookupTable.end()) ?
|
||||
result->second :
|
||||
HOOK_TYPE::UNDEFINED;
|
||||
}
|
||||
|
||||
HookEngine::HookEngine(ScriptExecutionInfo& execInfo) :
|
||||
_execInfo(execInfo)
|
||||
{
|
||||
_hookMap.resize(NUM_HOOK_TYPES);
|
||||
for (size_t i = 0; i < NUM_HOOK_TYPES; i++)
|
||||
{
|
||||
_hookMap[i].Type = static_cast<HOOK_TYPE>(i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 HookEngine::Subscribe(HOOK_TYPE type, Plugin& owner, const DukValue &function)
|
||||
{
|
||||
auto& hookList = GetHookList(type);
|
||||
auto cookie = _nextCookie++;
|
||||
Hook hook(cookie, owner, function);
|
||||
hookList.Hooks.push_back(hook);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
void HookEngine::Unsubscribe(HOOK_TYPE type, uint32 cookie)
|
||||
{
|
||||
auto& hookList = GetHookList(type);
|
||||
auto& hooks = hookList.Hooks;
|
||||
for (auto it = hooks.begin(); it != hooks.end(); it++)
|
||||
{
|
||||
if (it->Cookie == cookie)
|
||||
{
|
||||
hooks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HookEngine::UnsubscribeAll(const Plugin& owner)
|
||||
{
|
||||
for (auto& hookList : _hookMap)
|
||||
{
|
||||
auto& hooks = hookList.Hooks;
|
||||
for (auto it = hooks.begin(); it != hooks.end();)
|
||||
{
|
||||
if (it->Owner == &owner)
|
||||
{
|
||||
it = hooks.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HookEngine::Call(HOOK_TYPE type)
|
||||
{
|
||||
auto& hookList = GetHookList(type);
|
||||
for (auto& hook : hookList.Hooks)
|
||||
{
|
||||
_execInfo.SetCurrentPlugin(hook.Owner);
|
||||
|
||||
const auto& function = hook.Function;
|
||||
function.push();
|
||||
duk_pcall(function.context(), 0);
|
||||
duk_pop(function.context());
|
||||
}
|
||||
_execInfo.SetCurrentPlugin(nullptr);
|
||||
}
|
||||
|
||||
HookList& HookEngine::GetHookList(HOOK_TYPE type)
|
||||
{
|
||||
auto index = static_cast<size_t>(type);
|
||||
return _hookMap[index];
|
||||
}
|
||||
Reference in New Issue
Block a user