The codegenerator now handles dynamic typing (that SWIG alone could never to) by...
authorJim Carroll <thecarrolls@jiminger.com>
Fri, 18 Oct 2013 01:24:02 +0000 (21:24 -0400)
committerJim Carroll <thecarrolls@jiminger.com>
Mon, 21 Oct 2013 13:20:11 +0000 (09:20 -0400)
Removed all of the extraneous methods at the parent level to handle the dynamic language concerns of returning a Control rather than a specific type.

Added more documentation and removed some things that were only visible for reasons no longer viable.

Hide show/close from python in WindowDialog since they are inherited from Window.

Also added a simplistic hack for handling dynamically typed parameters to methods using an Alternative<T1,T2> template. The only better step would be full support of overridden methods. This allows the removal all of the explicit python code in the *.i files (with the exception of the rich compare _rcmp on the Action class).

54 files changed:
tools/codegenerator/SwigTypeParser.groovy
xbmc/commons/typeindex.h [new file with mode: 0644]
xbmc/cores/VideoRenderers/RenderManager.h
xbmc/interfaces/legacy/Addon.cpp
xbmc/interfaces/legacy/Addon.h
xbmc/interfaces/legacy/AddonCallback.h
xbmc/interfaces/legacy/AddonClass.cpp
xbmc/interfaces/legacy/AddonClass.h
xbmc/interfaces/legacy/Alternative.h
xbmc/interfaces/legacy/CallbackFunction.cpp
xbmc/interfaces/legacy/CallbackFunction.h
xbmc/interfaces/legacy/CallbackHandler.cpp
xbmc/interfaces/legacy/CallbackHandler.h
xbmc/interfaces/legacy/Control.cpp
xbmc/interfaces/legacy/Control.h
xbmc/interfaces/legacy/Dialog.cpp
xbmc/interfaces/legacy/Dialog.h
xbmc/interfaces/legacy/Exception.h
xbmc/interfaces/legacy/File.cpp
xbmc/interfaces/legacy/File.h
xbmc/interfaces/legacy/InfoTagMusic.cpp
xbmc/interfaces/legacy/InfoTagMusic.h
xbmc/interfaces/legacy/InfoTagVideo.cpp
xbmc/interfaces/legacy/Keyboard.cpp
xbmc/interfaces/legacy/Keyboard.h
xbmc/interfaces/legacy/LanguageHook.h
xbmc/interfaces/legacy/ListItem.cpp
xbmc/interfaces/legacy/ListItem.h
xbmc/interfaces/legacy/ModuleXbmcvfs.h
xbmc/interfaces/legacy/Monitor.cpp
xbmc/interfaces/legacy/Monitor.h
xbmc/interfaces/legacy/PlayList.cpp
xbmc/interfaces/legacy/Player.cpp
xbmc/interfaces/legacy/Player.h
xbmc/interfaces/legacy/RenderCapture.h
xbmc/interfaces/legacy/Stat.h
xbmc/interfaces/legacy/Window.cpp
xbmc/interfaces/legacy/Window.h
xbmc/interfaces/legacy/WindowDialog.cpp
xbmc/interfaces/legacy/WindowDialog.h
xbmc/interfaces/legacy/WindowXML.cpp
xbmc/interfaces/legacy/WindowXML.h
xbmc/interfaces/python/CallbackHandler.cpp
xbmc/interfaces/python/LanguageHook.cpp
xbmc/interfaces/python/LanguageHook.h
xbmc/interfaces/python/PythonInvoker.cpp
xbmc/interfaces/python/PythonSwig.cpp.template
xbmc/interfaces/python/swig.cpp
xbmc/interfaces/python/swig.h
xbmc/interfaces/python/typemaps/python.Alternative.intm [new file with mode: 0644]
xbmc/interfaces/swig/AddonModuleXbmc.i
xbmc/interfaces/swig/AddonModuleXbmcgui.i
xbmc/interfaces/swig/AddonModuleXbmcvfs.i
xbmc/interfaces/swig/ControlListAddItemMethods.i [deleted file]

index 07ed5f4..c7efb3f 100644 (file)
@@ -132,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
    }
 
    /**
@@ -209,7 +240,7 @@ public class SwigTypeParser
             firstarray = false
          } else if (SwigType_isreference(element)) {
             if (notypeconv) {
-               result == element
+               result += element
             } else {
                result += "p."
             }
@@ -220,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 (file)
index 0000000..66fc0bf
--- /dev/null
@@ -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;
+}
index 28596cf..c469795 100644 (file)
@@ -30,6 +30,7 @@
 #include "settings/VideoSettings.h"
 #include "OverlayRenderer.h"
 #include <deque>
+#include "PlatformDefs.h"
 
 class CRenderCapture;
 
index c9b247d..bfc51d2 100644 (file)
@@ -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);
 
index 1f94309..c35277c 100644 (file)
@@ -129,7 +129,6 @@ namespace XBMCAddon
        *   - version = self.Addon.getAddonInfo('version')
        */
       String getAddonInfo(const char* id) throw (AddonException);
