xbmc
RunningScriptsHandler.h
1 /*
2  * Copyright (C) 2017-2021 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "interfaces/generic/ScriptInvocationManager.h"
12 #include "interfaces/generic/ScriptRunner.h"
13 #include "threads/CriticalSection.h"
14 #include "threads/Event.h"
15 
16 #include <cstdint>
17 #include <map>
18 #include <mutex>
19 
20 template<class TScript>
22 {
23 protected:
24  using HandleType = int;
25 
26  CRunningScriptsHandler() = default;
27  virtual ~CRunningScriptsHandler() = default;
28 
29  using CScriptRunner::ExecuteScript;
30  using CScriptRunner::GetAddon;
31  using CScriptRunner::SetDone;
32  using CScriptRunner::StartScript;
33 
34  bool RunScript(TScript* script,
35  const ADDON::AddonPtr& addon,
36  const std::string& path,
37  bool resume)
38  {
39  if (script == nullptr || addon == nullptr || path.empty())
40  return false;
41 
42  // reuse an existing script handle or get a new one if necessary
43  int handle = CScriptInvocationManager::GetInstance().GetReusablePluginHandle(addon->LibPath());
44  if (handle < 0)
45  handle = GetNewScriptHandle(script);
46  else
47  ReuseScriptHandle(handle, script);
48 
49  // run the script
50  auto result = CScriptRunner::RunScript(addon, path, handle, resume);
51 
52  // remove the script handle if necessary
53  RemoveScriptHandle(handle);
54 
55  return result;
56  }
57 
58  static HandleType GetNewScriptHandle(TScript* script)
59  {
60  std::unique_lock<CCriticalSection> lock(s_critical);
61  uint32_t handle = ++s_scriptHandleCounter;
62  s_scriptHandles[handle] = script;
63 
64  return handle;
65  }
66 
67  static void ReuseScriptHandle(HandleType handle, TScript* script)
68  {
69  std::unique_lock<CCriticalSection> lock(s_critical);
70  s_scriptHandles[handle] = script;
71  }
72 
73  static void RemoveScriptHandle(HandleType handle)
74  {
75  std::unique_lock<CCriticalSection> lock(s_critical);
76  s_scriptHandles.erase(handle);
77  }
78 
79  static TScript* GetScriptFromHandle(HandleType handle)
80  {
81  std::unique_lock<CCriticalSection> lock(s_critical);
82  auto scriptHandle = s_scriptHandles.find(handle);
83  if (scriptHandle == s_scriptHandles.end())
84  return nullptr;
85 
86  return scriptHandle->second;
87  }
88 
89  static inline CCriticalSection& GetScriptsLock() { return s_critical; }
90 
91 private:
92  static std::map<HandleType, TScript*> s_scriptHandles;
93  static CCriticalSection s_critical;
94  static HandleType s_scriptHandleCounter;
95 };
96 
97 template<class TScript>
98 std::map<typename CRunningScriptsHandler<TScript>::HandleType, TScript*>
100 template<class TScript>
102 template<class TScript>
103 typename CRunningScriptsHandler<TScript>::HandleType
int GetReusablePluginHandle(const std::string &script)
Returns addon_handle if last reusable invoker is ready to use.
Definition: ScriptInvocationManager.cpp:178
Definition: RunningScriptsHandler.h:21
Definition: ScriptRunner.h:16