/* * Copyright (C) 2017-2021 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #pragma once #include "interfaces/generic/ScriptInvocationManager.h" #include "interfaces/generic/ScriptRunner.h" #include "threads/CriticalSection.h" #include "threads/Event.h" #include #include #include template class CRunningScriptsHandler : protected CScriptRunner { protected: using HandleType = int; CRunningScriptsHandler() = default; virtual ~CRunningScriptsHandler() = default; using CScriptRunner::ExecuteScript; using CScriptRunner::GetAddon; using CScriptRunner::SetDone; using CScriptRunner::StartScript; bool RunScript(TScript* script, const ADDON::AddonPtr& addon, const std::string& path, bool resume) { if (script == nullptr || addon == nullptr || path.empty()) return false; // reuse an existing script handle or get a new one if necessary int handle = CScriptInvocationManager::GetInstance().GetReusablePluginHandle(addon->LibPath()); if (handle < 0) handle = GetNewScriptHandle(script); else ReuseScriptHandle(handle, script); // run the script auto result = CScriptRunner::RunScript(addon, path, handle, resume); // remove the script handle if necessary RemoveScriptHandle(handle); return result; } static HandleType GetNewScriptHandle(TScript* script) { std::unique_lock lock(s_critical); uint32_t handle = ++s_scriptHandleCounter; s_scriptHandles[handle] = script; return handle; } static void ReuseScriptHandle(HandleType handle, TScript* script) { std::unique_lock lock(s_critical); s_scriptHandles[handle] = script; } static void RemoveScriptHandle(HandleType handle) { std::unique_lock lock(s_critical); s_scriptHandles.erase(handle); } static TScript* GetScriptFromHandle(HandleType handle) { std::unique_lock lock(s_critical); auto scriptHandle = s_scriptHandles.find(handle); if (scriptHandle == s_scriptHandles.end()) return nullptr; return scriptHandle->second; } static inline CCriticalSection& GetScriptsLock() { return s_critical; } private: static std::map s_scriptHandles; static CCriticalSection s_critical; static HandleType s_scriptHandleCounter; }; template std::map::HandleType, TScript*> CRunningScriptsHandler::s_scriptHandles; template CCriticalSection CRunningScriptsHandler::s_critical; template typename CRunningScriptsHandler::HandleType CRunningScriptsHandler::s_scriptHandleCounter = 0;