PageRenderTime 61ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/xbmc/interfaces/python/LanguageHook.cpp

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