2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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
26 #include "utils/StdString.h"
27 #include "interfaces/legacy/Exception.h"
28 #include "interfaces/legacy/AddonClass.h"
29 #include "interfaces/legacy/Window.h"
31 namespace PythonBindings
33 void PyXBMCGetUnicodeString(std::string& buf, PyObject* pObject, bool coerceToString = false,
34 const char* pos = "unknown",
35 const char* methodname = "unknown") throw (XBMCAddon::WrongTypeException);
37 // This is for casting from child class to base class
38 struct TypeConverterBase
40 virtual void* convert(void* from) = 0;
44 * Template to allow the instantiation of a particular type conversion
46 template<class T, class F> struct TypeConverter : public TypeConverterBase
48 inline virtual void* convert(void* from) { return static_cast<T*>((F*)from); }
55 TypeConverterBase* converter;
58 // This will hold the pointer to the api type, whether known or unknown
63 const TypeInfo* typeInfo;
67 #define XBMC_PYTHON_TYPE_MAGIC_NUMBER 0x58626D63
69 void PyXBMCInitializeTypeObject(PyTypeObject* type_object, TypeInfo* typeInfo);
72 * This method retrieves the pointer from the PyHolder. The return value should
73 * be case to the appropriate type.
75 * Since the calls to this are generated there's no NULL pointer checks
77 inline void* retrieveApiInstance(PyObject* pythonType, PyTypeObject* typeToCheck,
78 const char* methodNameForErrorString,
79 const char* typenameForErrorString) throw (XBMCAddon::WrongTypeException)
81 if (pythonType == NULL || ((PyHolder*)pythonType)->magicNumber != XBMC_PYTHON_TYPE_MAGIC_NUMBER)
83 if (!PyObject_TypeCheck(pythonType, typeToCheck))
84 throw XBMCAddon::WrongTypeException("Incorrect type passed to \"%s\", was expecting a \"%s\".",methodNameForErrorString,typenameForErrorString);
85 return ((PyHolder*)pythonType)->pSelf;
88 bool isParameterRightType(const char* passedType, const char* expectedType, const char* methodNamespacePrefix, bool tryReverse = true);
90 void* doretrieveApiInstance(const PyHolder* pythonType, const TypeInfo* typeInfo, const char* expectedType,
91 const char* methodNamespacePrefix, const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException);
94 * This method retrieves the pointer from the PyHolder. The return value should
95 * be case to the appropriate type.
97 * Since the calls to this are generated there's no NULL pointer checks
99 inline void* retrieveApiInstance(const PyObject* pythonType, const char* expectedType, const char* methodNamespacePrefix,
100 const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException)
102 return (pythonType == NULL) ? NULL :
103 doretrieveApiInstance(((PyHolder*)pythonType),((PyHolder*)pythonType)->typeInfo, expectedType, methodNamespacePrefix, methodNameForErrorString);
107 * This method is a helper for the generated API. It's called prior to any API
108 * class constructor being returned from the generated code to Python
110 void prepareForReturn(XBMCAddon::AddonClass* c);
113 * This method is a helper for the generated API. It's called prior to any API
114 * class destructor being dealloc-ed from the generated code from Python
116 void cleanForDealloc(XBMCAddon::AddonClass* c);
119 * This method is a helper for the generated API. It's called prior to any API
120 * class destructor being dealloc-ed from the generated code from Python
122 * There is a Catch-22 in the destruction of a Window. 'dispose' needs to be
123 * called on destruction but cannot be called from the destructor.
124 * This overrides the default cleanForDealloc to resolve that.
126 void cleanForDealloc(XBMCAddon::xbmcgui::Window* c);
129 * This method allows for conversion of the native api Type to the Python type
131 * NOTE: swigTypeString must be in the data segment. That is, it should be an explicit string since
132 * the const char* is stored in a PyHolder struct and never deleted.
134 PyObject* makePythonInstance(void* api, PyTypeObject* typeObj, TypeInfo* typeInfo, bool incrementRefCount);
141 inline Director() : self(NULL) {}
142 inline void setPyObjectForDirector(PyObject* pyargself) { self = pyargself; }
146 * This exception is thrown from Director calls that call into python when the
149 class PythonToCppException : public XbmcCommons::UncheckedException
153 * Assuming a PyErr_Occurred, this will fill the exception message with all
154 * of the appropriate information including the traceback if it can be
155 * obtained. It will also clear the python message.
157 PythonToCppException();
160 template<class T> struct PythonCompare
162 static inline int compare(PyObject* obj1, PyObject* obj2, const char* swigType, const char* methodNamespacePrefix, const char* methodNameForErrorString)
163 throw(XBMCAddon::WrongTypeException)
168 T* o1 = (T*)retrieveApiInstance(obj1, swigType, methodNamespacePrefix, methodNameForErrorString);
169 T* o2 = (T*)retrieveApiInstance(obj2, swigType, methodNamespacePrefix, methodNameForErrorString);
171 return ((*o1) < (*o2) ? -1 :
172 ((*o1) > (*o2) ? 1 : 0));
174 catch (const XBMCAddon::WrongTypeException& e)
176 CLog::Log(LOGERROR,"EXCEPTION: %s",e.GetMessage());
177 PyErr_SetString(PyExc_RuntimeError, e.GetMessage());