PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/xbmc/interfaces/python/swig.h

https://gitlab.com/sandihidayat/kodi
C Header | 212 lines | 96 code | 25 blank | 91 comment | 10 complexity | a193078b416d2e779bc8da4daf599335 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. #pragma once
  21. #include <Python.h>
  22. #include <string>
  23. #include <stdint.h>
  24. #include "interfaces/legacy/Exception.h"
  25. #include "interfaces/legacy/AddonClass.h"
  26. #include "interfaces/legacy/Window.h"
  27. #include "commons/typeindex.h"
  28. namespace PythonBindings
  29. {
  30. /**
  31. * This call will convert the python object passed to a string. The object
  32. * passed must be a python str or unicode object unless coerceToString is
  33. * true. If coerceToString is true then the type must be castable to a string
  34. * using the python call str(pObject).
  35. *
  36. * This method will handle a 'None' that's passed in. If 'None' is passed then
  37. * the resulting buf will contain the value of XBMCAddon::emptyString (which
  38. * is simply a std::string instantiated with the default constructor.
  39. */
  40. void PyXBMCGetUnicodeString(std::string& buf, PyObject* pObject, bool coerceToString = false,
  41. const char* pos = "unknown",
  42. const char* methodname = "unknown");
  43. struct TypeInfo
  44. {
  45. const char* swigType;
  46. TypeInfo* parentType;
  47. PyTypeObject pythonType;
  48. const XbmcCommons::type_index typeIndex;
  49. TypeInfo(const std::type_info& ti);
  50. };
  51. // This will hold the pointer to the api type, whether known or unknown
  52. struct PyHolder
  53. {
  54. PyObject_HEAD
  55. int32_t magicNumber;
  56. const TypeInfo* typeInfo;
  57. XBMCAddon::AddonClass* pSelf;
  58. };
  59. #define XBMC_PYTHON_TYPE_MAGIC_NUMBER 0x58626D63
  60. /**
  61. * This method retrieves the pointer from the PyHolder. The return value should
  62. * be cast to the appropriate type.
  63. *
  64. * Since the calls to this are generated there's no NULL pointer checks
  65. */
  66. inline XBMCAddon::AddonClass* retrieveApiInstance(PyObject* pythonObj, const TypeInfo* typeToCheck,
  67. const char* methodNameForErrorString,
  68. const char* typenameForErrorString)
  69. {
  70. if (pythonObj == NULL || pythonObj == Py_None)
  71. return NULL;
  72. if (((PyHolder*)pythonObj)->magicNumber != XBMC_PYTHON_TYPE_MAGIC_NUMBER || !PyObject_TypeCheck(pythonObj, (PyTypeObject*)(&(typeToCheck->pythonType))))
  73. throw XBMCAddon::WrongTypeException("Incorrect type passed to \"%s\", was expecting a \"%s\".",methodNameForErrorString,typenameForErrorString);
  74. return ((PyHolder*)pythonObj)->pSelf;
  75. }
  76. bool isParameterRightType(const char* passedType, const char* expectedType, const char* methodNamespacePrefix, bool tryReverse = true);
  77. XBMCAddon::AddonClass* doretrieveApiInstance(const PyHolder* pythonObj, const TypeInfo* typeInfo, const char* expectedType,
  78. const char* methodNamespacePrefix, const char* methodNameForErrorString);
  79. /**
  80. * This method retrieves the pointer from the PyHolder. The return value should
  81. * be cast to the appropriate type.
  82. *
  83. * Since the calls to this are generated there's no NULL pointer checks
  84. *
  85. * This method will return NULL if either the pythonObj is NULL or the
  86. * pythonObj is Py_None.
  87. */
  88. inline XBMCAddon::AddonClass* retrieveApiInstance(const PyObject* pythonObj, const char* expectedType, const char* methodNamespacePrefix,
  89. const char* methodNameForErrorString)
  90. {
  91. return (pythonObj == NULL || pythonObj == Py_None) ? NULL :
  92. doretrieveApiInstance(((PyHolder*)pythonObj),((PyHolder*)pythonObj)->typeInfo, expectedType, methodNamespacePrefix, methodNameForErrorString);
  93. }
  94. /**
  95. * This method is a helper for the generated API. It's called prior to any API
  96. * class constructor being returned from the generated code to Python
  97. */
  98. void prepareForReturn(XBMCAddon::AddonClass* c);
  99. /**
  100. * This method is a helper for the generated API. It's called prior to any API
  101. * class destructor being dealloc-ed from the generated code from Python
  102. */
  103. void cleanForDealloc(XBMCAddon::AddonClass* c);
  104. /**
  105. * This method is a helper for the generated API. It's called prior to any API
  106. * class destructor being dealloc-ed from the generated code from Python
  107. *
  108. * There is a Catch-22 in the destruction of a Window. 'dispose' needs to be
  109. * called on destruction but cannot be called from the destructor.
  110. * This overrides the default cleanForDealloc to resolve that.
  111. */
  112. void cleanForDealloc(XBMCAddon::xbmcgui::Window* c);
  113. /**
  114. * This method allows for conversion of the native api Type to the Python type.
  115. *
  116. * When this form of the call is used (and pythonType isn't NULL) then the
  117. * passed type is used in the instance. This is for classes that extend API
  118. * classes in python. The type passed may not be the same type that's stored
  119. * in the class metadata of the AddonClass of which 'api' is an instance,
  120. * it can be a subclass in python.
  121. *
  122. * if pythonType is NULL then the type is inferred using the class metadata
  123. * stored in the AddonClass instance 'api'.
  124. */
  125. PyObject* makePythonInstance(XBMCAddon::AddonClass* api, PyTypeObject* pythonType, bool incrementRefCount);
  126. /**
  127. * This method allows for conversion of the native api Type to the Python type.
  128. *
  129. * When this form of the call is used then the python type constructed will be the
  130. * type given by the class metadata in the AddonClass instance 'api'.
  131. *
  132. * This is just a helper inline to call the other makePythonInstance with NULL as
  133. * the pythonType.
  134. */
  135. inline PyObject* makePythonInstance(XBMCAddon::AddonClass* api, bool incrementRefCount)
  136. {
  137. return makePythonInstance(api,NULL,incrementRefCount);
  138. }
  139. void registerAddonClassTypeInformation(const TypeInfo* classInfo);
  140. const TypeInfo* getTypeInfoForInstance(XBMCAddon::AddonClass* obj);
  141. class Director
  142. {
  143. protected:
  144. PyObject* self;
  145. public:
  146. inline Director() : self(NULL) {}
  147. inline void setPyObjectForDirector(PyObject* pyargself) { self = pyargself; }
  148. };
  149. /**
  150. * This exception is thrown from Director calls that call into python when the
  151. * Python error is
  152. */
  153. class PythonToCppException : public XbmcCommons::UncheckedException
  154. {
  155. public:
  156. /**
  157. * Assuming a PyErr_Occurred, this will fill the exception message with all
  158. * of the appropriate information including the traceback if it can be
  159. * obtained. It will also clear the python message.
  160. */
  161. PythonToCppException();
  162. PythonToCppException(const std::string &exceptionType, const std::string &exceptionValue, const std::string &exceptionTraceback);
  163. static bool ParsePythonException(std::string &exceptionType, std::string &exceptionValue, std::string &exceptionTraceback);
  164. protected:
  165. void SetMessage(const std::string &exceptionType, const std::string &exceptionValue, const std::string &exceptionTraceback);
  166. };
  167. template<class T> struct PythonCompare
  168. {
  169. static inline int compare(PyObject* obj1, PyObject* obj2, const char* swigType, const char* methodNamespacePrefix, const char* methodNameForErrorString)
  170. {
  171. XBMC_TRACE;
  172. try
  173. {
  174. T* o1 = (T*)retrieveApiInstance(obj1, swigType, methodNamespacePrefix, methodNameForErrorString);
  175. T* o2 = (T*)retrieveApiInstance(obj2, swigType, methodNamespacePrefix, methodNameForErrorString);
  176. return ((*o1) < (*o2) ? -1 :
  177. ((*o1) > (*o2) ? 1 : 0));
  178. }
  179. catch (const XBMCAddon::WrongTypeException& e)
  180. {
  181. CLog::Log(LOGERROR,"EXCEPTION: %s",e.GetMessage());
  182. PyErr_SetString(PyExc_RuntimeError, e.GetMessage());
  183. }
  184. return -1;
  185. }
  186. };
  187. }