PageRenderTime 32ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/xbmc/interfaces/python/LanguageHook.cpp

https://gitlab.com/nghia-n-v2007/xbmc
C++ | 193 lines | 122 code | 25 blank | 46 comment | 10 complexity | 9b9510875da67091e5dd3551454b5737 MD5 | raw file
  1. /*
  2. * Copyright (C) 2005-2013 Team XBMC
  3. * http://xbmc.org
  4. *
  5. * This Program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2, or (at your option)
  8. * any later version.
  9. *
  10. * This Program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with XBMC; see the file COPYING. If not, see
  17. * <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #include "LanguageHook.h"
  21. #include "CallbackHandler.h"
  22. #include "XBPython.h"
  23. #include "interfaces/legacy/AddonUtils.h"
  24. #include "PyContext.h"
  25. namespace XBMCAddon
  26. {
  27. namespace Python
  28. {
  29. static AddonClass::Ref<PythonLanguageHook> instance;
  30. static CCriticalSection hooksMutex;
  31. static std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> > hooks;
  32. // vtab instantiation
  33. PythonLanguageHook::~PythonLanguageHook()
  34. {
  35. XBMC_TRACE;
  36. XBMCAddon::LanguageHook::deallocating();
  37. }
  38. void PythonLanguageHook::MakePendingCalls()
  39. {
  40. XBMC_TRACE;
  41. PythonCallbackHandler::makePendingCalls();
  42. }
  43. void PythonLanguageHook::DelayedCallOpen()
  44. {
  45. XBMC_TRACE;
  46. PyGILLock::releaseGil();
  47. }
  48. void PythonLanguageHook::DelayedCallClose()
  49. {
  50. XBMC_TRACE;
  51. PyGILLock::acquireGil();
  52. }
  53. void PythonLanguageHook::RegisterMe()
  54. {
  55. XBMC_TRACE;
  56. CSingleLock lock(hooksMutex);
  57. hooks[m_interp] = AddonClass::Ref<PythonLanguageHook>(this);
  58. }
  59. void PythonLanguageHook::UnregisterMe()
  60. {
  61. XBMC_TRACE;
  62. CSingleLock lock(hooksMutex);
  63. hooks.erase(m_interp);
  64. }
  65. static AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook> g_languageHook;
  66. // Ok ... we're going to get it even if it doesn't exist. If it doesn't exist then
  67. // we're going to assume we're not in control of the interpreter. This (apparently)
  68. // can be the case. E.g. Libspotify manages to call into a script using a ctypes
  69. // extention but under the control of an Interpreter we know nothing about. In
  70. // cases like this we're going to use a global interpreter
  71. AddonClass::Ref<PythonLanguageHook> PythonLanguageHook::GetIfExists(PyInterpreterState* interp)
  72. {
  73. XBMC_TRACE;
  74. CSingleLock lock(hooksMutex);
  75. std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> >::iterator iter = hooks.find(interp);
  76. if (iter != hooks.end())
  77. return AddonClass::Ref<PythonLanguageHook>(iter->second);
  78. // if we got here then we need to use the global one.
  79. if (g_languageHook.isNull())
  80. g_languageHook = new XBMCAddon::Python::PythonLanguageHook();
  81. return g_languageHook;
  82. }
  83. bool PythonLanguageHook::IsAddonClassInstanceRegistered(AddonClass* obj)
  84. {
  85. for (std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> >::iterator iter = hooks.begin();
  86. iter != hooks.end(); ++iter)
  87. {
  88. if ((iter->second)->HasRegisteredAddonClassInstance(obj))
  89. return true;
  90. }
  91. return false;
  92. }
  93. /**
  94. * PythonCallbackHandler expects to be instantiated PER AddonClass instance
  95. * that is to be used as a callback. This is why this cannot be instantited
  96. * once.
  97. *
  98. * There is an expectation that this method is called from the Python thread
  99. * that instantiated an AddonClass that has the potential for a callback.
  100. *
  101. * See RetardedAsynchCallbackHandler for more details.
  102. * See PythonCallbackHandler for more details
  103. * See PythonCallbackHandler::PythonCallbackHandler for more details
  104. */
  105. XBMCAddon::CallbackHandler* PythonLanguageHook::GetCallbackHandler()
  106. {
  107. XBMC_TRACE;
  108. return new PythonCallbackHandler();
  109. }
  110. String PythonLanguageHook::GetAddonId()
  111. {
  112. XBMC_TRACE;
  113. // Get a reference to the main module
  114. // and global dictionary
  115. PyObject* main_module = PyImport_AddModule((char*)"__main__");
  116. PyObject* global_dict = PyModule_GetDict(main_module);
  117. // Extract a reference to the function "func_name"
  118. // from the global dictionary
  119. PyObject* pyid = PyDict_GetItemString(global_dict, "__xbmcaddonid__");
  120. if (pyid)
  121. return PyString_AsString(pyid);
  122. return "";
  123. }
  124. String PythonLanguageHook::GetAddonVersion()
  125. {
  126. XBMC_TRACE;
  127. // Get a reference to the main module
  128. // and global dictionary
  129. PyObject* main_module = PyImport_AddModule((char*)"__main__");
  130. PyObject* global_dict = PyModule_GetDict(main_module);
  131. // Extract a reference to the function "func_name"
  132. // from the global dictionary
  133. PyObject* pyversion = PyDict_GetItemString(global_dict, "__xbmcapiversion__");
  134. if (pyversion)
  135. return PyString_AsString(pyversion);
  136. return "";
  137. }
  138. void PythonLanguageHook::RegisterPlayerCallback(IPlayerCallback* player) { XBMC_TRACE; g_pythonParser.RegisterPythonPlayerCallBack(player); }
  139. void PythonLanguageHook::UnregisterPlayerCallback(IPlayerCallback* player) { XBMC_TRACE; g_pythonParser.UnregisterPythonPlayerCallBack(player); }
  140. void PythonLanguageHook::RegisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { XBMC_TRACE; g_pythonParser.RegisterPythonMonitorCallBack(monitor); }
  141. void PythonLanguageHook::UnregisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { XBMC_TRACE; g_pythonParser.UnregisterPythonMonitorCallBack(monitor); }
  142. bool PythonLanguageHook::WaitForEvent(CEvent& hEvent, unsigned int milliseconds)
  143. {
  144. XBMC_TRACE;
  145. return g_pythonParser.WaitForEvent(hEvent,milliseconds);
  146. }
  147. void PythonLanguageHook::RegisterAddonClassInstance(AddonClass* obj)
  148. {
  149. XBMC_TRACE;
  150. CSingleLock l(*this);
  151. obj->Acquire();
  152. currentObjects.insert(obj);
  153. }
  154. void PythonLanguageHook::UnregisterAddonClassInstance(AddonClass* obj)
  155. {
  156. XBMC_TRACE;
  157. CSingleLock l(*this);
  158. if (currentObjects.erase(obj) > 0)
  159. obj->Release();
  160. }
  161. bool PythonLanguageHook::HasRegisteredAddonClassInstance(AddonClass* obj)
  162. {
  163. XBMC_TRACE;
  164. CSingleLock l(*this);
  165. return currentObjects.find(obj) != currentObjects.end();
  166. }
  167. }
  168. }