diff options
author | Jim Carroll <thecarrolls@jiminger.com> | 2013-10-21 06:45:14 -0700 |
---|---|---|
committer | Jim Carroll <thecarrolls@jiminger.com> | 2013-10-21 06:45:14 -0700 |
commit | 1ae84d9dc57c1a71bfba41e4beada588b996424b (patch) | |
tree | 0541deaf068c8293661c7f580a0c2ae1b6d52204 | |
parent | 96410e2d0148f901c1b7d34f6f14c5458878b70c (diff) | |
parent | 395e4cd618d13702c4cf5fc371e9d48156bdcaaf (diff) |
Merge pull request #3463 from jimfcarroll/cleanup-control
Cleanup XBMCAddon::xbmcgui::Control class and related docs
57 files changed, 768 insertions, 908 deletions
diff --git a/codegenerator.mk b/codegenerator.mk index 7eddb3817a..9615aa3f80 100644 --- a/codegenerator.mk +++ b/codegenerator.mk @@ -32,7 +32,7 @@ GENERATE_DEPS += $(TOPDIR)/xbmc/interfaces/legacy/*.h $(TOPDIR)/xbmc/interfaces/ vpath %.i $(INTERFACES_DIR)/swig $(GENDIR)/%.cpp: $(GENDIR)/%.xml $(JAVA) $(SWIG) $(DOXY_XML_PATH) - $(JAVA) -cp "$(GROOVY_DIR)/groovy-all-1.8.9.jar:$(GROOVY_DIR)/commons-lang-2.6.jar:$(TOPDIR)/tools/codegenerator:$(INTERFACES_DIR)/python" \ + $(JAVA) -cp "$(GROOVY_DIR)/groovy-all-2.1.7.jar:$(GROOVY_DIR)/commons-lang-2.6.jar:$(TOPDIR)/tools/codegenerator:$(INTERFACES_DIR)/python" \ groovy.ui.GroovyMain $(TOPDIR)/tools/codegenerator/Generator.groovy $< $(INTERFACES_DIR)/python/PythonSwig.cpp.template $@ $(DOXY_XML_PATH) rm $< diff --git a/lib/groovy/groovy-all-1.8.9.jar b/lib/groovy/groovy-all-2.1.7.jar Binary files differindex 0052e2b056..e24f300562 100644 --- a/lib/groovy/groovy-all-1.8.9.jar +++ b/lib/groovy/groovy-all-2.1.7.jar diff --git a/tools/codegenerator/GenerateSWIGBindings.bat b/tools/codegenerator/GenerateSWIGBindings.bat index 73d4519824..822b0ca0f6 100644 --- a/tools/codegenerator/GenerateSWIGBindings.bat +++ b/tools/codegenerator/GenerateSWIGBindings.bat @@ -27,7 +27,7 @@ rem run doxygen rem run swig to generate the XML used by groovy to generate the python bindings "%bin_dir%\swig\swig.exe" -w401 -c++ -outdir "%python_generated_dir%" -o "%python_generated_dir%\%2.xml" -xml -I"%base_Dir%\xbmc" -xmllang python "%swig_dir%\%2.i" rem run groovy to generate the python bindings -java.exe -cp "%groovy_dir%\groovy-all-1.8.9.jar;%groovy_dir%\commons-lang-2.6.jar;%generator_dir%;%python_dir%" groovy.ui.GroovyMain "%generator_dir%\Generator.groovy" "%python_generated_dir%\%2.xml" "%python_dir%\PythonSwig.cpp.template" "%python_generated_dir%\%2.cpp" "%doxygen_dir%" +java.exe -cp "%groovy_dir%\groovy-all-2.1.7.jar;%groovy_dir%\commons-lang-2.6.jar;%generator_dir%;%python_dir%" groovy.ui.GroovyMain "%generator_dir%\Generator.groovy" "%python_generated_dir%\%2.xml" "%python_dir%\PythonSwig.cpp.template" "%python_generated_dir%\%2.cpp" "%doxygen_dir%" rem delete the XML file generated by SWIG as it's not needed anymore del "%python_generated_dir%\%2.xml" > NUL diff --git a/tools/codegenerator/SwigTypeParser.groovy b/tools/codegenerator/SwigTypeParser.groovy index cb04277cd3..c7efb3f7d2 100644 --- a/tools/codegenerator/SwigTypeParser.groovy +++ b/tools/codegenerator/SwigTypeParser.groovy @@ -33,6 +33,10 @@ public class SwigTypeParser */ private static Map typeTable = [:] + /** + * Add a typedef node to the global list of typedefs to be used later in + * parsing types. + */ public static void appendTypeTable(Node typetab) { typetab.each { typeTable[it.@namespace + it.@type] = it.@basetype } } /** @@ -128,25 +132,56 @@ public class SwigTypeParser return result.replaceAll('<\\(', '<').replaceAll('\\)>', '>') } + /** + * This will resolve the typedefs given the parameter passed is a simple type. + * see SwigType_resolve_all_typedefs which will handle qualifiers, pointers, + * references, and typedef of typedefs to resolve all the way down to the + * most basic types. + */ public static String SwigType_typedef_resolve(String t) { String td = typeTable[t] String ret = td == null ? t : td -// System.out.println "trying to resolve ${t} and it appears to be typedefed to ${ret}" return ret } - public static String SwigType_typedef_resolve_all(String t) - { - String prev = t - t = SwigType_typedef_resolve(prev) - while(prev != t) - { - String tmp = t - t = SwigType_typedef_resolve(prev) - prev = tmp + /** + * This will resolve typedefs anbd handle qualifiers, pointers, + * references, and typedef of typedefs to resolve all the way down to the + * most basic types. + */ + public static String SwigType_resolve_all_typedefs(String s) + { + String result = '' + String tc = s + + /* Nuke all leading qualifiers, appending them to the result*/ + while (SwigType_isqualifier(tc)) { + List tmpl = SwigType_pop(tc) + tc = tmpl[1] + result += tmpl[0] + } + + if (SwigType_issimple(tc)) { + /* Resolve any typedef definitions */ + String tt = tc + String td + while ((td = SwigType_typedef_resolve(tt)) != tt) { + if (td != tt) { + tt = td + break + } + else if (td != tt) tt = td + } + tc = td + + return tc } - return t + + List tmpl = SwigType_pop(tc) + result += tmpl[0] + result += SwigType_resolve_all_typedefs(tmpl[1]) + return result } /** @@ -205,7 +240,7 @@ public class SwigTypeParser firstarray = false } else if (SwigType_isreference(element)) { if (notypeconv) { - result == element + result += element } else { result += "p." } @@ -216,7 +251,7 @@ public class SwigTypeParser } else { result += "p." } - firstarray = 0; + firstarray = false; } else if (SwigType_isenum(element)) { boolean anonymous_enum = (element == "enum ") if (notypeconv || !anonymous_enum) { diff --git a/xbmc/commons/typeindex.h b/xbmc/commons/typeindex.h new file mode 100644 index 0000000000..66fc0bf17c --- /dev/null +++ b/xbmc/commons/typeindex.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <typeinfo> + +/** + * This struct represents a pre-introduction of the std::type_index for RTTI + * which will only availalbe in C++11. + */ + +namespace XbmcCommons +{ + /** + @brief The class type_index provides a simple wrapper for type_info + which can be used as an index type in associative containers (23.6) + and in unordered associative containers (23.7). + */ + struct type_index + { + inline type_index(const std::type_info& __rhs) + : _M_target(&__rhs) { } + + inline bool + operator==(const type_index& __rhs) const + { return *_M_target == *__rhs._M_target; } + + inline bool + operator!=(const type_index& __rhs) const + { return *_M_target != *__rhs._M_target; } + + inline bool + operator<(const type_index& __rhs) const + { return _M_target->before(*__rhs._M_target); } + + inline bool + operator<=(const type_index& __rhs) const + { return !__rhs._M_target->before(*_M_target); } + + inline bool + operator>(const type_index& __rhs) const + { return __rhs._M_target->before(*_M_target); } + + inline bool + operator>=(const type_index& __rhs) const + { return !_M_target->before(*__rhs._M_target); } + + inline const char* + name() const + { return _M_target->name(); } + + private: + const std::type_info* _M_target; + }; + + template<typename _Tp> struct hash; +} diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h index 28596cfc05..c4697955ca 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.h +++ b/xbmc/cores/VideoRenderers/RenderManager.h @@ -30,6 +30,7 @@ #include "settings/VideoSettings.h" #include "OverlayRenderer.h" #include <deque> +#include "PlatformDefs.h" class CRenderCapture; diff --git a/xbmc/interfaces/legacy/Addon.cpp b/xbmc/interfaces/legacy/Addon.cpp index c9b247dff2..bfc51d20a2 100644 --- a/xbmc/interfaces/legacy/Addon.cpp +++ b/xbmc/interfaces/legacy/Addon.cpp @@ -36,7 +36,7 @@ namespace XBMCAddon String Addon::getAddonVersion() { return languageHook == NULL ? emptyString : languageHook->GetAddonVersion(); } - Addon::Addon(const char* cid) throw (AddonException) : AddonClass("Addon") + Addon::Addon(const char* cid) throw (AddonException) { String id(cid ? cid : emptyString); diff --git a/xbmc/interfaces/legacy/Addon.h b/xbmc/interfaces/legacy/Addon.h index 1f94309594..c35277ce8b 100644 --- a/xbmc/interfaces/legacy/Addon.h +++ b/xbmc/interfaces/legacy/Addon.h @@ -129,7 +129,6 @@ namespace XBMCAddon * - version = self.Addon.getAddonInfo('version') */ String getAddonInfo(const char* id) throw (AddonException); - }; } } diff --git a/xbmc/interfaces/legacy/AddonCallback.h b/xbmc/interfaces/legacy/AddonCallback.h index 049995a114..8f55467ad5 100644 --- a/xbmc/interfaces/legacy/AddonCallback.h +++ b/xbmc/interfaces/legacy/AddonCallback.h @@ -39,16 +39,17 @@ namespace XBMCAddon bool hasHandler() { return handler.isNotNull(); } - public: - inline AddonCallback(const char* classname) : AddonClass(classname), handler(NULL) + inline AddonCallback() : handler(NULL) { // if there is a LanguageHook, it should be set already. if (languageHook != NULL) setHandler(languageHook->GetCallbackHandler()); } + public: + virtual ~AddonCallback(); - void setHandler(CallbackHandler* _handler) { handler = _handler; } + inline void setHandler(CallbackHandler* _handler) { handler = _handler; } void invokeCallback(Callback* callback); }; } diff --git a/xbmc/interfaces/legacy/AddonClass.cpp b/xbmc/interfaces/legacy/AddonClass.cpp index 80fd96b46e..a4a9d0ca35 100644 --- a/xbmc/interfaces/legacy/AddonClass.cpp +++ b/xbmc/interfaces/legacy/AddonClass.cpp @@ -37,24 +37,14 @@ namespace XBMCAddon if (languageHook != NULL) languageHook->Release(); -#ifdef ENABLE_TRACE_API - TraceGuard tg_; - CLog::Log(LOGDEBUG, "%sNEWADDON destroying %s 0x%lx", tg_.getSpaces(), classname.c_str(), (long)(((void*)this))); -#endif - #ifdef XBMC_ADDON_DEBUG_MEMORY isDeleted = false; #endif } - AddonClass::AddonClass(const char* cname) : refs(0L), classname(cname), m_isDeallocating(false), - languageHook(NULL) + AddonClass::AddonClass() : refs(0L), m_isDeallocating(false), + languageHook(NULL) { -#ifdef ENABLE_TRACE_API - TraceGuard tg_; - CLog::Log(LOGDEBUG, "%sNEWADDON constructing %s 0x%lx", tg_.getSpaces(), classname.c_str(), (long)(((void*)this))); -#endif - #ifdef XBMC_ADDON_DEBUG_MEMORY isDeleted = false; #endif @@ -78,11 +68,11 @@ namespace XBMCAddon { if (isDeleted) CLog::Log(LOGERROR,"NEWADDON REFCNT Releasing dead class %s 0x%lx", - classname.c_str(), (long)(((void*)this))); + GetClassname(), (long)(((void*)this))); long ct = AtomicDecrement((long*)&refs); #ifdef LOG_LIFECYCLE_EVENTS - CLog::Log(LOGDEBUG,"NEWADDON REFCNT decrementing to %ld on %s 0x%lx", ct,classname.c_str(), (long)(((void*)this))); + CLog::Log(LOGDEBUG,"NEWADDON REFCNT decrementing to %ld on %s 0x%lx", GetClassname(), (long)(((void*)this))); #endif if(ct == 0) { @@ -96,16 +86,15 @@ namespace XBMCAddon { if (isDeleted) CLog::Log(LOGERROR,"NEWADDON REFCNT Acquiring dead class %s 0x%lx", - classname.c_str(), (long)(((void*)this))); + GetClassname(), (long)(((void*)this))); #ifdef LOG_LIFECYCLE_EVENTS CLog::Log(LOGDEBUG,"NEWADDON REFCNT incrementing to %ld on %s 0x%lx", - AtomicIncrement((long*)&refs),classname.c_str(), (long)(((void*)this))); + AtomicIncrement((long*)&refs),GetClassname(), (long)(((void*)this))); #else AtomicIncrement((long*)&refs); #endif } - #endif } diff --git a/xbmc/interfaces/legacy/AddonClass.h b/xbmc/interfaces/legacy/AddonClass.h index 3e893c2744..d5ced32637 100644 --- a/xbmc/interfaces/legacy/AddonClass.h +++ b/xbmc/interfaces/legacy/AddonClass.h @@ -62,22 +62,19 @@ namespace XBMCAddon * If a scripting language bindings require specific handling there is a * hook to add in these language specifics that can be set here. */ - class AddonClass + class AddonClass : public CCriticalSection { private: long refs; - String classname; - CCriticalSection thisLock; bool m_isDeallocating; + // no copying inline AddonClass(const AddonClass&); - #ifdef XBMC_ADDON_DEBUG_MEMORY bool isDeleted; #endif - friend class Synchronize; protected: LanguageHook* languageHook; @@ -92,15 +89,21 @@ namespace XBMCAddon */ virtual void deallocating() { - Synchronize lock(*this); + CSingleLock lock(*this); m_isDeallocating = true; } + /** + * This is meant to be called during static initialization and so isn't + * synchronized. + */ + static short getNextClassIndex(); + public: - AddonClass(const char* classname); + AddonClass(); virtual ~AddonClass(); - inline const String& GetClassname() const { return classname; } + inline const char* GetClassname() const { return typeid(*this).name(); } inline LanguageHook* GetLanguageHook() { return languageHook; } /** @@ -110,6 +113,8 @@ namespace XBMCAddon */ bool isDeallocating() { TRACE; return m_isDeallocating; } + static short getNumAddonClasses(); + #ifdef XBMC_ADDON_DEBUG_MEMORY virtual #else @@ -120,7 +125,7 @@ namespace XBMCAddon { long ct = AtomicDecrement((long*)&refs); #ifdef LOG_LIFECYCLE_EVENTS - CLog::Log(LOGDEBUG,"NEWADDON REFCNT decrementing to %ld on %s 0x%lx", ct,classname.c_str(), (long)(((void*)this))); + CLog::Log(LOGDEBUG,"NEWADDON REFCNT decrementing to %ld on %s 0x%lx", ct,GetClassname(), (long)(((void*)this))); #endif if(ct == 0) delete this; @@ -140,7 +145,7 @@ namespace XBMCAddon { #ifdef LOG_LIFECYCLE_EVENTS CLog::Log(LOGDEBUG,"NEWADDON REFCNT incrementing to %ld on %s 0x%lx", - AtomicIncrement((long*)&refs),classname.c_str(), (long)(((void*)this))); + AtomicIncrement((long*)&refs),GetClassname(), (long)(((void*)this))); #else AtomicIncrement((long*)&refs); #endif @@ -207,21 +212,5 @@ namespace XBMCAddon inline void reset() { refcheck; if (ac) ac->Release(); ac = NULL; } }; - /** - * This class can be used like a "synchronize" block in java as long - * as the object is an AddonClass. It can be used to synchronize on - * 'this' effectively creating the effect of a synchronize keyword - * on a method declaration. - * - * Keep in mind that this DOES NOT use 'monitor' semantics, but - * uses MUTEX semantics. That means that using this class, a thread - * can deadlock itself, while in java a synchronize keyword won't. - */ - class Synchronize : public CSingleLock - { - public: - inline Synchronize(const AddonClass& obj) : CSingleLock(obj.thisLock) {} - }; - }; } diff --git a/xbmc/interfaces/legacy/Alternative.h b/xbmc/interfaces/legacy/Alternative.h index 96c641c8af..8677b0f4a7 100644 --- a/xbmc/interfaces/legacy/Alternative.h +++ b/xbmc/interfaces/legacy/Alternative.h @@ -45,7 +45,7 @@ namespace XBMCAddon new(data) T2(o.later()); } - inline WhichAlternative which() { return pos; } + inline WhichAlternative which() const { return pos; } inline T1& former() throw (WrongTypeException) { @@ -89,6 +89,9 @@ namespace XBMCAddon inline operator const T1& () const throw (WrongTypeException) { return former(); } inline operator T2& () throw (WrongTypeException) { return later(); } inline operator const T2& () const throw (WrongTypeException) { return later(); } + + static inline Alternative<T1,T2>& nullItem() { return *(Alternative<T1,T2>*)NULL; } + static inline bool isNullReference(const Alternative<T1,T2>& ref) { return (&ref) == NULL; } }; } diff --git a/xbmc/interfaces/legacy/CallbackFunction.cpp b/xbmc/interfaces/legacy/CallbackFunction.cpp index 3408b6b4a7..55486db8ea 100644 --- a/xbmc/interfaces/legacy/CallbackFunction.cpp +++ b/xbmc/interfaces/legacy/CallbackFunction.cpp @@ -22,9 +22,5 @@ namespace XBMCAddon { - Callback::~Callback() - { - deallocating(); - } - + Callback::~Callback() { deallocating(); } } diff --git a/xbmc/interfaces/legacy/CallbackFunction.h b/xbmc/interfaces/legacy/CallbackFunction.h index 4304b420e2..65a8489aca 100644 --- a/xbmc/interfaces/legacy/CallbackFunction.h +++ b/xbmc/interfaces/legacy/CallbackFunction.h @@ -38,7 +38,7 @@ namespace XBMCAddon { protected: AddonClass* addonClassObject; - Callback(AddonClass* _object, const char* classname) : AddonClass(classname), addonClassObject(_object) {} + Callback(AddonClass* _object) : addonClassObject(_object) {} public: virtual void executeCallback() = 0; @@ -70,7 +70,7 @@ namespace XBMCAddon public: CallbackFunction(M* object, MemberFunction method) : - Callback(object, "CallbackFunction<M>"), meth(method), obj(object) {} + Callback(object), meth(method), obj(object) {} virtual ~CallbackFunction() { deallocating(); } @@ -93,7 +93,7 @@ namespace XBMCAddon public: CallbackFunction(M* object, MemberFunction method, P1 parameter) : - Callback(object, "CallbackFunction<M,P1>"), meth(method), obj(object), + Callback(object), meth(method), obj(object), param(parameter) {} virtual ~CallbackFunction() { deallocating(); } @@ -118,7 +118,7 @@ namespace XBMCAddon public: CallbackFunction(M* object, MemberFunction method, P1* parameter) : - Callback(object, "CallbackFunction<M,P1>"), meth(method), obj(object), + Callback(object), meth(method), obj(object), param(parameter) {} virtual ~CallbackFunction() { deallocating(); } @@ -144,7 +144,7 @@ namespace XBMCAddon public: CallbackFunction(M* object, MemberFunction method, P1 parameter, P2 parameter2) : - Callback(object, "CallbackFunction<M,P1,P2>"), meth(method), obj(object), + Callback(object), meth(method), obj(object), param1(parameter), param2(parameter2) {} virtual ~CallbackFunction() { deallocating(); } @@ -171,15 +171,13 @@ namespace XBMCAddon public: CallbackFunction(M* object, MemberFunction method, P1 parameter, P2 parameter2, P3 parameter3) : - Callback(object, "CallbackFunction<M,P1,P2,P3>"), meth(method), obj(object), + Callback(object), meth(method), obj(object), param1(parameter), param2(parameter2), param3(parameter3) {} virtual ~CallbackFunction() { deallocating(); } virtual void executeCallback() { TRACE; ((*obj).*(meth))(param1,param2,param3); } }; - - } diff --git a/xbmc/interfaces/legacy/CallbackHandler.cpp b/xbmc/interfaces/legacy/CallbackHandler.cpp index 69b1047a82..19a4a888aa 100644 --- a/xbmc/interfaces/legacy/CallbackHandler.cpp +++ b/xbmc/interfaces/legacy/CallbackHandler.cpp @@ -32,7 +32,7 @@ namespace XBMCAddon AddonClass::Ref<Callback> cb; RetardedAsynchCallbackHandler* handler; AsynchCallbackMessage(Callback* _cb, RetardedAsynchCallbackHandler* _handler) : - AddonClass("AsynchCallbackMessage"), cb(_cb), handler(_handler) { TRACE; } + cb(_cb), handler(_handler) { TRACE; } }; //******************************************************************** @@ -103,7 +103,7 @@ namespace XBMCAddon #ifdef ENABLE_TRACE_API CLog::Log(LOGDEBUG,"%sNEWADDON executing callback 0x%lx",_tg.getSpaces(),(long)(p->cb.get())); #endif - Synchronize lock2(*(p->cb->getObject())); + CSingleLock lock2(*(p->cb->getObject())); if (!p->cb->getObject()->isDeallocating()) { try diff --git a/xbmc/interfaces/legacy/CallbackHandler.h b/xbmc/interfaces/legacy/CallbackHandler.h index db5ea038a2..4199b34d87 100644 --- a/xbmc/interfaces/legacy/CallbackHandler.h +++ b/xbmc/interfaces/legacy/CallbackHandler.h @@ -33,7 +33,7 @@ namespace XBMCAddon class CallbackHandler : public AddonClass { protected: - inline CallbackHandler(const char* classname):AddonClass(classname) {} + inline CallbackHandler() {} public: virtual void invokeCallback(Callback* cb) = 0; @@ -54,7 +54,7 @@ namespace XBMCAddon class RetardedAsynchCallbackHandler : public CallbackHandler { protected: - RetardedAsynchCallbackHandler(const char* classname) : CallbackHandler(classname) {} + inline RetardedAsynchCallbackHandler() {} public: virtual ~RetardedAsynchCallbackHandler(); diff --git a/xbmc/interfaces/legacy/Control.cpp b/xbmc/interfaces/legacy/Control.cpp index a4eea05182..e921434dbf 100644 --- a/xbmc/interfaces/legacy/Control.cpp +++ b/xbmc/interfaces/legacy/Control.cpp @@ -54,7 +54,6 @@ namespace XBMCAddon ControlFadeLabel::ControlFadeLabel(long x, long y, long width, long height, const char* font, const char* _textColor, long _alignment) : - Control("ControlFadeLabel"), strFont("font13"), textColor(0xffffffff), align(_alignment) { dwPosX = x; @@ -117,7 +116,6 @@ namespace XBMCAddon // ============================================================ ControlTextBox::ControlTextBox(long x, long y, long width, long height, const char* font, const char* _textColor) : - Control("ControlTextBox"), strFont("font13"), textColor(0xffffffff) { dwPosX = x; @@ -182,7 +180,7 @@ namespace XBMCAddon long alignment, const char* font, const char* _textColor, const char* _disabledColor, long angle, const char* _shadowColor, const char* _focusedColor) : - Control("ControlButton"), textOffsetX(_textOffsetX), textOffsetY(_textOffsetY), + textOffsetX(_textOffsetX), textOffsetY(_textOffsetY), align(alignment), strFont("font13"), textColor(0xffffffff), disabledColor(0x60ffffff), iAngle(angle), shadowColor(0), focusedColor(0xffffffff) { @@ -299,7 +297,7 @@ namespace XBMCAddon long _checkWidth, long _checkHeight, long _alignment, const char* font, const char* _textColor, const char* _disabledColor) : - Control("ControlCheckMark"), strFont("font13"), checkWidth(_checkWidth), checkHeight(_checkHeight), + strFont("font13"), checkWidth(_checkWidth), checkHeight(_checkHeight), align(_alignment), textColor(0xffffffff), disabledColor(0x60ffffff) { dwPosX = x; @@ -406,7 +404,7 @@ namespace XBMCAddon ControlImage::ControlImage(long x, long y, long width, long height, const char* filename, long aspectRatio, const char* _colorDiffuse): - Control("ControlImage"), colorDiffuse(0) + colorDiffuse(0) { dwPosX = x; dwPosY = y; @@ -462,8 +460,7 @@ namespace XBMCAddon const char* textureleft, const char* texturemid, const char* textureright, - const char* textureoverlay): - Control("ControlProgress") + const char* textureoverlay) { dwPosX = x; dwPosY = y; @@ -516,8 +513,7 @@ namespace XBMCAddon ControlSlider::ControlSlider(long x, long y, long width, long height, const char* textureback, const char* texture, - const char* texturefocus) : - Control("ControlSlider") + const char* texturefocus) { dwPosX = x; dwPosY = y; @@ -558,8 +554,7 @@ namespace XBMCAddon // ============================================================ // ============================================================ - ControlGroup::ControlGroup(long x, long y, long width, long height): - Control("ControlCheckMark") + ControlGroup::ControlGroup(long x, long y, long width, long height) { dwPosX = x; dwPosY = y; @@ -591,7 +586,7 @@ namespace XBMCAddon const char* _disabledColor, long angle, const char* _shadowColor, const char* _focusedColor, const char* TextureRadioFocus, const char* TextureRadioNoFocus) : - Control("ControlRadioButton"), strFont("font13"), textColor(0xffffffff), disabledColor(0x60ffffff), + strFont("font13"), textColor(0xffffffff), disabledColor(0x60ffffff), textOffsetX(_textOffsetX), textOffsetY(_textOffsetY), align(alignment), iAngle(angle), shadowColor(0), focusedColor(0xffffffff) { @@ -929,7 +924,7 @@ namespace XBMCAddon // ============================================================ // ControlSpin // ============================================================ - ControlSpin::ControlSpin() : Control("ControlSpin") + ControlSpin::ControlSpin() { // default values for spin control color = 0xffffffff; @@ -975,7 +970,7 @@ namespace XBMCAddon const char* p_disabledColor, long p_alignment, bool hasPath, long angle) : - Control("ControlLabel"), strFont("font13"), + strFont("font13"), textColor(0xffffffff), disabledColor(0x60ffffff), align(p_alignment), bHasPath(hasPath), iAngle(angle) { @@ -1046,7 +1041,7 @@ namespace XBMCAddon const char* _disabledColor, long _alignment, const char* focusTexture, const char* noFocusTexture, bool isPassword) : - Control("ControlEdit"), strFont("font13"), textColor(0xffffffff), disabledColor(0x60ffffff), + strFont("font13"), textColor(0xffffffff), disabledColor(0x60ffffff), align(_alignment), bIsPassword(isPassword) { @@ -1130,7 +1125,6 @@ namespace XBMCAddon const char* cselectedColor, long _imageWidth, long _imageHeight, long _itemTextXOffset, long _itemTextYOffset, long _itemHeight, long _space, long _alignmentY) : - Control("ControlList"), strFont("font13"), textColor(0xe0f0f0f0), selectedColor(0xffffffff), imageHeight(_imageHeight), imageWidth(_imageWidth), @@ -1202,14 +1196,23 @@ namespace XBMCAddon return pGUIControl; } - void ControlList::addItemStream(const String& fileOrUrl, bool sendMessage) throw(UnimplementedException,WindowException) + void ControlList::addItem(const Alternative<String, const XBMCAddon::xbmcgui::ListItem* > & item, bool sendMessage) { - internAddListItem(ListItem::fromString(fileOrUrl),sendMessage); + TRACE; + + if (item.which() == first) + internAddListItem(ListItem::fromString(item.former()),sendMessage); + else + internAddListItem(item.later(),sendMessage); } - void ControlList::addListItem(const XBMCAddon::xbmcgui::ListItem* pListItem, bool sendMessage) throw(UnimplementedException,WindowException) + void ControlList::addItems(const std::vector<Alternative<String, const XBMCAddon::xbmcgui::ListItem* > > & items) { - internAddListItem(pListItem,sendMessage); + TRACE; + + for (std::vector<Alternative<String, const XBMCAddon::xbmcgui::ListItem* > >::const_iterator iter = items.begin(); iter != items.end(); ++iter) + addItem(*iter,false); + sendLabelBind(items.size()); } void ControlList::internAddListItem(AddonClass::Ref<ListItem> pListItem, bool sendMessage) throw (WindowException) diff --git a/xbmc/interfaces/legacy/Control.h b/xbmc/interfaces/legacy/Control.h index 4a30d04b45..743ddb15d4 100644 --- a/xbmc/interfaces/legacy/Control.h +++ b/xbmc/interfaces/legacy/Control.h @@ -24,6 +24,7 @@ #include "guilib/GUIFont.h" #include "guilib/Key.h" +#include "Alternative.h" #include "Tuple.h" #include "ListItem.h" #include "swighelper.h" @@ -39,48 +40,19 @@ namespace XBMCAddon { namespace xbmcgui { - - // Parent for control classes. The problem here is that Python uses - // references to this class in a dynamic typing way. For example, - // you will find this type of python code frequently: - // - // window.getControl( 100 ).setLabel( "Stupid Dynamic Type") - // - // Notice that the 'getControl' call returns a 'Control' object. - // In a dynamically typed language, the subsequent call to setLabel - // works if the specific type of control has the method. The script - // writer is often in a position to know more than the code about - // the specific Control type (in the example, that control id 100 - // is a 'ControlLabel') where the C++ code is not. - // - // SWIG doesn't support this type of dynamic typing. The 'Control' - // wrapper that's returned will wrap a ControlLabel but will not - // have the 'setLabel' method on it. The only way to handle this is - // to add all possible subclass methods to the parent class. This is - // ugly but the alternative is nearly as ugly. It's particularly ugly - // here because the majority of the methods are unique to the - // particular subclass. - // - // If anyone thinks they have a solution then let me know. The alternative - // would be to have a set of 'getContol' methods, each one coresponding - // to a type so that the downcast can be done in the native code. IOW - // rather than a simple 'getControl' there would be a 'getControlLabel', - // 'getControlRadioButton', 'getControlButton', etc. - // - // TODO:This later solution should be implemented for future scripting - // languages while the former will remain as deprecated functionality - // for Python. - // - // We don't need the SWIGHIDDENVIRTUAL since this is not a director. + /** + * Control class. + * + * Base class for all controls. + */ class Control : public AddonClass { protected: - public: - Control(const char* classname) : AddonClass(classname), - iControlId(0), iParentId(0), dwPosX(0), dwPosY(0), dwWidth(0), - dwHeight(0), iControlUp(0), iControlDown(0), iControlLeft(0), - iControlRight(0), pGUIControl(NULL) {} + Control() : iControlId(0), iParentId(0), dwPosX(0), dwPosY(0), dwWidth(0), + dwHeight(0), iControlUp(0), iControlDown(0), iControlLeft(0), + iControlRight(0), pGUIControl(NULL) {} + public: virtual ~Control(); #ifndef SWIG @@ -91,188 +63,6 @@ namespace XBMCAddon virtual bool canAcceptMessages(int actionId) { return false; } /** - * setLabel() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setLabel(const String& label = emptyString, - const char* font = NULL, - const char* textColor = NULL, - const char* disabledColor = NULL, - const char* shadowColor = NULL, - const char* focusedColor = NULL, - const String& label2 = emptyString) DECL_UNIMP("Control"); - /** - * reset() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void reset() DECL_UNIMP("Control"); - /** - * removeItem() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void removeItem(int index) DECL_UNIMP2("Control",WindowException); - /** - * setSelected() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setSelected(bool selected) DECL_UNIMP("Control"); - /** - * setPercent() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setPercent(float pct) DECL_UNIMP("Control"); - /** - * setDisabledColor() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setDisabledColor(const char* color) DECL_UNIMP("Control"); - /** - * getPercent() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual float getPercent() DECL_UNIMP("Control"); - /** - * getLabel() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual String getLabel() DECL_UNIMP("Control"); - /** - * getText() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual String getText() DECL_UNIMP("Control"); - /** - * size() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual long size() DECL_UNIMP("Control"); - /** - * setTextures() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setTextures(const char* up, const char* down, - const char* upFocus, - const char* downFocus) DECL_UNIMP("Control"); - /** - * setText() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setText(const String& text) DECL_UNIMP("Control"); - /** - * setStaticContent() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setStaticContent(const ListItemList* items) DECL_UNIMP("Control"); - /** - * setSpace() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setSpace(int space) DECL_UNIMP("Control"); - /** - * setRadioDimension() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setRadioDimension(long x, long y, long width, long height) DECL_UNIMP("Control"); - /** - * setPageControlVisible() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setPageControlVisible(bool visible) DECL_UNIMP("Control"); - /** - * setItemHeight() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setItemHeight(long height) DECL_UNIMP("Control"); - /** - * setImageDimensions() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setImageDimensions(long imageWidth,long imageHeight) DECL_UNIMP("Control"); - /** - * setImage() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setImage(const char* imageFilename) DECL_UNIMP("Control"); - /** - * setColorDiffuse() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void setColorDiffuse(const char* hexString) DECL_UNIMP("Control"); - /** - * selectItem() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void selectItem(long item) DECL_UNIMP("Control"); - /** - * scroll() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void scroll(long id) DECL_UNIMP("Control"); - /** - * isSelected() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual bool isSelected() DECL_UNIMP("Control"); - /** - * getSpinControl() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual Control* getSpinControl() DECL_UNIMP("Control"); - /** - * getSpace() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual long getSpace() DECL_UNIMP("Control"); - /** - * getSelectedPosition() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual long getSelectedPosition() DECL_UNIMP("Control"); - /** - * getSelectedItem() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual XBMCAddon::xbmcgui::ListItem* getSelectedItem() DECL_UNIMP("Control"); - /** - * getSelected() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual bool getSelected() DECL_UNIMP("Control"); - /** - * getListItem() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual XBMCAddon::xbmcgui::ListItem* getListItem(int index) DECL_UNIMP2("Control",WindowException); - /** - * getLabel2() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual String getLabel2() DECL_UNIMP("Control"); - /** - * getItemHeight() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual long getItemHeight() DECL_UNIMP("Control"); - /** - * addLabel() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void addLabel(const String& label) DECL_UNIMP("Control"); - - // These need to be here for the stubbed out addItem - // and addItems methods - /** - * addItemStream() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void addItemStream(const String& fileOrUrl, bool sendMessage = true) DECL_UNIMP2("Control",WindowException); - /** - * addListItem() is only defined in subclasses of Control. See the specific - * subclass for the appropriate documentation. - */ - virtual void addListItem(const XBMCAddon::xbmcgui::ListItem* listitem, bool sendMessage = true) DECL_UNIMP2("Control",WindowException); - - /** * getId() -- Returns the control's current id as an integer. * * example: @@ -614,7 +404,6 @@ namespace XBMCAddon const String& label2 = emptyString) throw(UnimplementedException); #ifndef SWIG ControlLabel() : - Control ("ControlLabel"), bHasPath(false), iAngle (0) {} @@ -628,6 +417,7 @@ namespace XBMCAddon int iAngle; SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); + #endif }; @@ -716,7 +506,6 @@ namespace XBMCAddon #ifndef SWIG ControlEdit() : - Control ("ControlEdit"), bIsPassword (false) {} @@ -788,8 +577,21 @@ namespace XBMCAddon * example: * - cList.addItem('Reboot XBMC') */ - virtual void addItemStream(const String& fileOrUrl, bool sendMessage = true) throw(UnimplementedException,WindowException); - virtual void addListItem(const XBMCAddon::xbmcgui::ListItem* listitem, bool sendMessage = true) throw(UnimplementedException,WindowException); + virtual void addItem(const Alternative<String, const XBMCAddon::xbmcgui::ListItem* > & item, bool sendMessage = true); + + /** + * addItems(items) -- Adds a list of listitems or strings to this list control. + * + * items : List - list of strings, unicode objects or ListItems to add. + * + * *Note, You can use the above as keywords for arguments. + * + * Large lists benefit considerably, than using the standard addItem() + * + * example: + * - cList.addItems(items=listitems) + */ + virtual void addItems(const std::vector<Alternative<String, const XBMCAddon::xbmcgui::ListItem* > > & items); /** * selectItem(item) -- Select an item by index number. @@ -961,7 +763,6 @@ namespace XBMCAddon // This is called from AddonWindow.cpp but shouldn't be available // to the scripting languages. ControlList() : - Control("ControlList"), imageHeight (0), imageWidth (0), itemHeight (0), @@ -1049,7 +850,7 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); - ControlFadeLabel() : Control("ControlFadeLabel") {} + ControlFadeLabel() {} #endif }; @@ -1116,7 +917,7 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); - ControlTextBox() : Control("ControlTextBox") {} + ControlTextBox() {} #endif }; @@ -1170,7 +971,6 @@ namespace XBMCAddon #ifndef SWIG ControlImage() : - Control ("ControlImage"), aspectRatio (0) {} @@ -1223,7 +1023,6 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); ControlProgress() : - Control ("ControlProgress"), aspectRatio (0) {} #endif @@ -1346,7 +1145,6 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); ControlButton() : - Control ("ControlButton"), textOffsetX (0), textOffsetY (0), iAngle (0), @@ -1461,7 +1259,6 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); ControlCheckMark() : - Control ("ControlCheckMark"), checkWidth (0), checkHeight (0) {} @@ -1489,7 +1286,7 @@ namespace XBMCAddon #ifndef SWIG SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); - ControlGroup() : Control("ControlGroup") {} + inline ControlGroup() {} #endif }; @@ -1630,7 +1427,6 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); ControlRadioButton() : - Control ("ControlRadioButton"), textOffsetX (0), textOffsetY (0), iAngle (0) @@ -1689,7 +1485,7 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL CGUIControl* Create() throw (WindowException); - ControlSlider() : Control("ControlSlider") {} + inline ControlSlider() {} #endif }; } diff --git a/xbmc/interfaces/legacy/Dialog.cpp b/xbmc/interfaces/legacy/Dialog.cpp index f907e60bb4..cbb10eb333 100644 --- a/xbmc/interfaces/legacy/Dialog.cpp +++ b/xbmc/interfaces/legacy/Dialog.cpp @@ -36,7 +36,6 @@ namespace XBMCAddon { namespace xbmcgui { - static void XBMCWaitForThreadMessage(int message, int param1, int param2) { ThreadMessage tMsg = {(DWORD)message, (DWORD)param1, (DWORD)param2}; diff --git a/xbmc/interfaces/legacy/Dialog.h b/xbmc/interfaces/legacy/Dialog.h index 0697d1c71d..8cc0e041c4 100644 --- a/xbmc/interfaces/legacy/Dialog.h +++ b/xbmc/interfaces/legacy/Dialog.h @@ -51,7 +51,7 @@ namespace XBMCAddon { public: - Dialog() : AddonClass("Dialog") {} + inline Dialog() {} virtual ~Dialog(); /** @@ -297,7 +297,7 @@ namespace XBMCAddon public: - DialogProgress() : AddonClass("DialogProgress"), dlg(NULL) {} + DialogProgress() : dlg(NULL) {} virtual ~DialogProgress(); @@ -366,7 +366,7 @@ namespace XBMCAddon public: - DialogProgressBG() : AddonClass("DialogProgressBG"), dlg(NULL), handle(NULL) {} + DialogProgressBG() : dlg(NULL), handle(NULL) {} virtual ~DialogProgressBG(); diff --git a/xbmc/interfaces/legacy/Exception.h b/xbmc/interfaces/legacy/Exception.h index 5a88b65e40..5741c85ec0 100644 --- a/xbmc/interfaces/legacy/Exception.h +++ b/xbmc/interfaces/legacy/Exception.h @@ -68,6 +68,4 @@ namespace XBMCAddon * languages. See the comment in AddonControl.h for more details. */ #define THROW_UNIMP(classname) throw UnimplementedException(classname, __FUNCTION__) -#define DECL_UNIMP(classname) throw(UnimplementedException) { throw UnimplementedException(classname, __FUNCTION__); } -#define DECL_UNIMP2(classname,otherexception) throw(UnimplementedException,otherexception) { throw UnimplementedException(classname, __FUNCTION__); } diff --git a/xbmc/interfaces/legacy/File.cpp b/xbmc/interfaces/legacy/File.cpp index b93a5b6e5b..433cc72343 100644 --- a/xbmc/interfaces/legacy/File.cpp +++ b/xbmc/interfaces/legacy/File.cpp @@ -22,7 +22,6 @@ namespace XBMCAddon { - namespace xbmcvfs { XbmcCommons::Buffer File::readBytes(unsigned long numBytes) diff --git a/xbmc/interfaces/legacy/File.h b/xbmc/interfaces/legacy/File.h index d356230190..0dfcbd0049 100644 --- a/xbmc/interfaces/legacy/File.h +++ b/xbmc/interfaces/legacy/File.h @@ -45,7 +45,7 @@ namespace XBMCAddon { XFILE::CFile* file; public: - inline File(const String& filepath, const char* mode = NULL) : AddonClass("File"), file(new XFILE::CFile()) + inline File(const String& filepath, const char* mode = NULL) : file(new XFILE::CFile()) { DelayedCallGuard dg(languageHook); if (mode && strncmp(mode, "w", 1) == 0) diff --git a/xbmc/interfaces/legacy/InfoTagMusic.cpp b/xbmc/interfaces/legacy/InfoTagMusic.cpp index 8f608f9578..fe01cba12b 100644 --- a/xbmc/interfaces/legacy/InfoTagMusic.cpp +++ b/xbmc/interfaces/legacy/InfoTagMusic.cpp @@ -26,12 +26,12 @@ namespace XBMCAddon { namespace xbmc { - InfoTagMusic::InfoTagMusic() : AddonClass("InfoTagMusic") + InfoTagMusic::InfoTagMusic() { infoTag = new MUSIC_INFO::CMusicInfoTag(); } - InfoTagMusic::InfoTagMusic(const MUSIC_INFO::CMusicInfoTag& tag) : AddonClass("InfoTagMusic") + InfoTagMusic::InfoTagMusic(const MUSIC_INFO::CMusicInfoTag& tag) { infoTag = new MUSIC_INFO::CMusicInfoTag(); *infoTag = tag; diff --git a/xbmc/interfaces/legacy/InfoTagMusic.h b/xbmc/interfaces/legacy/InfoTagMusic.h index 63865f0a8c..3a8777e977 100644 --- a/xbmc/interfaces/legacy/InfoTagMusic.h +++ b/xbmc/interfaces/legacy/InfoTagMusic.h @@ -102,7 +102,6 @@ namespace XBMCAddon * getLyrics() -- returns a string.\n */ String getLyrics(); - }; } } diff --git a/xbmc/interfaces/legacy/InfoTagVideo.cpp b/xbmc/interfaces/legacy/InfoTagVideo.cpp index dc4b680512..9c5d1abf08 100644 --- a/xbmc/interfaces/legacy/InfoTagVideo.cpp +++ b/xbmc/interfaces/legacy/InfoTagVideo.cpp @@ -26,12 +26,12 @@ namespace XBMCAddon { namespace xbmc { - InfoTagVideo::InfoTagVideo() : AddonClass("InfoTagVideo") + InfoTagVideo::InfoTagVideo() { infoTag = new CVideoInfoTag(); } - InfoTagVideo::InfoTagVideo(const CVideoInfoTag& tag) : AddonClass("InfoTagVideo") + InfoTagVideo::InfoTagVideo(const CVideoInfoTag& tag) { infoTag = new CVideoInfoTag(); *infoTag = tag; diff --git a/xbmc/interfaces/legacy/Keyboard.cpp b/xbmc/interfaces/legacy/Keyboard.cpp index b6c5ad79f8..be2d3528d1 100644 --- a/xbmc/interfaces/legacy/Keyboard.cpp +++ b/xbmc/interfaces/legacy/Keyboard.cpp @@ -30,8 +30,9 @@ namespace XBMCAddon { namespace xbmc { + Keyboard::Keyboard(const String& line /* = nullString*/, const String& heading/* = nullString*/, bool hidden/* = false*/) - : AddonClass("Keyboard"), strDefault(line), strHeading(heading), bHidden(hidden), bConfirmed(false) + : strDefault(line), strHeading(heading), bHidden(hidden), bConfirmed(false) { } diff --git a/xbmc/interfaces/legacy/Keyboard.h b/xbmc/interfaces/legacy/Keyboard.h index 6f4d39e950..0392a1842f 100644 --- a/xbmc/interfaces/legacy/Keyboard.h +++ b/xbmc/interfaces/legacy/Keyboard.h @@ -126,7 +126,6 @@ namespace XBMCAddon * - if (kb.isConfirmed()): */ bool isConfirmed(); - }; } } diff --git a/xbmc/interfaces/legacy/LanguageHook.h b/xbmc/interfaces/legacy/LanguageHook.h index 6b929f2054..76ca78fd57 100644 --- a/xbmc/interfaces/legacy/LanguageHook.h +++ b/xbmc/interfaces/legacy/LanguageHook.h @@ -42,7 +42,7 @@ namespace XBMCAddon class LanguageHook : public AddonClass { protected: - LanguageHook(const char* subclassName) : AddonClass(subclassName) {} + inline LanguageHook() {} public: virtual ~LanguageHook(); diff --git a/xbmc/interfaces/legacy/ListItem.cpp b/xbmc/interfaces/legacy/ListItem.cpp index ec380b0f7f..7ad8ac976d 100644 --- a/xbmc/interfaces/legacy/ListItem.cpp +++ b/xbmc/interfaces/legacy/ListItem.cpp @@ -39,7 +39,7 @@ namespace XBMCAddon const String& label2, const String& iconImage, const String& thumbnailImage, - const String& path) : AddonClass("ListItem") + const String& path) { item.reset(); diff --git a/xbmc/interfaces/legacy/ListItem.h b/xbmc/interfaces/legacy/ListItem.h index 8c495d9120..f88bbdf581 100644 --- a/xbmc/interfaces/legacy/ListItem.h +++ b/xbmc/interfaces/legacy/ListItem.h @@ -56,7 +56,7 @@ namespace XBMCAddon const String& path = emptyString); #ifndef SWIG - inline ListItem(CFileItemPtr pitem) : AddonClass("ListItem"), item(pitem) {} + inline ListItem(CFileItemPtr pitem) : item(pitem) {} static inline AddonClass::Ref<ListItem> fromString(const String& str) { @@ -346,7 +346,6 @@ namespace XBMCAddon * getfilename() -- Returns the filename of this PlayListItem.\n */ String getfilename(); - }; typedef std::vector<ListItem*> ListItemList; diff --git a/xbmc/interfaces/legacy/ModuleXbmcvfs.h b/xbmc/interfaces/legacy/ModuleXbmcvfs.h index 857a12f311..c1b66e71a0 100644 --- a/xbmc/interfaces/legacy/ModuleXbmcvfs.h +++ b/xbmc/interfaces/legacy/ModuleXbmcvfs.h @@ -40,6 +40,7 @@ namespace XBMCAddon */ bool copy(const String& strSource, const String& strDestnation); + // delete a file /** * delete(file) * @@ -48,7 +49,6 @@ namespace XBMCAddon * example: * - xbmcvfs.delete(file) */ - // delete a file bool deleteFile(const String& file); /** diff --git a/xbmc/interfaces/legacy/Monitor.cpp b/xbmc/interfaces/legacy/Monitor.cpp index 2f6580e15b..e67580ad45 100644 --- a/xbmc/interfaces/legacy/Monitor.cpp +++ b/xbmc/interfaces/legacy/Monitor.cpp @@ -24,7 +24,7 @@ namespace XBMCAddon { namespace xbmc { - Monitor::Monitor() : AddonCallback("Monitor") + Monitor::Monitor() { if (languageHook) { diff --git a/xbmc/interfaces/legacy/Monitor.h b/xbmc/interfaces/legacy/Monitor.h index 9291f671db..0e03cb137f 100644 --- a/xbmc/interfaces/legacy/Monitor.h +++ b/xbmc/interfaces/legacy/Monitor.h @@ -28,9 +28,9 @@ namespace XBMCAddon namespace xbmc { /** - * Monitor class.\n - * \n - * Monitor() -- Creates a new Monitor to notify addon about changes.\n + * Monitor class. + * + * Monitor() -- Creates a new Monitor to notify addon about changes. */ class Monitor : public AddonCallback { @@ -46,6 +46,8 @@ namespace XBMCAddon inline void OnDatabaseScanStarted(const String &database) { TRACE; invokeCallback(new CallbackFunction<Monitor,const String>(this,&Monitor::onDatabaseScanStarted,database)); } inline void OnAbortRequested() { TRACE; invokeCallback(new CallbackFunction<Monitor>(this,&Monitor::onAbortRequested)); } inline void OnNotification(const String &sender, const String &method, const String &data) { TRACE; invokeCallback(new CallbackFunction<Monitor,const String,const String,const String>(this,&Monitor::onNotification,sender,method,data)); } + + inline const String& GetId() { return Id; } #endif /** @@ -106,8 +108,6 @@ namespace XBMCAddon virtual void onNotification(const String sender, const String method, const String data) { TRACE; } virtual ~Monitor(); - - inline const String& GetId() { return Id; } }; } }; diff --git a/xbmc/interfaces/legacy/PlayList.cpp b/xbmc/interfaces/legacy/PlayList.cpp index e67b41e726..a84428c522 100644 --- a/xbmc/interfaces/legacy/PlayList.cpp +++ b/xbmc/interfaces/legacy/PlayList.cpp @@ -33,7 +33,6 @@ namespace XBMCAddon // TODO: need a means to check for a valid construction // either by throwing an exception or by an "isValid" check PlayList::PlayList(int playList) throw (PlayListException) : - AddonClass("PlayList"), refs(1), iPlayList(playList), pPlayList(NULL) { // we do not create our own playlist, just using the ones from playlistplayer diff --git a/xbmc/interfaces/legacy/Player.cpp b/xbmc/interfaces/legacy/Player.cpp index 2f41102f80..ad51349e51 100644 --- a/xbmc/interfaces/legacy/Player.cpp +++ b/xbmc/interfaces/legacy/Player.cpp @@ -35,7 +35,7 @@ namespace XBMCAddon { namespace xbmc { - Player::Player(int _playerCore): AddonCallback("Player") + Player::Player(int _playerCore) { iPlayList = PLAYLIST_MUSIC; @@ -66,6 +66,19 @@ namespace XBMCAddon } } + void Player::play(const Alternative<String, const PlayList* > & item, + const XBMCAddon::xbmcgui::ListItem* listitem, bool windowed, int startpos) + { + TRACE; + + if (Alternative<String, const PlayList*>::isNullReference(item)) + playCurrent(windowed); + else if (item.which() == XBMCAddon::first) + playStream(item.former(), listitem, windowed); + else // item is a PlayListItem + playPlaylist(item.later(),windowed,startpos); + } + void Player::playStream(const String& item, const xbmcgui::ListItem* plistitem, bool windowed) { TRACE; diff --git a/xbmc/interfaces/legacy/Player.h b/xbmc/interfaces/legacy/Player.h index 3f2a561241..2ab12b8856 100644 --- a/xbmc/interfaces/legacy/Player.h +++ b/xbmc/interfaces/legacy/Player.h @@ -30,6 +30,7 @@ #include "AddonString.h" #include "InfoTagMusic.h" #include "AddonCallback.h" +#include "Alternative.h" #include "swighelper.h" @@ -39,23 +40,35 @@ namespace XBMCAddon { XBMCCOMMONS_STANDARD_EXCEPTION(PlayerException); - /** - * Player class. - * - * Player() -- Creates a new Player class. - */ + typedef Alternative<String, const PlayList* > PlayParameter; // This class is a merge of what was previously in xbmcmodule/player.h // and xbmcmodule/PythonPlayer.h without the python references. The // queuing and handling of asynchronous callbacks is done internal to // this class. + /** + * Player class. + * + * Player([core]) -- Creates a new Player with as default the xbmc music playlist. + * + * core : (optional) Use a specified playcore instead of letting xbmc decide the playercore to use. + * - xbmc.PLAYER_CORE_AUTO + * - xbmc.PLAYER_CORE_DVDPLAYER + * - xbmc.PLAYER_CORE_MPLAYER + * - xbmc.PLAYER_CORE_PAPLAYER + */ class Player : public AddonCallback, public IPlayerCallback { private: int iPlayList; EPLAYERCORES playerCore; + void playStream(const String& item = emptyString, const XBMCAddon::xbmcgui::ListItem* listitem = NULL, bool windowed = false); + void playPlaylist(const PlayList* playlist = NULL, + bool windowed = false, int startpos=-1); + void playCurrent(bool windowed = false); + public: // Construct a Player proxying the given generated binding. The // construction of a Player needs to identify whether or not any @@ -64,9 +77,9 @@ namespace XBMCAddon virtual ~Player(void); /** - * playStream([item, listitem, windowed]) -- Play this item.\n + * play([item, listitem, windowed]) -- Play this item.\n * \n - * item : [opt] string - filename or url.\n + * item : [opt] string - filename, url or playlist.\n * listitem : [opt] listitem - used with setInfo() to set different infolabels.\n * windowed : [opt] bool - true=play video windowed, false=play users preference.(default)\n * \n @@ -75,42 +88,14 @@ namespace XBMCAddon * \n * You can use the above as keywords for arguments and skip certain optional arguments.\n * Once you use a keyword, all following arguments require the keyword.\n - * - * example: - * - listitem = xbmcgui.ListItem('Ironman') - * - listitem.setInfo('video', {'Title': 'Ironman', 'Genre': 'Science Fiction'}) - * - xbmc.Player().play(url, listitem, windowed) - */ - void playStream(const String& item = emptyString, const XBMCAddon::xbmcgui::ListItem* listitem = NULL, bool windowed = false); - - /** - * playPlaylist([playlist, windowed, startpos]) -- Play this item.\n - * \n - * playlist : [opt] playlist.\n - * windowed : [opt] bool - true=play video windowed, false=play users preference.(default)\n - * startpos : [opt] int - Playlist starting position (0 based). If not given, current position is used\n - * \n - * *Note, If playlist is not given then the Player will try to play the current item\n - * in the current playlist.\n - * \n - * You can use the above as keywords for arguments and skip certain optional arguments.\n - * Once you use a keyword, all following arguments require the keyword.\n * \n * example:\n + * - listitem = xbmcgui.ListItem('Ironman')\n + * - listitem.setInfo('video', {'Title': 'Ironman', 'Genre': 'Science Fiction'})\n + * - xbmc.Player( xbmc.PLAYER_CORE_MPLAYER ).play(url, listitem, windowed)\n */ - void playPlaylist(const PlayList* playlist = NULL, - bool windowed = false, int startpos=-1); - - /** - * play() -- try to play the current item in the current playlist. - * - * windowed : [opt] bool - true=play video windowed, false=play users preference (default). - * - * example: - * - * - xbmc.Player().play() - */ - void playCurrent(bool windowed = false); + void play(const PlayParameter& item = PlayParameter::nullItem(), + const XBMCAddon::xbmcgui::ListItem* listitem = NULL, bool windowed = false, int startpos = -1); /** * stop() -- Stop playing. diff --git a/xbmc/interfaces/legacy/RenderCapture.h b/xbmc/interfaces/legacy/RenderCapture.h index 4ec69c6981..12ce1c4ac3 100644 --- a/xbmc/interfaces/legacy/RenderCapture.h +++ b/xbmc/interfaces/legacy/RenderCapture.h @@ -23,6 +23,7 @@ #include "cores/VideoRenderers/RenderManager.h" #include "cores/VideoRenderers/RenderCapture.h" #include "AddonClass.h" +#include "LanguageHook.h" #include "Exception.h" #include "commons/Buffer.h" @@ -36,7 +37,7 @@ namespace XBMCAddon { CRenderCapture* m_capture; public: - inline RenderCapture() : AddonClass("RenderCapture"), m_capture(g_renderManager.AllocRenderCapture()) {} + inline RenderCapture() : m_capture(g_renderManager.AllocRenderCapture()) {} inline virtual ~RenderCapture() { g_renderManager.ReleaseRenderCapture(m_capture); } /** diff --git a/xbmc/interfaces/legacy/Stat.h b/xbmc/interfaces/legacy/Stat.h index 63bc4f6337..b13616213d 100644 --- a/xbmc/interfaces/legacy/Stat.h +++ b/xbmc/interfaces/legacy/Stat.h @@ -42,7 +42,7 @@ namespace XBMCAddon struct __stat64 st; public: - Stat(const String& path) : AddonClass("Stat") + Stat(const String& path) { DelayedCallGuard dg; XFILE::CFile::Stat(path, &st); diff --git a/xbmc/interfaces/legacy/Window.cpp b/xbmc/interfaces/legacy/Window.cpp index f29fca6d68..76478bacb3 100644 --- a/xbmc/interfaces/legacy/Window.cpp +++ b/xbmc/interfaces/legacy/Window.cpp @@ -83,8 +83,8 @@ namespace XBMCAddon CGUIWindow* ProxyExistingWindowInterceptor::get() { TRACE; return cguiwindow; } - Window::Window(const char* classname) throw (WindowException): - AddonCallback(classname), isDisposed(false), window(NULL), iWindowId(-1), + Window::Window() throw (WindowException): + isDisposed(false), window(NULL), iWindowId(-1), iOldWindowId(0), iCurrentControlId(3000), bModal(false), m_actionEvent(true), canPulse(true), existingWindow(false), destroyAfterDeInit(false) { @@ -95,7 +95,7 @@ namespace XBMCAddon * This just creates a default window. */ Window::Window(int existingWindowId) throw (WindowException) : - AddonCallback("Window"), isDisposed(false), window(NULL), iWindowId(-1), + isDisposed(false), window(NULL), iWindowId(-1), iOldWindowId(0), iCurrentControlId(3000), bModal(false), m_actionEvent(true), canPulse(false), existingWindow(true), destroyAfterDeInit(false) { diff --git a/xbmc/interfaces/legacy/Window.h b/xbmc/interfaces/legacy/Window.h index 636db05f60..dfe097f381 100644 --- a/xbmc/interfaces/legacy/Window.h +++ b/xbmc/interfaces/legacy/Window.h @@ -40,15 +40,22 @@ namespace XBMCAddon // file needs to include the Window class because of the template class InterceptorBase; + /** + * Action class. + * + * For backwards compatibility reasons the == operator is extended so that it\n + * can compare an action with other actions and action.GetID() with numbers + * - example: (action == ACTION_MOVE_LEFT) + */ class Action : public AddonClass { public: - Action() : AddonClass("Action"), id(-1), fAmount1(0.0f), fAmount2(0.0f), + Action() : id(-1), fAmount1(0.0f), fAmount2(0.0f), fRepeat(0.0f), buttonCode(0), strAction("") { } #ifndef SWIG - Action(const CAction& caction) : AddonClass("Action") { setFromCAction(caction); } + Action(const CAction& caction) { setFromCAction(caction); } void setFromCAction(const CAction& caction); @@ -63,31 +70,45 @@ namespace XBMCAddon AddonClass::Ref<Control> control; // previously pObject #endif - /** - * getId() -- Returns the action's current id as a long or 0 if no action is mapped in the xml's. - */ + /** + * getId() -- Returns the action's current id as a long or 0 if no action is mapped in the xml's. + */ long getId() { TRACE; return id; } - /** - * getButtonCode() -- Returns the button code for this action. - */ + /** + * getButtonCode() -- Returns the button code for this action. + */ long getButtonCode() { TRACE; return buttonCode; } - /** - * getAmount1() -- Returns the first amount of force applied to the thumbstick n. - */ + /** + * getAmount1() -- Returns the first amount of force applied to the thumbstick n. + */ float getAmount1() { TRACE; return fAmount1; } - /** - * getAmount2() -- Returns the second amount of force applied to the thumbstick n. - */ + /** + * getAmount2() -- Returns the second amount of force applied to the thumbstick n. + */ float getAmount2() { TRACE; return fAmount2; } }; + //============================================================================ + // This is the main class for the xbmcgui.Window functionality. It is tied + // into the main XBMC windowing system via the Interceptor\n + //============================================================================ /** - * This is the main class for the xbmcgui.Window functionality. It is tied\n - * into the main XBMC windowing system via the Interceptor\n - */ + * Window class. + * + * Window(self[, int windowId): + * - Create a new Window to draw on. + * - Specify an id to use an existing window. + * + * Throws: + * - ValueError, if supplied window Id does not exist. + * - Exception, if more then 200 windows are created. + * + * Deleting this window will activate the old window that was active\n + * and resets (not delete) all controls that are associated with this window. + */ class Window : public AddonCallback { friend class WindowDialogMixin; @@ -113,7 +134,7 @@ namespace XBMCAddon bool existingWindow; bool destroyAfterDeInit; - Window(const char* classname) throw (WindowException); + Window() throw (WindowException); virtual void deallocating(); @@ -148,7 +169,7 @@ namespace XBMCAddon #endif public: - Window(int existingWindowId = -1) throw (WindowException); + Window(int existingWindowId) throw (WindowException); virtual ~Window(); @@ -166,7 +187,7 @@ namespace XBMCAddon // This is called from the InterceptorBase destructor to prevent further // use of the interceptor from the window. - inline void interceptorClear() { Synchronize lock(*this); window = NULL; } + inline void interceptorClear() { CSingleLock lock(*this); window = NULL; } #endif // callback takes a parameter @@ -182,12 +203,46 @@ namespace XBMCAddon * - Don't forget to capture ACTION_PREVIOUS_MENU or ACTION_NAV_BACK, else the user can't close this window. */ virtual void onAction(Action* action); + // on control is not actually on Window in the api but is called - // into Python anyway. This must result in a problem when + // into Python anyway. + /** + * onControl(self, Control control) -- onClick method. + * + * This method will recieve all click events on owned and selected controls when\n + * the control itself doesn't handle the message. + */ virtual void onControl(Control* control); + + /** + * onClick(self, int controlId) -- onClick method. + * + * This method will recieve all click events that the main program will send\n + * to this window. + */ virtual void onClick(int controlId); + + /** + * onDoubleClick(self, int controlId) -- onClick method. + * + * This method will recieve all double click events that the main program will send\n + * to this window. + */ virtual void onDoubleClick(int controlId); + + /** + * onFocus(self, int controlId) -- onFocus method. + * + * This method will recieve all focus events that the main program will send\n + * to this window. + */ virtual void onFocus(int controlId); + + /** + * onInit(self) -- onInit method. + * + * This method will be called to initialize the window + */ virtual void onInit(); /** diff --git a/xbmc/interfaces/legacy/WindowDialog.cpp b/xbmc/interfaces/legacy/WindowDialog.cpp index 5989e05498..87f0d84a65 100644 --- a/xbmc/interfaces/legacy/WindowDialog.cpp +++ b/xbmc/interfaces/legacy/WindowDialog.cpp @@ -27,9 +27,8 @@ namespace XBMCAddon { namespace xbmcgui { - WindowDialog::WindowDialog() throw(WindowException) : - Window("WindowDialog"), WindowDialogMixin(this) + WindowDialogMixin(this) { CSingleLock lock(g_graphicsContext); setWindow(new Interceptor<CGUIWindow>("CGUIWindow",this,getNextAvailalbeWindowId())); diff --git a/xbmc/interfaces/legacy/WindowDialog.h b/xbmc/interfaces/legacy/WindowDialog.h index 6197968fc3..6b48ec23a7 100644 --- a/xbmc/interfaces/legacy/WindowDialog.h +++ b/xbmc/interfaces/legacy/WindowDialog.h @@ -28,6 +28,9 @@ namespace XBMCAddon { namespace xbmcgui { + /** + * WindowDialog class + */ class WindowDialog : public Window, private WindowDialogMixin { @@ -43,10 +46,10 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL bool IsDialogRunning() const { return WindowDialogMixin::IsDialogRunning(); } SWIGHIDDENVIRTUAL bool IsModalDialog() const { TRACE; return true; }; SWIGHIDDENVIRTUAL bool IsDialog() const { TRACE; return true; }; -#endif SWIGHIDDENVIRTUAL inline void show() { TRACE; WindowDialogMixin::show(); } SWIGHIDDENVIRTUAL inline void close() { TRACE; WindowDialogMixin::close(); } +#endif }; } } diff --git a/xbmc/interfaces/legacy/WindowXML.cpp b/xbmc/interfaces/legacy/WindowXML.cpp index 3203f35d27..6d21133527 100644 --- a/xbmc/interfaces/legacy/WindowXML.cpp +++ b/xbmc/interfaces/legacy/WindowXML.cpp @@ -91,32 +91,12 @@ namespace XBMCAddon }; - WindowXML::WindowXML(const String& xmlFilename, - const String& scriptPath, - const String& defaultSkin, - const String& defaultRes) throw(WindowException) : - Window("WindowXML") - { - initialize(xmlFilename,scriptPath,defaultSkin,defaultRes); - } - - WindowXML::WindowXML(const char* classname, - const String& xmlFilename, - const String& scriptPath, - const String& defaultSkin, - const String& defaultRes) throw(WindowException) : - Window(classname) - { - TRACE; - initialize(xmlFilename,scriptPath,defaultSkin,defaultRes); - } - WindowXML::~WindowXML() { TRACE; deallocating(); } - void WindowXML::initialize(const String& xmlFilename, + WindowXML::WindowXML(const String& xmlFilename, const String& scriptPath, const String& defaultSkin, - const String& defaultRes) + const String& defaultRes) throw(WindowException) { TRACE; RESOLUTION_INFO res; @@ -172,21 +152,14 @@ namespace XBMCAddon return getNextAvailalbeWindowId(); } - void WindowXML::addItem(const String& item, int pos) - { - TRACE; - AddonClass::Ref<ListItem> ritem(ListItem::fromString(item)); - addListItem(ritem.get(),pos); - } - - void WindowXML::addListItem(ListItem* item, int pos) + void WindowXML::addItem(const Alternative<String, const ListItem*>& item, int position) { TRACE; // item could be deleted if the reference count is 0. // so I MAY need to check prior to using a Ref just in // case this object is managed by Python. I'm not sure // though. - AddonClass::Ref<ListItem> ritem(item); + AddonClass::Ref<ListItem> ritem = item.which() == XBMCAddon::first ? ListItem::fromString(item.former()) : AddonClass::Ref<ListItem>(item.later()); // Tells the window to add the item to FileItem vector { @@ -197,17 +170,17 @@ namespace XBMCAddon //AddItem(ritem->item, pos); { CFileItemPtr& fileItem = ritem->item; - if (pos == INT_MAX || pos > A(m_vecItems)->Size()) + if (position == INT_MAX || position > A(m_vecItems)->Size()) { A(m_vecItems)->Add(fileItem); } - else if (pos < -1 && !(pos*-1 < A(m_vecItems)->Size())) + else if (position < -1 && !(position*-1 < A(m_vecItems)->Size())) { A(m_vecItems)->AddFront(fileItem,0); } else { - A(m_vecItems)->AddFront(fileItem,pos); + A(m_vecItems)->AddFront(fileItem,position); } A(m_viewControl).SetItems(*(A(m_vecItems))); A(UpdateButtons()); @@ -502,7 +475,7 @@ namespace XBMCAddon WindowXMLDialog::WindowXMLDialog(const String& xmlFilename, const String& scriptPath, const String& defaultSkin, const String& defaultRes) throw(WindowException) : - WindowXML("WindowXMLDialog",xmlFilename, scriptPath, defaultSkin, defaultRes), + WindowXML(xmlFilename, scriptPath, defaultSkin, defaultRes), WindowDialogMixin(this) { TRACE; } diff --git a/xbmc/interfaces/legacy/WindowXML.h b/xbmc/interfaces/legacy/WindowXML.h index 07c2ac3852..f3db088d4f 100644 --- a/xbmc/interfaces/legacy/WindowXML.h +++ b/xbmc/interfaces/legacy/WindowXML.h @@ -39,14 +39,27 @@ namespace XBMCAddon class ListItem; class WindowXMLInterceptor; + /** + * WindowXML class. + * + * WindowXML(self, xmlFilename, scriptPath[, defaultSkin, defaultRes]) -- Create a new WindowXML script. + * + * xmlFilename : string - the name of the xml file to look for.\n + * scriptPath : string - path to script. used to fallback to if the xml doesn't exist in the current skin. (eg os.getcwd())\n + * defaultSkin : [opt] string - name of the folder in the skins path to look in for the xml. (default='Default')\n + * defaultRes : [opt] string - default skins resolution. (default='720p') + * + * *Note, skin folder structure is eg(resources/skins/Default/720p) + * + * example:\n + * - ui = GUI('script-Lyrics-main.xml', os.getcwd(), 'LCARS', 'PAL')\n + * ui.doModal()\n + * del ui + */ class WindowXML : public Window { std::string sFallBackPath; - void initialize(const String& xmlFilename, - const String& scriptPath, - const String& defaultSkin, - const String& defaultRes); protected: #ifndef SWIG /** @@ -56,26 +69,94 @@ namespace XBMCAddon static int lockingGetNextAvailalbeWindowId() throw (WindowException); WindowXMLInterceptor* interceptor; - - WindowXML(const char* classname, const String& xmlFilename, const String& scriptPath, - const String& defaultSkin, - const String& defaultRes) throw(WindowException); #endif + public: WindowXML(const String& xmlFilename, const String& scriptPath, const String& defaultSkin = "Default", const String& defaultRes = "720p") throw(WindowException); virtual ~WindowXML(); + /** + * addItem(item[, position]) -- Add a new item to this Window List. + * + * - item : string, unicode or ListItem - item to add. + * - position : [opt] integer - position of item to add. (NO Int = Adds to bottom,0 adds to top, 1 adds to one below from top,-1 adds to one above from bottom etc etc ) + * - If integer positions are greater than list size, negative positions will add to top of list, positive positions will add to bottom of list + * + * example: + * - self.addItem('Reboot XBMC', 0) + */ + SWIGHIDDENVIRTUAL void addItem(const Alternative<String, const ListItem*>& item, int position = INT_MAX); + // these calls represent the python interface - SWIGHIDDENVIRTUAL void addItem(const String& item, int position = INT_MAX); - SWIGHIDDENVIRTUAL void addListItem(ListItem* item, int position = INT_MAX); + /** + * removeItem(position) -- Removes a specified item based on position, from the Window List. + * + * position : integer - position of item to remove. + * + * example:\n + * - self.removeItem(5) + */ SWIGHIDDENVIRTUAL void removeItem(int position); + + /** + * getCurrentListPosition() -- Gets the current position in the Window List. + * + * example:\n + * - pos = self.getCurrentListPosition() + */ SWIGHIDDENVIRTUAL int getCurrentListPosition(); + + /** + * setCurrentListPosition(position) -- Set the current position in the Window List. + * + * position : integer - position of item to set. + * + * example:\n + * - self.setCurrentListPosition(5) + */ SWIGHIDDENVIRTUAL void setCurrentListPosition(int position); + + /** + * getListItem(position) -- Returns a given ListItem in this Window List. + * + * position : integer - position of item to return. + * + * example:\n + * - listitem = self.getListItem(6) + */ SWIGHIDDENVIRTUAL ListItem* getListItem(int position) throw (WindowException); + + /** + * getListSize() -- Returns the number of items in this Window List. + * + * example:\n + * - listSize = self.getListSize() + */ SWIGHIDDENVIRTUAL int getListSize(); + + /** + * clearList() -- Clear the Window List. + * + * example:\n + * - self.clearList() + */ SWIGHIDDENVIRTUAL void clearList(); + + /** + * setProperty(key, value) -- Sets a container property, similar to an infolabel. + * + * key : string - property name.\n + * value : string or unicode - value of property. + * + * *Note, Key is NOT case sensitive. + * You can use the above as keywords for arguments and skip certain optional arguments.\n + * Once you use a keyword, all following arguments require the keyword. + * + * example:\n + * - self.setProperty('Category', 'Newest') + */ SWIGHIDDENVIRTUAL void setProperty(const String &strProperty, const String &strValue); #ifndef SWIG @@ -127,6 +208,23 @@ namespace XBMCAddon // At some point this entire hierarchy needs to be reworked. The XML handling // routines should be put in a mixin. + /** + * WindowXMLDialog class. + * + * WindowXMLDialog(self, xmlFilename, scriptPath[, defaultSkin, defaultRes]) -- Create a new WindowXMLDialog script. + * + * xmlFilename : string - the name of the xml file to look for.\n + * scriptPath : string - path to script. used to fallback to if the xml doesn't exist in the current skin. (eg os.getcwd())\n + * defaultSkin : [opt] string - name of the folder in the skins path to look in for the xml. (default='Default')\n + * defaultRes : [opt] string - default skins resolution. (default='720p') + * + * *Note, skin folder structure is eg(resources/skins/Default/720p) + * + * example: + * - ui = GUI('script-Lyrics-main.xml', os.getcwd(), 'LCARS', 'PAL') + * - ui.doModal() + * - del ui + */ class WindowXMLDialog : public WindowXML, private WindowDialogMixin { public: @@ -144,12 +242,12 @@ namespace XBMCAddon SWIGHIDDENVIRTUAL bool IsMediaWindow() const { TRACE; return false; }; SWIGHIDDENVIRTUAL bool OnAction(const CAction &action); SWIGHIDDENVIRTUAL void OnDeinitWindow(int nextWindowID); -#endif SWIGHIDDENVIRTUAL inline void show() { TRACE; WindowDialogMixin::show(); } SWIGHIDDENVIRTUAL inline void close() { TRACE; WindowDialogMixin::close(); } friend class DialogJumper; +#endif }; } } diff --git a/xbmc/interfaces/python/CallbackHandler.cpp b/xbmc/interfaces/python/CallbackHandler.cpp index 3283e0e42f..42599c5b29 100644 --- a/xbmc/interfaces/python/CallbackHandler.cpp +++ b/xbmc/interfaces/python/CallbackHandler.cpp @@ -25,14 +25,13 @@ namespace XBMCAddon { namespace Python { - /** * We are ASS-U-MEing that this construction is happening * within the context of a Python call. This way we can * store off the PyThreadState to later verify that we're * handling callbacks in the appropriate thread. */ - PythonCallbackHandler::PythonCallbackHandler() : RetardedAsynchCallbackHandler("PythonCallbackHandler") + PythonCallbackHandler::PythonCallbackHandler() { TRACE; objectThreadState = PyThreadState_Get(); @@ -49,7 +48,7 @@ namespace XBMCAddon if (objectThreadState == state) { // make sure the interpreter is still active. - AddonClass::Ref<XBMCAddon::Python::LanguageHook> lh(XBMCAddon::Python::LanguageHook::GetIfExists(state->interp)); + AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook> lh(XBMCAddon::Python::PythonLanguageHook::GetIfExists(state->interp)); if (lh.isNotNull() && lh->HasRegisteredAddonClassInstance(obj) && lh.get() == obj->GetLanguageHook()) return true; } @@ -71,7 +70,7 @@ namespace XBMCAddon // we also want to remove the callback if the language hook no longer exists. // this is a belt-and-suspenders cleanup mechanism - return ! XBMCAddon::Python::LanguageHook::IsAddonClassInstanceRegistered(obj); + return ! XBMCAddon::Python::PythonLanguageHook::IsAddonClassInstanceRegistered(obj); } } } diff --git a/xbmc/interfaces/python/LanguageHook.cpp b/xbmc/interfaces/python/LanguageHook.cpp index a64096ebed..563beb6ef6 100644 --- a/xbmc/interfaces/python/LanguageHook.cpp +++ b/xbmc/interfaces/python/LanguageHook.cpp @@ -31,75 +31,75 @@ namespace XBMCAddon { namespace Python { - static AddonClass::Ref<LanguageHook> instance; + static AddonClass::Ref<PythonLanguageHook> instance; static CCriticalSection hooksMutex; - static std::map<PyInterpreterState*,AddonClass::Ref<LanguageHook> > hooks; + static std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> > hooks; // vtab instantiation - LanguageHook::~LanguageHook() + PythonLanguageHook::~PythonLanguageHook() { TRACE; XBMCAddon::LanguageHook::deallocating(); } - void LanguageHook::MakePendingCalls() + void PythonLanguageHook::MakePendingCalls() { TRACE; PythonCallbackHandler::makePendingCalls(); } - void LanguageHook::DelayedCallOpen() + void PythonLanguageHook::DelayedCallOpen() { TRACE; PyGILLock::releaseGil(); } - void LanguageHook::DelayedCallClose() + void PythonLanguageHook::DelayedCallClose() { TRACE; PyGILLock::acquireGil(); } - void LanguageHook::RegisterMe() + void PythonLanguageHook::RegisterMe() { TRACE; CSingleLock lock(hooksMutex); - hooks[m_interp] = AddonClass::Ref<LanguageHook>(this); + hooks[m_interp] = AddonClass::Ref<PythonLanguageHook>(this); } - void LanguageHook::UnregisterMe() + void PythonLanguageHook::UnregisterMe() { TRACE; CSingleLock lock(hooksMutex); hooks.erase(m_interp); } - static AddonClass::Ref<XBMCAddon::Python::LanguageHook> g_languageHook; + static AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook> g_languageHook; // Ok ... we're going to get it even if it doesn't exist. If it doesn't exist then // we're going to assume we're not in control of the interpreter. This (apparently) // can be the case. E.g. Libspotify manages to call into a script using a ctypes // extention but under the control of an Interpreter we know nothing about. In // cases like this we're going to use a global interpreter - AddonClass::Ref<LanguageHook> LanguageHook::GetIfExists(PyInterpreterState* interp) + AddonClass::Ref<PythonLanguageHook> PythonLanguageHook::GetIfExists(PyInterpreterState* interp) { TRACE; CSingleLock lock(hooksMutex); - std::map<PyInterpreterState*,AddonClass::Ref<LanguageHook> >::iterator iter = hooks.find(interp); + std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> >::iterator iter = hooks.find(interp); if (iter != hooks.end()) - return AddonClass::Ref<LanguageHook>(iter->second); + return AddonClass::Ref<PythonLanguageHook>(iter->second); // if we got here then we need to use the global one. if (g_languageHook.isNull()) - g_languageHook = new XBMCAddon::Python::LanguageHook(); + g_languageHook = new XBMCAddon::Python::PythonLanguageHook(); return g_languageHook; } - bool LanguageHook::IsAddonClassInstanceRegistered(AddonClass* obj) + bool PythonLanguageHook::IsAddonClassInstanceRegistered(AddonClass* obj) { - for (std::map<PyInterpreterState*,AddonClass::Ref<LanguageHook> >::iterator iter = hooks.begin(); + for (std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> >::iterator iter = hooks.begin(); iter != hooks.end(); ++iter) { if ((iter->second)->HasRegisteredAddonClassInstance(obj)) @@ -120,13 +120,13 @@ namespace XBMCAddon * See PythonCallbackHandler for more details * See PythonCallbackHandler::PythonCallbackHandler for more details */ - XBMCAddon::CallbackHandler* LanguageHook::GetCallbackHandler() + XBMCAddon::CallbackHandler* PythonLanguageHook::GetCallbackHandler() { TRACE; return new PythonCallbackHandler(); } - String LanguageHook::GetAddonId() + String PythonLanguageHook::GetAddonId() { TRACE; const char* id = NULL; @@ -142,7 +142,7 @@ namespace XBMCAddon return id; } - String LanguageHook::GetAddonVersion() + String PythonLanguageHook::GetAddonVersion() { TRACE; // Get a reference to the main module @@ -156,37 +156,37 @@ namespace XBMCAddon return version; } - void LanguageHook::RegisterPlayerCallback(IPlayerCallback* player) { TRACE; g_pythonParser.RegisterPythonPlayerCallBack(player); } - void LanguageHook::UnregisterPlayerCallback(IPlayerCallback* player) { TRACE; g_pythonParser.UnregisterPythonPlayerCallBack(player); } - void LanguageHook::RegisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { TRACE; g_pythonParser.RegisterPythonMonitorCallBack(monitor); } - void LanguageHook::UnregisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { TRACE; g_pythonParser.UnregisterPythonMonitorCallBack(monitor); } + void PythonLanguageHook::RegisterPlayerCallback(IPlayerCallback* player) { TRACE; g_pythonParser.RegisterPythonPlayerCallBack(player); } + void PythonLanguageHook::UnregisterPlayerCallback(IPlayerCallback* player) { TRACE; g_pythonParser.UnregisterPythonPlayerCallBack(player); } + void PythonLanguageHook::RegisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { TRACE; g_pythonParser.RegisterPythonMonitorCallBack(monitor); } + void PythonLanguageHook::UnregisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { TRACE; g_pythonParser.UnregisterPythonMonitorCallBack(monitor); } - bool LanguageHook::WaitForEvent(CEvent& hEvent, unsigned int milliseconds) + bool PythonLanguageHook::WaitForEvent(CEvent& hEvent, unsigned int milliseconds) { TRACE; return g_pythonParser.WaitForEvent(hEvent,milliseconds); } - void LanguageHook::RegisterAddonClassInstance(AddonClass* obj) + void PythonLanguageHook::RegisterAddonClassInstance(AddonClass* obj) { TRACE; - Synchronize l(*this); + CSingleLock l(*this); obj->Acquire(); currentObjects.insert(obj); } - void LanguageHook::UnregisterAddonClassInstance(AddonClass* obj) + void PythonLanguageHook::UnregisterAddonClassInstance(AddonClass* obj) { TRACE; - Synchronize l(*this); + CSingleLock l(*this); if (currentObjects.erase(obj) > 0) obj->Release(); } - bool LanguageHook::HasRegisteredAddonClassInstance(AddonClass* obj) + bool PythonLanguageHook::HasRegisteredAddonClassInstance(AddonClass* obj) { TRACE; - Synchronize l(*this); + CSingleLock l(*this); return currentObjects.find(obj) != currentObjects.end(); } } diff --git a/xbmc/interfaces/python/LanguageHook.h b/xbmc/interfaces/python/LanguageHook.h index f7875c2b0d..263b90edf9 100644 --- a/xbmc/interfaces/python/LanguageHook.h +++ b/xbmc/interfaces/python/LanguageHook.h @@ -43,22 +43,19 @@ namespace XBMCAddon * plugging into the API. It's got a static only implementation * and uses the singleton pattern for access. */ - class LanguageHook : public XBMCAddon::LanguageHook + class PythonLanguageHook : public XBMCAddon::LanguageHook { PyInterpreterState* m_interp; CCriticalSection crit; std::set<AddonClass*> currentObjects; // This constructor is only used to instantiate the global LanguageHook - inline LanguageHook() : - XBMCAddon::LanguageHook("Python::LanguageHook(Global)"), m_interp(NULL) { } + inline PythonLanguageHook() : m_interp(NULL) { } public: - inline LanguageHook(PyInterpreterState* interp) : - XBMCAddon::LanguageHook("Python::LanguageHook"), m_interp(interp) { } - - virtual ~LanguageHook(); + inline PythonLanguageHook(PyInterpreterState* interp) : m_interp(interp) { } + virtual ~PythonLanguageHook(); virtual void DelayedCallOpen(); virtual void DelayedCallClose(); @@ -87,13 +84,13 @@ namespace XBMCAddon virtual void UnregisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor); virtual bool WaitForEvent(CEvent& hEvent, unsigned int milliseconds); - static AddonClass::Ref<LanguageHook> GetIfExists(PyInterpreterState* interp); + static AddonClass::Ref<PythonLanguageHook> GetIfExists(PyInterpreterState* interp); static bool IsAddonClassInstanceRegistered(AddonClass* obj); void RegisterAddonClassInstance(AddonClass* obj); void UnregisterAddonClassInstance(AddonClass* obj); bool HasRegisteredAddonClassInstance(AddonClass* obj); - inline bool HasRegisteredAddonClasses() { Synchronize l(*this); return !currentObjects.empty(); } + inline bool HasRegisteredAddonClasses() { CSingleLock l(*this); return !currentObjects.empty(); } // You should hold the lock on the LanguageHook itself if you're // going to do anything with the set that gets returned. diff --git a/xbmc/interfaces/python/PythonInvoker.cpp b/xbmc/interfaces/python/PythonInvoker.cpp index d42140b484..7b5b04ba06 100644 --- a/xbmc/interfaces/python/PythonInvoker.cpp +++ b/xbmc/interfaces/python/PythonInvoker.cpp @@ -80,10 +80,10 @@ extern "C" CCriticalSection CPythonInvoker::s_critical; -static const CStdString getListOfAddonClassesAsString(XBMCAddon::AddonClass::Ref<XBMCAddon::Python::LanguageHook>& languageHook) +static const CStdString getListOfAddonClassesAsString(XBMCAddon::AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook>& languageHook) { CStdString message; - XBMCAddon::AddonClass::Synchronize l(*(languageHook.get())); + CSingleLock l(*(languageHook.get())); std::set<XBMCAddon::AddonClass*>& acs = languageHook->GetRegisteredAddonClasses(); bool firstTime = true; for (std::set<XBMCAddon::AddonClass*>::iterator iter = acs.begin(); iter != acs.end(); ++iter) @@ -92,7 +92,7 @@ static const CStdString getListOfAddonClassesAsString(XBMCAddon::AddonClass::Ref message += ","; else firstTime = false; - message += (*iter)->GetClassname().c_str(); + message += (*iter)->GetClassname(); } return message; @@ -181,7 +181,7 @@ bool CPythonInvoker::execute(const std::string &script, const std::vector<std::s // swap in my thread state PyThreadState_Swap(state); - XBMCAddon::AddonClass::Ref<XBMCAddon::Python::LanguageHook> languageHook(new XBMCAddon::Python::LanguageHook(state->interp)); + XBMCAddon::AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook> languageHook(new XBMCAddon::Python::PythonLanguageHook(state->interp)); languageHook->RegisterMe(); onInitialization(); diff --git a/xbmc/interfaces/python/PythonSwig.cpp.template b/xbmc/interfaces/python/PythonSwig.cpp.template index 39dc6424af..86cc2083c7 100644 --- a/xbmc/interfaces/python/PythonSwig.cpp.template +++ b/xbmc/interfaces/python/PythonSwig.cpp.template @@ -23,7 +23,6 @@ import Helper import SwigTypeParser import PythonTools -import MethodType import groovy.xml.XmlUtil import groovy.text.SimpleTemplateEngine @@ -34,12 +33,24 @@ import java.util.regex.Pattern * times over, so they are pulled out once here. */ +// --------------------------------------------------------- // initialize the SwigTypeParser with the module's typetables module.findAll( { it.name() == 'typetab' } ).each { SwigTypeParser.appendTypeTable(it) } +// --------------------------------------------------------- -methods = module.depthFirst().findAll { it.name() == 'function' || it.name() == 'constructor' || it.name() == 'destructor' } -classes = module.depthFirst().findAll { it.name() == 'class' } +// --------------------------------------------------------- +// Flatten out all of the method/function nodes, whether inside +// classes or not, into 'methods' +List methods = module.depthFirst().findAll { it.name() == 'function' || it.name() == 'constructor' || it.name() == 'destructor' } +// --------------------------------------------------------- +// --------------------------------------------------------- +// Flatten out all of the class nodes into 'classes' +List classes = module.depthFirst().findAll { it.name() == 'class' } +// --------------------------------------------------------- + +// --------------------------------------------------------- +// Initialize the Helper with the type conversions Helper.setup(this,classes, /** * This is meant to contain mini-templates for converting the return type @@ -61,7 +72,7 @@ Helper.setup(this,classes, (Pattern.compile('''(p.){0,1}std::vector<\\(.*\\)>''')) : new File('typemaps/python.vector.outtm'), (Pattern.compile('''(p.){0,1}Tuple<\\(.*\\)>''')) : new File('typemaps/python.Tuple.outtm'), (Pattern.compile('''(p.){0,1}Alternative<\\(.*\\)>''')) : new File('typemaps/python.Alternative.outtm') - ], '${result} = makePythonInstance(${api},&Py${classname.replaceAll(\'::\',\'_\')}_Type,&Ty${classname.replaceAll(\'::\',\'_\')}_Type,true);', + ], '${result} = makePythonInstance(${api},true);', /** * This is meant to contain mini-templates for converting the parameter types * of the native call to be converted from the python types provided by the caller. @@ -74,6 +85,7 @@ Helper.setup(this,classes, 'String' : 'if (${slarg}) PyXBMCGetUnicodeString(${api},${slarg},false,"${api}","${method.@name}");', (Pattern.compile('''(p.){0,1}std::vector<\\(.*\\)>''')) : new File('typemaps/python.vector.intm'), (Pattern.compile('''(p.){0,1}Tuple(3){0,1}<\\(.*\\)>''')) : new File('typemaps/python.Tuple.intm'), + (Pattern.compile('''(p.){0,1}Alternative<\\(.*\\)>''')) : new File('typemaps/python.Alternative.intm'), // I shouldn't need both of these but my parser doesn't resolve namespaces within // parameter declarations. TODO: Maybe I should fix this. 'r.q(const).Dictionary' : new File('typemaps/python.dict.intm'), @@ -89,10 +101,14 @@ Helper.setup(this,classes, 'double' : '${api} = PyFloat_AsDouble(${slarg});', 'float' : '${api} = (float)PyFloat_AsDouble(${slarg});' ], '${api} = (${swigTypeParser.SwigType_str(ltype)})retrieveApiInstance(${slarg},"${ltype}","${helper.findNamespace(method)}","${helper.callingName(method)}");') +// --------------------------------------------------------- -//println 'this: ' + this.binding.getVariables() - -void doMethod(method, MethodType methodType) +/*******************************************************************************/ +/** + * The doMethod will actually write out the CPython method call for + * the method/function represented by the provided Node ('method'). + */ +void doMethod(Node method, MethodType methodType) { boolean isOperator = method.@name.startsWith("operator ") boolean doAsMappingIndex = false @@ -188,14 +204,14 @@ void doMethod(method, MethodType methodType) } // now do the method call itself if (!destructor) { - if (constructor || !clazz) { %> XBMCAddon::SetLanguageHookGuard slhg(XBMCAddon::Python::LanguageHook::GetIfExists(PyThreadState_Get()->interp).get());<% println() } + if (constructor || !clazz) { %> XBMCAddon::SetLanguageHookGuard slhg(XBMCAddon::Python::PythonLanguageHook::GetIfExists(PyThreadState_Get()->interp).get());<% println() } %> <% if (returns != "void") { %>apiResult = (${SwigTypeParser.SwigType_lstr(returns)})<% } if (clazz && !constructor) { - %>((${clazz}*)retrieveApiInstance((PyObject*)self,&Py${classNameAsVariable}_Type,"${Helper.callingName(method)}","${clazz}"))-> <% + %>((${clazz}*)retrieveApiInstance((PyObject*)self,&Ty${classNameAsVariable}_Type,"${Helper.callingName(method)}","${clazz}"))-> <% } if (constructor && classnode.@feature_director) { - %>(&Py${classNameAsVariable}_Type != pytype) ? new ${classNameAsVariable}_Director(<% params.eachWithIndex { param, i -> %> ${param.@name}${i < params.size() - 1 ? "," : ""} <% } %>) : <% } + %>(&(Ty${classNameAsVariable}_Type.pythonType) != pytype) ? new ${classNameAsVariable}_Director(<% params.eachWithIndex { param, i -> %> ${param.@name}${i < params.size() - 1 ? "," : ""} <% } %>) : <% } // Here is the actual call ... if this is a Director we need to do an upCall (from Python) if (isDirectorCall){ %>${clazz}::<% } @@ -205,7 +221,7 @@ void doMethod(method, MethodType methodType) } // close the 'if method is not a destructor' else { // it is a destructor %> - ${clazz}* theObj = (${clazz}*)retrieveApiInstance((PyObject*)self,&Py${classNameAsVariable}_Type,"~${Helper.callingName(method)}","${clazz}"); + ${clazz}* theObj = (${clazz}*)retrieveApiInstance((PyObject*)self,&Ty${classNameAsVariable}_Type,"~${Helper.callingName(method)}","${clazz}"); cleanForDealloc(theObj); <% } @@ -242,13 +258,13 @@ void doMethod(method, MethodType methodType) // transform the result <% if (constructor) { - %> result = makePythonInstance(apiResult,pytype,&Ty${SwigTypeParser.getRootType(returns).replaceAll('::','_')}_Type,false);<% + %> result = makePythonInstance(apiResult,pytype,false);<% } else { %> ${Helper.getOutConversion(returns,'result',method)}<% } if (constructor && method.@feature_director) { %> - if (&Py${classNameAsVariable}_Type != pytype) + if (&(Ty${classNameAsVariable}_Type.pythonType) != pytype) ((${classNameAsVariable}_Director*)apiResult)->setPyObjectForDirector(result);<% } %> @@ -261,7 +277,15 @@ void doMethod(method, MethodType methodType) %> } <% } +/*******************************************************************************/ +/** + * This method writes out the instance of a TypeInfo (which includes + * The PyTypeObject as a member) for the class node provided. + * + * If classNameAsVariable is not null then the class name as a + * variable will be appended to it. + */ void doClassTypeInfo(Node clazz, List classNameAsVariables = null) { String classNameAsVariable = PythonTools.getClassNameAsVariable(clazz) @@ -270,32 +294,49 @@ void doClassTypeInfo(Node clazz, List classNameAsVariables = null) %> //========================================================================= // These variables will hold the Python Type information for ${fullClassName} - PyTypeObject Py${classNameAsVariable}_Type; - TypeInfo Ty${classNameAsVariable}_Type;<% - - Node baseclass = PythonTools.findValidBaseClass(clazz, module) - if (baseclass) - {%> - TypeConverter<${Helper.findFullClassName(baseclass)},${fullClassName}> ${classNameAsVariable}_ParentConverter;<% - } + TypeInfo Ty${classNameAsVariable}_Type(typeid(${fullClassName}));<% %> //========================================================================= <% } +/** + * This method will take the name of an API class from another module and + * create an external reference to its TypeInfo instance. + */ void doExternClassTypeInfo(String knownType) { String classNameAsVariable = knownType.replaceAll('::','_') %> //========================================================================= // These variables define the type ${knownType} from another module - extern PyTypeObject Py${classNameAsVariable}_Type; extern TypeInfo Ty${classNameAsVariable}_Type; //========================================================================= <% } -void doClassMethodInfo(Node clazz, List initTypeCalls = null) +/*******************************************************************************/ +/** + * This method takes the class node and outputs all of the python meta-data + * and class oddities (like comparators, as_mapping, etc.). These include: + * + * 1) comparator *_cmp python method as long as there's an operator==, an + * operator>, AND an operator<. + * 2) it will create a python "as_mapping" method as long as there's both + * an operator[], AND a .size() method on the class. + * 3) it will handle the explicitly defined rich compare (_rcmp) if the + * feature is included in the .i file using %feature("python:rcmp") + * 4) The array of PyMethodDefs for the class definition + * 5) It will handle public fields as if the were python properties by: + * a) Creating a get/set_member if there are read/write properties. + * b) Creating only a get if there are only read-only properties. + * 6) It will write the init[Classname] method for the class which will + * initialize the TypeInfo and PyTypeObject structs. + * + * If initTypeCalls is not null then the method name for the generated init + * method (see #6 above) will be appended to it. + */ +void doClassMethodInfo(Node clazz, List initTypeCalls) { String classNameAsVariable = PythonTools.getClassNameAsVariable(clazz) String fullClassName = Helper.findFullClassName(clazz) @@ -361,7 +402,7 @@ void doClassMethodInfo(Node clazz, List initTypeCalls = null) %> static Py_ssize_t ${module.@name}_${classNameAsVariable}_size_(PyObject* self) { - return (Py_ssize_t)((${fullClassName}*)retrieveApiInstance(self,&Py${classNameAsVariable}_Type,"${Helper.callingName(indexOp)}","${fullClassName}"))-> size(); + return (Py_ssize_t)((${fullClassName}*)retrieveApiInstance(self,&Ty${classNameAsVariable}_Type,"${Helper.callingName(indexOp)}","${fullClassName}"))-> size(); } //========================================================================= @@ -416,7 +457,7 @@ void doClassMethodInfo(Node clazz, List initTypeCalls = null) %> try { - ${clazzName}* theObj = (${clazzName}*)retrieveApiInstance((PyObject*)self, &Py${classNameAsVariable}_Type, "${classNameAsVariable}_getMember()", "${clazzName}"); + ${clazzName}* theObj = (${clazzName}*)retrieveApiInstance((PyObject*)self, &Ty${classNameAsVariable}_Type, "${classNameAsVariable}_getMember()", "${clazzName}"); PyObject* result = NULL; <% @@ -467,7 +508,7 @@ void doClassMethodInfo(Node clazz, List initTypeCalls = null) ${clazzName}* theObj = NULL; try { - theObj = (${clazzName}*)retrieveApiInstance((PyObject*)self, &Py${classNameAsVariable}_Type, "${classNameAsVariable}_getMember()", "${clazzName}"); + theObj = (${clazzName}*)retrieveApiInstance((PyObject*)self, &Ty${classNameAsVariable}_Type, "${classNameAsVariable}_getMember()", "${clazzName}"); } catch (const XBMCAddon::WrongTypeException& e) { @@ -529,42 +570,48 @@ void doClassMethodInfo(Node clazz, List initTypeCalls = null) ${PythonTools.makeDocString(clazz.doc[0])} ); <% } %> - PyXBMCInitializeTypeObject(&Py${classNameAsVariable}_Type,&Ty${classNameAsVariable}_Type); - Py${classNameAsVariable}_Type.tp_name = (char*)"${module.@name}.${clazz.@sym_name}"; - Py${classNameAsVariable}_Type.tp_basicsize = sizeof(PyHolder); - Py${classNameAsVariable}_Type.tp_dealloc = (destructor)${module.@name}_${classNameAsVariable}_Dealloc; <% + PyTypeObject& pythonType = Ty${classNameAsVariable}_Type.pythonType; + pythonType.tp_name = (char*)"${module.@name}.${clazz.@sym_name}"; + pythonType.tp_basicsize = sizeof(PyHolder); + pythonType.tp_dealloc = (destructor)${module.@name}_${classNameAsVariable}_Dealloc; <% if (doComparator) { %> - Py${classNameAsVariable}_Type.tp_compare=${module.@name}_${classNameAsVariable}_cmp;<% + pythonType.tp_compare=${module.@name}_${classNameAsVariable}_cmp;<% } if (clazz.@feature_python_rcmp) { %> - Py${classNameAsVariable}_Type.tp_richcompare=(richcmpfunc)${module.@name}_${classNameAsVariable}_rcmp;<% + pythonType.tp_richcompare=(richcmpfunc)${module.@name}_${classNameAsVariable}_rcmp;<% } %> - Py${classNameAsVariable}_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - Py${classNameAsVariable}_Type.tp_doc = ${Helper.hasDoc(clazz) ? (classNameAsVariable + '__doc__') : 'NULL' }; - Py${classNameAsVariable}_Type.tp_methods = ${classNameAsVariable}_methods; <% + pythonType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + pythonType.tp_doc = ${Helper.hasDoc(clazz) ? (classNameAsVariable + '__doc__') : 'NULL' }; + pythonType.tp_methods = ${classNameAsVariable}_methods; <% if (properties.size() > 0) { %> - Py${classNameAsVariable}_Type.tp_getset = ${classNameAsVariable}_getsets; + pythonType.tp_getset = ${classNameAsVariable}_getsets; <% } if (doAsMapping) { %> - Py${classNameAsVariable}_Type.tp_as_mapping = &${module.@name}_${classNameAsVariable}_as_mapping; + pythonType.tp_as_mapping = &${module.@name}_${classNameAsVariable}_as_mapping; <% } Node baseclass = PythonTools.findValidBaseClass(clazz, module) -%> Py${classNameAsVariable}_Type.tp_base = ${baseclass ? ('&Py' + PythonTools.getClassNameAsVariable(baseclass) + '_Type') : "NULL"}; - Py${classNameAsVariable}_Type.tp_new = <% Helper.hasHiddenConstructor(clazz) ? print('NULL') : print("${module.@name}_${classNameAsVariable}_New") %>; +%> + pythonType.tp_base = ${baseclass ? ('&(Ty' + PythonTools.getClassNameAsVariable(baseclass) + '_Type.pythonType)') : "NULL"}; + pythonType.tp_new = <% Helper.hasHiddenConstructor(clazz) ? print('NULL') : print("${module.@name}_${classNameAsVariable}_New") %>; Ty${classNameAsVariable}_Type.swigType="p.${fullClassName}";<% if (baseclass) { %> Ty${classNameAsVariable}_Type.parentType=&Ty${PythonTools.getClassNameAsVariable(baseclass)}_Type; - Ty${classNameAsVariable}_Type.converter=&${classNameAsVariable}_ParentConverter; -<%} %> +<%} + + if (!Helper.hasHiddenConstructor(clazz)) { %> + registerAddonClassTypeInformation(&Ty${classNameAsVariable}_Type); +<%} %> } //========================================================================= <% } +/*******************************************************************************/ + List getAllVirtualMethods(Node clazz) { @@ -624,6 +671,7 @@ Helper.getInsertNodes(module, 'header').each { %>${Helper.unescape(it)}<% } namespace PythonBindings { <% + // initTypeCalls is the List initTypeCalls = [] List classNameAsVariables = [] @@ -649,7 +697,9 @@ namespace PythonBindings <% //========================================================================= -// Do the directors +// Do the directors. For every class that can be extended in python, we +// need to create a Director instance with bridging calls. This chunk of +// code will generate those classes. classes.findAll({ it.@feature_director != null }).each { clazz -> // find the constructor for this class constructor = clazz.constructor[0] @@ -750,7 +800,7 @@ namespace PythonBindings } classNameAsVariables.each { %> - if (PyType_Ready(&Py${it}_Type) < 0) + if (PyType_Ready(&(Ty${it}_Type.pythonType)) < 0) return;<% }%> } @@ -764,14 +814,14 @@ namespace PythonBindings PyObject* module; <% classNameAsVariables.each { %> - Py_INCREF(&Py${it}_Type);<% + Py_INCREF(&(Ty${it}_Type.pythonType));<% }%> module = Py_InitModule((char*)"${module.@name}", ${module.@name}_methods); if (module == NULL) return; <% classes.each { clazz -> %> - PyModule_AddObject(module, (char*)"${clazz.@sym_name}", (PyObject*)&Py${PythonTools.getClassNameAsVariable(clazz)}_Type);<% + PyModule_AddObject(module, (char*)"${clazz.@sym_name}", (PyObject*)(&(Ty${PythonTools.getClassNameAsVariable(clazz)}_Type.pythonType)));<% }%> // constants diff --git a/xbmc/interfaces/python/swig.cpp b/xbmc/interfaces/python/swig.cpp index f95dee3d54..7b1a302fd4 100644 --- a/xbmc/interfaces/python/swig.cpp +++ b/xbmc/interfaces/python/swig.cpp @@ -25,13 +25,11 @@ namespace PythonBindings { - void PyXBMCInitializeTypeObject(PyTypeObject* type_object, TypeInfo* typeInfo) + TypeInfo::TypeInfo(const std::type_info& ti) : swigType(NULL), parentType(NULL), typeIndex(ti) { static PyTypeObject py_type_object_header = { PyObject_HEAD_INIT(NULL) 0}; - int size = (long*)&(py_type_object_header.tp_name) - (long*)&py_type_object_header; - memset(type_object, 0, sizeof(PyTypeObject)); - memcpy(type_object, &py_type_object_header, size); - memset(typeInfo, 0, sizeof(TypeInfo)); + static int size = (long*)&(py_type_object_header.tp_name) - (long*)&py_type_object_header; + memcpy(&(this->pythonType), &py_type_object_header, size); } class PyObjectDecrementor @@ -199,7 +197,7 @@ namespace PythonBindings SetMessage("%s",msg.c_str()); } - void* doretrieveApiInstance(const PyHolder* pythonType, const TypeInfo* typeInfo, const char* expectedType, + XBMCAddon::AddonClass* doretrieveApiInstance(const PyHolder* pythonType, const TypeInfo* typeInfo, const char* expectedType, const char* methodNamespacePrefix, const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException) { if (pythonType == NULL || pythonType->magicNumber != XBMC_PYTHON_TYPE_MAGIC_NUMBER) @@ -228,7 +226,7 @@ namespace PythonBindings if(c) { c->Acquire(); PyThreadState* state = PyThreadState_Get(); - XBMCAddon::Python::LanguageHook::GetIfExists(state->interp)->RegisterAddonClassInstance(c); + XBMCAddon::Python::PythonLanguageHook::GetIfExists(state->interp)->RegisterAddonClassInstance(c); } } @@ -236,7 +234,7 @@ namespace PythonBindings { TRACE; if(c){ - XBMCAddon::AddonClass::Ref<XBMCAddon::Python::LanguageHook> lh = + XBMCAddon::AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook> lh = XBMCAddon::AddonClass::Ref<XBMCAddon::AddonClass>(c->GetLanguageHook()); if (lh.isNotNull()) @@ -247,7 +245,7 @@ namespace PythonBindings else { PyThreadState* state = PyThreadState_Get(); - lh = XBMCAddon::Python::LanguageHook::GetIfExists(state->interp); + lh = XBMCAddon::Python::PythonLanguageHook::GetIfExists(state->interp); if (lh.isNotNull()) lh->UnregisterAddonClassInstance(c); return true; } @@ -285,12 +283,18 @@ namespace PythonBindings } /** - * This method allows for conversion of the native api Type to the Python type + * This method allows for conversion of the native api Type to the Python type. * - * NOTE: swigTypeString must be in the data segment. That is, it should be an explicit string since - * the const char* is stored in a PyHolder struct and never deleted. + * When this form of the call is used (and pytype isn't NULL) then the + * passed type is used in the instance. This is for classes that extend API + * classes in python. The type passed may not be the same type that's stored + * in the class metadata of the AddonClass of which 'api' is an instance, + * it can be a subclass in python. + * + * if pytype is NULL then the type is inferred using the class metadata + * stored in the AddonClass instance 'api'. */ - PyObject* makePythonInstance(void* api, PyTypeObject* typeObj, TypeInfo* typeInfo, bool incrementRefCount) + PyObject* makePythonInstance(XBMCAddon::AddonClass* api, PyTypeObject* pytype, bool incrementRefCount) { // null api types result in Py_None if (!api) @@ -299,6 +303,10 @@ namespace PythonBindings return Py_None; } + // retrieve the TypeInfo from the api class + const TypeInfo* typeInfo = getTypeInfoForInstance(api); + PyTypeObject* typeObj = pytype == NULL ? (PyTypeObject*)(&(typeInfo->pythonType)) : pytype; + PyHolder* self = (PyHolder*)typeObj->tp_alloc(typeObj,0); if (!self) return NULL; self->magicNumber = XBMC_PYTHON_TYPE_MAGIC_NUMBER; @@ -309,5 +317,18 @@ namespace PythonBindings return (PyObject*)self; } + std::map<XbmcCommons::type_index, const TypeInfo*> typeInfoLookup; + + void registerAddonClassTypeInformation(const TypeInfo* classInfo) + { + typeInfoLookup[classInfo->typeIndex] = classInfo; + } + + const TypeInfo* getTypeInfoForInstance(XBMCAddon::AddonClass* obj) + { + XbmcCommons::type_index ti(typeid(*obj)); + return typeInfoLookup[ti]; + } + } diff --git a/xbmc/interfaces/python/swig.h b/xbmc/interfaces/python/swig.h index 2a795c6ad8..8c0fbfa8c2 100644 --- a/xbmc/interfaces/python/swig.h +++ b/xbmc/interfaces/python/swig.h @@ -18,6 +18,8 @@ * */ +#pragma once + #include <Python.h> #include <string> #include <stdint.h> @@ -27,31 +29,22 @@ #include "interfaces/legacy/AddonClass.h" #include "interfaces/legacy/Window.h" +#include "commons/typeindex.h" + namespace PythonBindings { void PyXBMCGetUnicodeString(std::string& buf, PyObject* pObject, bool coerceToString = false, const char* pos = "unknown", const char* methodname = "unknown") throw (XBMCAddon::WrongTypeException); - // This is for casting from child class to base class - struct TypeConverterBase - { - virtual void* convert(void* from) = 0; - }; - - /** - * Template to allow the instantiation of a particular type conversion - */ - template<class T, class F> struct TypeConverter : public TypeConverterBase - { - inline virtual void* convert(void* from) { return static_cast<T*>((F*)from); } - }; - struct TypeInfo { const char* swigType; TypeInfo* parentType; - TypeConverterBase* converter; + PyTypeObject pythonType; + const XbmcCommons::type_index typeIndex; + + TypeInfo(const std::type_info& ti); }; // This will hold the pointer to the api type, whether known or unknown @@ -60,42 +53,40 @@ namespace PythonBindings PyObject_HEAD int32_t magicNumber; const TypeInfo* typeInfo; - void* pSelf; + XBMCAddon::AddonClass* pSelf; }; #define XBMC_PYTHON_TYPE_MAGIC_NUMBER 0x58626D63 - void PyXBMCInitializeTypeObject(PyTypeObject* type_object, TypeInfo* typeInfo); - /** * This method retrieves the pointer from the PyHolder. The return value should - * be case to the appropriate type. + * be cast to the appropriate type. * * Since the calls to this are generated there's no NULL pointer checks */ - inline void* retrieveApiInstance(PyObject* pythonType, PyTypeObject* typeToCheck, + inline XBMCAddon::AddonClass* retrieveApiInstance(PyObject* pythonType, const TypeInfo* typeToCheck, const char* methodNameForErrorString, const char* typenameForErrorString) throw (XBMCAddon::WrongTypeException) { if (pythonType == NULL || ((PyHolder*)pythonType)->magicNumber != XBMC_PYTHON_TYPE_MAGIC_NUMBER) return NULL; - if (!PyObject_TypeCheck(pythonType, typeToCheck)) + if (!PyObject_TypeCheck(pythonType, (PyTypeObject*)(&(typeToCheck->pythonType)))) throw XBMCAddon::WrongTypeException("Incorrect type passed to \"%s\", was expecting a \"%s\".",methodNameForErrorString,typenameForErrorString); return ((PyHolder*)pythonType)->pSelf; } bool isParameterRightType(const char* passedType, const char* expectedType, const char* methodNamespacePrefix, bool tryReverse = true); - void* doretrieveApiInstance(const PyHolder* pythonType, const TypeInfo* typeInfo, const char* expectedType, + XBMCAddon::AddonClass* doretrieveApiInstance(const PyHolder* pythonType, const TypeInfo* typeInfo, const char* expectedType, const char* methodNamespacePrefix, const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException); /** * This method retrieves the pointer from the PyHolder. The return value should - * be case to the appropriate type. + * be cast to the appropriate type. * * Since the calls to this are generated there's no NULL pointer checks */ - inline void* retrieveApiInstance(const PyObject* pythonType, const char* expectedType, const char* methodNamespacePrefix, + inline XBMCAddon::AddonClass* retrieveApiInstance(const PyObject* pythonType, const char* expectedType, const char* methodNamespacePrefix, const char* methodNameForErrorString) throw (XBMCAddon::WrongTypeException) { return (pythonType == NULL) ? NULL : @@ -125,12 +116,35 @@ namespace PythonBindings void cleanForDealloc(XBMCAddon::xbmcgui::Window* c); /** - * This method allows for conversion of the native api Type to the Python type + * This method allows for conversion of the native api Type to the Python type. + * + * When this form of the call is used (and pythonType isn't NULL) then the + * passed type is used in the instance. This is for classes that extend API + * classes in python. The type passed may not be the same type that's stored + * in the class metadata of the AddonClass of which 'api' is an instance, + * it can be a subclass in python. + * + * if pythonType is NULL then the type is inferred using the class metadata + * stored in the AddonClass instance 'api'. + */ + PyObject* makePythonInstance(XBMCAddon::AddonClass* api, PyTypeObject* pythonType, bool incrementRefCount); + + /** + * This method allows for conversion of the native api Type to the Python type. + * + * When this form of the call is used then the python type constructed will be the + * type given by the class metadata in the AddonClass instance 'api'. * - * NOTE: swigTypeString must be in the data segment. That is, it should be an explicit string since - * the const char* is stored in a PyHolder struct and never deleted. + * This is just a helper inline to call the other makePythonInstance with NULL as + * the pythonType. */ - PyObject* makePythonInstance(void* api, PyTypeObject* typeObj, TypeInfo* typeInfo, bool incrementRefCount); + inline PyObject* makePythonInstance(XBMCAddon::AddonClass* api, bool incrementRefCount) + { + return makePythonInstance(api,NULL,incrementRefCount); + } + + void registerAddonClassTypeInformation(const TypeInfo* classInfo); + const TypeInfo* getTypeInfoForInstance(XBMCAddon::AddonClass* obj); class Director { diff --git a/xbmc/interfaces/python/typemaps/python.Alternative.intm b/xbmc/interfaces/python/typemaps/python.Alternative.intm new file mode 100644 index 0000000000..0a3c34a101 --- /dev/null +++ b/xbmc/interfaces/python/typemaps/python.Alternative.intm @@ -0,0 +1,68 @@ +<% +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +%> +<% + type = swigTypeParser.SwigType_resolve_all_typedefs(type) + matcher = type =~ /Alternative<\((.*)\)>/ + vectype = '(' + matcher[0][1] + ')' + boolean ispointer = swigTypeParser.SwigType_ispointer(type) + String accessor = ispointer ? '->' : '.' + int seq = sequence.increment() + altAccess = [ 'former', 'later' ] + altSwitch = [ 'first', 'second' ] + + List types = swigTypeParser.SwigType_parmlist(vectype) +%> + { + // we need to check the parameter type and see if it matches + PyObject *pyentry_${seq} = ${slarg}; + try + { + ${swigTypeParser.SwigType_str(swigTypeParser.SwigType_ltype(types[0]))} entry0_${seq}; + ${helper.getInConversion(types[0], 'entry0' + '_' + seq, 'pyentry' + '_' + seq, method, + [ 'type' : vectype, + 'ltype' : swigTypeParser.SwigType_ltype(types[0]), + 'sequence' : sequence + ])} + ${api}${accessor}${altAccess[0]}() = entry0_${seq}; + } + catch (XBMCAddon::WrongTypeException wte) + { + try + { + ${swigTypeParser.SwigType_str(swigTypeParser.SwigType_ltype(types[1]))} entry1_${seq}; + ${helper.getInConversion(types[1], 'entry1' + '_' + seq, 'pyentry' + '_' + seq, method, + [ 'type' : vectype, + 'ltype' : swigTypeParser.SwigType_ltype(types[1]), + 'sequence' : sequence + ])} + ${api}${accessor}${altAccess[1]}() = entry1_${seq}; + } + catch (XBMCAddon::WrongTypeException wte2) + { + throw XBMCAddon::WrongTypeException("Failed to convert to input type to either a " + "${swigTypeParser.SwigType_ltype(types[0])} or a " + "${swigTypeParser.SwigType_ltype(types[1])}" ); + } + } + } + + diff --git a/xbmc/interfaces/swig/AddonModuleXbmc.i b/xbmc/interfaces/swig/AddonModuleXbmc.i index dd8cfc327a..7a0e27f3c2 100644 --- a/xbmc/interfaces/swig/AddonModuleXbmc.i +++ b/xbmc/interfaces/swig/AddonModuleXbmc.i @@ -48,65 +48,6 @@ using namespace xbmc; %feature("director") Player; -%feature("python:method:play") Player -{ - TRACE; - PyObject *pObject = NULL; - PyObject *pObjectListItem = NULL; - char bWindowed = false; - static const char *keywords[] = { "item", "listitem", "windowed", NULL }; - - if (!PyArg_ParseTupleAndKeywords( - args, - kwds, - (char*)"|OOb", - (char**)keywords, - &pObject, - &pObjectListItem, - &bWindowed)) - { - return NULL; - } - - try - { - Player* player = ((Player*)retrieveApiInstance((PyObject*)self,&PyXBMCAddon_xbmc_Player_Type,"play","XBMCAddon::xbmc::Player")); - - // set fullscreen or windowed - bool windowed = (0 != bWindowed); - - if (pObject == NULL) - player->playCurrent(windowed); - else if ((PyString_Check(pObject) || PyUnicode_Check(pObject))) - { - CStdString item; - PyXBMCGetUnicodeString(item,pObject,"item","Player::play"); - XBMCAddon::xbmcgui::ListItem* pListItem = - (pObjectListItem ? - (XBMCAddon::xbmcgui::ListItem *)retrieveApiInstance(pObjectListItem,"p.XBMCAddon::xbmcgui::ListItem","XBMCAddon::xbmc::","play") : - NULL); - player->playStream(item,pListItem,windowed); - } - else // pObject must be a playlist - player->playPlaylist((PlayList *)retrieveApiInstance(pObject,"p.XBMCAddon::xbmc::PlayList","XBMCAddon::xbmc::","play"), windowed); - } - catch (const XbmcCommons::Exception& e) - { - CLog::Log(LOGERROR,"Leaving Python method 'XBMCAddon_xbmc_Player_play'. Exception from call to 'play' '%s' ... returning NULL", e.GetMessage()); - PyErr_SetString(PyExc_RuntimeError, e.GetMessage()); - return NULL; - } - catch (...) - { - CLog::Log(LOGERROR,"Unknown exception thrown from the call 'play'"); - PyErr_SetString(PyExc_RuntimeError, "Unknown exception thrown from the call 'play'"); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; - } - %feature("python:nokwds") XBMCAddon::xbmc::Keyboard::Keyboard "true" %feature("python:nokwds") XBMCAddon::xbmc::Player::Player "true" %feature("python:nokwds") XBMCAddon::xbmc::PlayList::PlayList "true" diff --git a/xbmc/interfaces/swig/AddonModuleXbmcgui.i b/xbmc/interfaces/swig/AddonModuleXbmcgui.i index 305ebc81b1..52eeddfb10 100644 --- a/xbmc/interfaces/swig/AddonModuleXbmcgui.i +++ b/xbmc/interfaces/swig/AddonModuleXbmcgui.i @@ -51,7 +51,6 @@ using namespace xbmcgui; %include "interfaces/legacy/ListItem.h" -%include "ControlListAddItemMethods.i" %feature("python:coerceToUnicode") XBMCAddon::xbmcgui::ControlButton::getLabel "true" %feature("python:coerceToUnicode") XBMCAddon::xbmcgui::ControlButton::getLabel2 "true" %include "interfaces/legacy/Control.h" @@ -74,11 +73,11 @@ using namespace xbmcgui; { TRACE; if (method == Py_EQ) { - XBMCAddon::xbmcgui::Action* a1 = (Action*)retrieveApiInstance(obj1,&PyXBMCAddon_xbmcgui_Action_Type,"rcmp","XBMCAddon::xbmcgui::Action"); - if (PyObject_TypeCheck(obj2, &PyXBMCAddon_xbmcgui_Action_Type)) + XBMCAddon::xbmcgui::Action* a1 = (Action*)retrieveApiInstance(obj1,&TyXBMCAddon_xbmcgui_Action_Type,"rcmp","XBMCAddon::xbmcgui::Action"); + if (PyObject_TypeCheck(obj2, &(TyXBMCAddon_xbmcgui_Action_Type.pythonType))) { // both are Action objects - XBMCAddon::xbmcgui::Action* a2 = (Action*)retrieveApiInstance(obj2,&PyXBMCAddon_xbmcgui_Action_Type,"rcmp","XBMCAddon::xbmcgui::Action"); + XBMCAddon::xbmcgui::Action* a2 = (Action*)retrieveApiInstance(obj2,&TyXBMCAddon_xbmcgui_Action_Type,"rcmp","XBMCAddon::xbmcgui::Action"); if (a1->id == a2->id && a1->buttonCode == a2->buttonCode && @@ -110,70 +109,6 @@ using namespace xbmcgui; %include "interfaces/legacy/WindowDialog.h" %include "interfaces/legacy/Dialog.h" -%rename ("addItemString") XBMCAddon::xbmcgui::WindowXML::addItem; -%feature("python:method:addItem") XBMCAddon::xbmcgui::WindowXML -{ - TRACE; - - static const char *keywords[] = { - "item", - NULL}; - - String item; - PyObject* pyitem = NULL; - if (!PyArg_ParseTupleAndKeywords( - args, - kwds, - (char*)"O", - (char**)keywords, - &pyitem - )) - return NULL; - - const char* callName = "addItem"; - try - { - XBMCAddon::xbmcgui::WindowXML* apiobj = ((XBMCAddon::xbmcgui::WindowXML*)retrieveApiInstance((PyObject*)self, - &PyXBMCAddon_xbmcgui_WindowXML_Type,"addItem","XBMCAddon::xbmcgui::WindowXML")); - - if (PyUnicode_Check(pyitem) || PyString_Check(pyitem)) - { - callName = "addItemString"; - PyXBMCGetUnicodeString(item,pyitem,false,"item","addItem"); - apiobj->addItem(item); - } - else - { - callName = "addListItem"; - // assume it's a ListItem. retrieveApiInstance will throw an exception if it's not - XBMCAddon::xbmcgui::ListItem* listItem = ((XBMCAddon::xbmcgui::ListItem*)retrieveApiInstance((PyObject*)pyitem, - &PyXBMCAddon_xbmcgui_ListItem_Type,"addItem","XBMCAddon::xbmcgui::ListItem")); - apiobj->addListItem(listItem); - } - } - catch (const XbmcCommons::Exception& e) - { - CLog::Log(LOGERROR,"EXCEPTION: from call to '%s' '%s' ... returning NULL", callName,e.GetMessage()); - PyErr_SetString(PyExc_RuntimeError, e.GetMessage()); - return NULL; - } - catch (...) - { - CLog::Log(LOGERROR,"EXCEPTION: Unknown exception thrown from the call '%s'",callName); - PyErr_SetString(PyExc_RuntimeError, "Unknown exception thrown from the call 'addItem'"); - return NULL; - } - - PyObject* result; - - // transform the result - Py_INCREF(Py_None); - result = Py_None; - - return result; -} - - %include "interfaces/legacy/WindowXML.h" %include "guilib/Key.h" diff --git a/xbmc/interfaces/swig/AddonModuleXbmcvfs.i b/xbmc/interfaces/swig/AddonModuleXbmcvfs.i index 92d8709bbe..ac09158cf1 100644 --- a/xbmc/interfaces/swig/AddonModuleXbmcvfs.i +++ b/xbmc/interfaces/swig/AddonModuleXbmcvfs.i @@ -35,6 +35,8 @@ using namespace xbmcvfs; %} +%include "interfaces/legacy/swighelper.h" + %include "interfaces/legacy/File.h" %rename ("st_atime") XBMCAddon::xbmcvfs::Stat::atime; diff --git a/xbmc/interfaces/swig/ControlListAddItemMethods.i b/xbmc/interfaces/swig/ControlListAddItemMethods.i deleted file mode 100644 index c13b749be8..0000000000 --- a/xbmc/interfaces/swig/ControlListAddItemMethods.i +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -/** - * This file contains the two python methods, addItem and addItems for controls - */ -#pragma once - -%feature("python:method:addItem") Control -{ - TRACE; - - static const char *keywords[] = { - "item", - NULL}; - - String item; - PyObject* pyitem = NULL; - if (!PyArg_ParseTupleAndKeywords( - args, - kwds, - (char*)"O", - (char**)keywords, - &pyitem - )) - return NULL; - - const char* callName = "addItem"; - try - { - XBMCAddon::xbmcgui::Control* tmp = ((XBMCAddon::xbmcgui::Control*)retrieveApiInstance((PyObject*)self, - &PyXBMCAddon_xbmcgui_Control_Type,"addItem","XBMCAddon::xbmcgui::Control")); - - XBMCAddon::xbmcgui::ControlList* apiobj = dynamic_cast<XBMCAddon::xbmcgui::ControlList*>(tmp); - - if (apiobj == NULL) - throw WrongTypeException("Incorrect type passed to '%s', was expecting a '%s'.",callName,"XBMCAddon::xbmcgui::Control"); - - - if (PyUnicode_Check(pyitem) || PyString_Check(pyitem)) - { - callName = "addItemStream"; - PyXBMCGetUnicodeString(item,pyitem,false,"item","addItem"); - apiobj->addItemStream(item); - } - else - { - callName = "addListItem"; - // assume it's a ListItem. retrieveApiInstance will throw an exception if it's not - XBMCAddon::xbmcgui::ListItem* listItem = ((XBMCAddon::xbmcgui::ListItem*)retrieveApiInstance((PyObject*)pyitem, - &PyXBMCAddon_xbmcgui_ListItem_Type,"addItem","XBMCAddon::xbmcgui::ListItem")); - apiobj->addListItem(listItem); - } - } - catch (const XbmcCommons::Exception& e) - { - CLog::Log(LOGERROR,"EXCEPTION: from call to '%s' '%s' ... returning NULL", callName,e.GetMessage()); - PyErr_SetString(PyExc_RuntimeError, e.GetMessage()); - return NULL; - } - catch (...) - { - CLog::Log(LOGERROR,"EXCEPTION: Unknown exception thrown from the call '%s'",callName); - PyErr_SetString(PyExc_RuntimeError, "Unknown exception thrown from the call 'addItem'"); - return NULL; - } - - PyObject* result; - - // transform the result - Py_INCREF(Py_None); - result = Py_None; - - return result; -} - -%feature("python:method:addItems") Control -{ - TRACE; - - static const char *keywords[] = { - "items", - NULL}; - - String items; - PyObject* pyitems = NULL; - if (!PyArg_ParseTupleAndKeywords( - args, - kwds, - (char*)"O", - (char**)keywords, - &pyitems - )) - return NULL; - - const char* callName = "addItems"; - try - { - XBMCAddon::xbmcgui::Control* tmp = ((XBMCAddon::xbmcgui::Control*)retrieveApiInstance((PyObject*)self, - &PyXBMCAddon_xbmcgui_Control_Type,"addItem","XBMCAddon::xbmcgui::Control")); - - XBMCAddon::xbmcgui::ControlList* apiobj = dynamic_cast<XBMCAddon::xbmcgui::ControlList*>(tmp); - - if (apiobj == NULL) - throw WrongTypeException("Incorrect type passed to '%s', was expecting a '%s'.",callName,"XBMCAddon::xbmcgui::Control"); - - CGUIListItemPtr items(new CFileItemList()); - int listSize = PyList_Size(pyitems); - for (int index = 0; index < listSize; index++) - { - PyObject *pyitem = PyList_GetItem(pyitems, index); - - if (PyUnicode_Check(pyitem) || PyString_Check(pyitem)) - { - callName = "addItemStream"; - String item; - PyXBMCGetUnicodeString(item,pyitem,false,"item","addItem"); - apiobj->addItemStream(item,false); - } - else - { - callName = "addListItem"; - // assume it's a ListItem. retrieveApiInstance will throw an exception if it's not - XBMCAddon::xbmcgui::ListItem* listItem = ((XBMCAddon::xbmcgui::ListItem*)retrieveApiInstance((PyObject*)pyitem, - &PyXBMCAddon_xbmcgui_ListItem_Type,"addItem","XBMCAddon::xbmcgui::ListItem")); - apiobj->addListItem(listItem,false); - } - } - - apiobj->sendLabelBind(listSize); - } - catch (const XbmcCommons::Exception& e) - { - CLog::Log(LOGERROR,"EXCEPTION: from call to '%s' '%s' ... returning NULL", callName,e.GetMessage()); - PyErr_SetString(PyExc_RuntimeError, e.GetMessage()); - return NULL; - } - catch (...) - { - CLog::Log(LOGERROR,"EXCEPTION: Unknown exception thrown from the call '%s'",callName); - PyErr_SetString(PyExc_RuntimeError, "Unknown exception thrown from the call 'addItem'"); - return NULL; - } - - PyObject* result; - - // transform the result - Py_INCREF(Py_None); - result = Py_None; - - return result; -} - |