-
     };
   }
 }
index 049995a..8f55467 100644 (file)
@@ -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);
   };
 }
index 80fd96b..a4a9d0c 100644 (file)
@@ -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
 }
 
index cde936d..d5ced32 100644 (file)
@@ -66,12 +66,11 @@ namespace XBMCAddon
   {
   private:
     long   refs;
-    String classname;
     bool m_isDeallocating;
+
     // no copying
     inline AddonClass(const AddonClass&);
 
-
 #ifdef XBMC_ADDON_DEBUG_MEMORY
     bool isDeleted;
 #endif
@@ -94,11 +93,17 @@ namespace XBMCAddon
       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; }
 
     /**
@@ -108,6 +113,8 @@ namespace XBMCAddon
      */
     bool isDeallocating() { TRACE; return m_isDeallocating; }
 
+    static short getNumAddonClasses();
+
 #ifdef XBMC_ADDON_DEBUG_MEMORY
     virtual 
 #else
@@ -118,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;
@@ -138,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
index 96c641c..8677b0f 100644 (file)
@@ -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; }
   };
 }
 
index 3408b6b..55486db 100644 (file)
@@ -22,9 +22,5 @@
 
 namespace XBMCAddon
 {
-  Callback::~Callback()
-  {
-    deallocating();
-  }
-
+  Callback::~Callback() { deallocating(); }
 }
index 4304b42..65a8489 100644 (file)
@@ -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); }
   };
-
-
 }
 
 
index cbaa2ca..19a4a88 100644 (file)
@@ -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; }
   };
 
   //********************************************************************
index db5ea03..4199b34 100644 (file)
@@ -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();
index a4eea05..e921434 100644 (file)
@@ -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)
index 4a30d04..743ddb1 100644 (file)
@@ -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
     };
   }
index f907e60..cbb10eb 100644 (file)
@@ -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};
index 0697d1c..8cc0e04 100644 (file)
@@ -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();
 
 
index 5a88b65..5741c85 100644 (file)
@@ -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__); }
 
index b93a5b6..433cc72 100644 (file)
@@ -22,7 +22,6 @@
 
 namespace XBMCAddon
 {
-
   namespace xbmcvfs
   {
     XbmcCommons::Buffer File::readBytes(unsigned long numBytes)
index d356230..0dfcbd0 100644 (file)
@@ -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)
index 8f608f9..fe01cba 100644 (file)
@@ -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;
index 63865f0..3a8777e 100644 (file)
@@ -102,7 +102,6 @@ namespace XBMCAddon
        * getLyrics() -- returns a string.\n
        */
       String getLyrics();
-
     };
   }
 }
index dc4b680..9c5d1ab 100644 (file)
@@ -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;
index b6c5ad7..be2d352 100644 (file)
@@ -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)
     {
     }
 
index 6f4d39e..0392a18 100644 (file)
@@ -126,7 +126,6 @@ namespace XBMCAddon
        *   - if (kb.isConfirmed()):
        */
       bool isConfirmed();
-
     };
   }
 }
