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