index 6b929f2..76ca78f 100644 (file)
@@ -42,7 +42,7 @@ namespace XBMCAddon
   class LanguageHook : public AddonClass
   {
   protected:
-    LanguageHook(const char* subclassName) : AddonClass(subclassName) {}
+    inline LanguageHook() {}
 
   public:
     virtual ~LanguageHook();
index ec380b0..7ad8ac9 100644 (file)
@@ -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();
 
index 8c495d9..f88bbdf 100644 (file)
@@ -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;
index 857a12f..c1b66e7 100644 (file)
@@ -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);
 
     /**
index 2f6580e..e67580a 100644 (file)
@@ -24,7 +24,7 @@ namespace XBMCAddon
 {
   namespace xbmc
   {
-    Monitor::Monitor() : AddonCallback("Monitor") 
+    Monitor::Monitor()
     {
       if (languageHook)
       {
index 9291f67..0e03cb1 100644 (file)
@@ -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; }
     };
   }
 };
index e67b41e..a84428c 100644 (file)
@@ -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
index 2f41102..ad51349 100644 (file)
@@ -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;
index 3f2a561..2ab12b8 100644 (file)
@@ -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.
index 4ec69c6..12ce1c4 100644 (file)
@@ -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); }
 
       /**
index 63bc4f6..b136162 100644 (file)
@@ -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);
index f29fca6..76478ba 100644 (file)
@@ -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)
     {
index 63d5fe4..dfe097f 100644 (file)
@@ -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();
 
@@ -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();
 
       /**
index 5989e05..87f0d84 100644 (file)
@@ -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()));
index 6197968..6b48ec2 100644 (file)
@@ -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
     };
   }
 }
index 3203f35..6d21133 100644 (file)
@@ -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; }
 
index 07c2ac3..f3db088 100644 (file)
@@ -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
     };
   }
 }
index 3283e0e..42599c5 100644 (file)
@@ -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);
     }
   }
 }
index 98461d9..563beb6 100644 (file)
@@ -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,18 +156,18 @@ 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;
       CSingleLock l(*this);
@@ -175,7 +175,7 @@ namespace XBMCAddon
       currentObjects.insert(obj);
     }
 
-    void LanguageHook::UnregisterAddonClassInstance(AddonClass* obj)
+    void PythonLanguageHook::UnregisterAddonClassInstance(AddonClass* obj)
     {
       TRACE;
       CSingleLock l(*this);
@@ -183,7 +183,7 @@ namespace XBMCAddon
         obj->Release();
     }
 
-    bool LanguageHook::HasRegisteredAddonClassInstance(AddonClass* obj)
+    bool PythonLanguageHook::HasRegisteredAddonClassInstance(AddonClass* obj)
     {
       TRACE;
       CSingleLock l(*this);
index eee548f..263b90e 100644 (file)
@@ -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,7 +84,7 @@ 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);
index 9f5403e..da74f75 100644 (file)
@@ -78,7 +78,7 @@ 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;
   CSingleLock l(*(languageHook.get()));
@@ -90,7 +90,7 @@ static const CStdString getListOfAddonClassesAsString(XBMCAddon::AddonClass::Ref
       message += ",";
     else
       firstTime = false;
-    message += (*iter)->GetClassname().c_str();
+    message += (*iter)->GetClassname();
   }
 
   return message;
@@ -179,7 +179,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();
index 93523ed..86cc208 100644 (file)
@@ -72,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.
@@ -85,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'),
@@ -203,14 +204,14 @@ void doMethod(Node 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}::<% }
@@ -220,7 +221,7 @@ void doMethod(Node 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);
 <%
     }
@@ -257,13 +258,13 @@ void doMethod(Node 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);<%
     }
  %>
@@ -293,14 +294,7 @@ 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}));<%
 %>
   //=========================================================================
 <%    
@@ -316,7 +310,6 @@ void doExternClassTypeInfo(String knownType)
 %>
   //=========================================================================
   // These variables define the type ${knownType} from another module 
-  extern PyTypeObject Py${classNameAsVariable}_Type;
   extern TypeInfo Ty${classNameAsVariable}_Type;
   //=========================================================================
 <%    
@@ -409,7 +402,7 @@ void doClassMethodInfo(Node clazz, List initTypeCalls)
 %>
   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();
   }
 
   //=========================================================================
@@ -464,7 +457,7 @@ void doClassMethodInfo(Node clazz, List initTypeCalls)
 %>
     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;
    <%
@@ -515,7 +508,7 @@ void doClassMethodInfo(Node clazz, List initTypeCalls)
     ${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)
     {
@@ -577,38 +570,42 @@ void doClassMethodInfo(Node clazz, List initTypeCalls)
                  ${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);
+<%} %>
   }
   //=========================================================================
 <%
@@ -803,7 +800,7 @@ namespace PythonBindings
       }
 
       classNameAsVariables.each { %>
-      if (PyType_Ready(&Py${it}_Type) < 0)
+      if (PyType_Ready(&(Ty${it}_Type.pythonType)) < 0)
         return;<%
       }%>
     }
@@ -817,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
index f95dee3..7b1a302 100644 (file)
 
 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];
+  }
+
 }
 
index 2a795c6..8c0fbfa 100644 (file)
@@ -18,6 +18,8 @@
  *
  */
 
+#pragma once
+
 #include <Python.h>
 #include <string>
 #include <stdint.h>
 #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 (file)
index 0000000..0a3c34a
--- /dev/null
@@ -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])}" );
+        }
+      }
+    }
+
+      
index dd8cfc3..7a0e27f 100644 (file)
@@ -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"
index 305ebc8..52eeddf 100644 (file)
@@ -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"
index 92d8709..ac09158 100644 (file)
@@ -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 (file)
index c13b749..0000000
+++ /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; 
-} 
-