summaryrefslogtreecommitdiffstats
path: root/lib/kross/api/proxy.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kross/api/proxy.h')
-rw-r--r--lib/kross/api/proxy.h342
1 files changed, 342 insertions, 0 deletions
diff --git a/lib/kross/api/proxy.h b/lib/kross/api/proxy.h
new file mode 100644
index 00000000..f25a4845
--- /dev/null
+++ b/lib/kross/api/proxy.h
@@ -0,0 +1,342 @@
+/***************************************************************************
+ * proxy.h
+ * This file is part of the KDE project
+ * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, 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
+ * Library General Public License for more details.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ ***************************************************************************/
+
+#ifndef KROSS_API_PROXY_H
+#define KROSS_API_PROXY_H
+
+#include "../main/krossconfig.h"
+#include "object.h"
+#include "variant.h"
+#include "list.h"
+
+#include <qstring.h>
+
+namespace Kross { namespace Api {
+
+ /**
+ * \internal used struct to translate an argument-value dynamicly.
+ */
+ template<class OBJ>
+ struct ProxyArgTranslator {
+ OBJ* m_object;
+ ProxyArgTranslator(Kross::Api::Object* obj) {
+ m_object = Kross::Api::Object::fromObject<OBJ>(obj);
+ }
+ template<typename T>
+ inline operator T () {
+ return m_object->operator T();
+ }
+ };
+
+ /**
+ * \internal used struct to translate a return-value dynamicly.
+ */
+ struct ProxyRetTranslator {
+ template<class RETURNOBJ, typename TYPE>
+ inline static Object::Ptr cast(TYPE t) {
+ return RETURNOBJ::toObject(t);
+ }
+ };
+
+ /**
+ * The ProxyFunction template-class is used to publish any C/C++
+ * method (not only slots) of a struct or class instance as a
+ * a \a Function to Kross.
+ *
+ * With this class we don't need to have a method-wrapper for
+ * each single function what a) should reduce the code needed for
+ * wrappers and b) is more typesafe cause the connection to the
+ * C/C++ method is done on compiletime.
+ *
+ * Example how a ProxyFunction may got used;
+ * @code
+ * #include "../api/class.h"
+ * #include "../api/proxy.h"
+ * // The class which should be published.
+ * class MyClass : public Kross::Api::Class<MyClass> {
+ * public:
+ * MyClass(const QString& name) : Kross::Api::Class<MyClass>(name) {
+ * // publish the function myfunc, so that scripting-code is able
+ * // to call that method.
+ * this->addProxyFunction <
+ * Kross::Api::Variant, // the uint returnvalue is handled with Variant.
+ * Kross::Api::Variant, // the QString argument is handled with Variant too.
+ * MyClass // the MyClass* is handled implicit by our class.
+ * > ( "myfuncname", // the name the function should be published as.
+ * this, // pointer to the class-instance which has the method.
+ * &TestPluginObject::myfunc ); // pointer to the method itself.
+ * }
+ * virtual ~MyClass() {}
+ * virtual const QString getClassName() const { return "MyClass"; }
+ * private:
+ * uint myfunc(const QCString&, MyClass* myotherclass) {
+ * // This method will be published to the scripting backend. So, scripting
+ * // code is able to call this method.
+ * }
+ * }
+ * @endcode
+ */
+ template< class INSTANCE, // the objectinstance
+ typename METHOD, // the method-signature
+ class RETURNOBJ,// = Kross::Api::Object, // return-value
+ class ARG1OBJ = Kross::Api::Object, // first parameter-value
+ class ARG2OBJ = Kross::Api::Object, // second parameter-value
+ class ARG3OBJ = Kross::Api::Object, // theird parameter-value
+ class ARG4OBJ = Kross::Api::Object // forth parameter-value
+ >
+ class ProxyFunction : public Function
+ {
+ template<class PROXYFUNC, typename RETURNTYPE>
+ friend struct ProxyFunctionCaller;
+ private:
+ /// Pointer to the objectinstance which method should be called.
+ INSTANCE* m_instance;
+ /// Pointer to the method which should be called.
+ const METHOD m_method;
+
+ /// First default argument.
+ KSharedPtr<ARG1OBJ> m_defarg1;
+ /// Second default argument.
+ KSharedPtr<ARG2OBJ> m_defarg2;
+ /// Theird default argument.
+ KSharedPtr<ARG3OBJ> m_defarg3;
+ /// Forth default argument.
+ KSharedPtr<ARG4OBJ> m_defarg4;
+
+ /**
+ * \internal used struct that does the execution of the wrapped
+ * method.
+ */
+ template<class PROXYFUNC, typename RETURNTYPE>
+ struct ProxyFunctionCaller {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1, Kross::Api::Object* arg2, Kross::Api::Object* arg3, Kross::Api::Object* arg4) {
+ return ProxyRetTranslator::cast<RETURNTYPE>(
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1), ProxyArgTranslator<ARG2OBJ>(arg2), ProxyArgTranslator<ARG3OBJ>(arg3), ProxyArgTranslator<ARG4OBJ>(arg4) )
+ );
+ }
+ };
+
+ /**
+ * \internal template-specialization of the \a ProxyFunctionCaller
+ * above which handles void-returnvalues. We need to handle this
+ * special case seperatly cause compilers deny to return void :-/
+ */
+ template<class PROXYFUNC>
+ struct ProxyFunctionCaller<PROXYFUNC, void> {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1, Kross::Api::Object* arg2, Kross::Api::Object* arg3, Kross::Api::Object* arg4) {
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1), ProxyArgTranslator<ARG1OBJ>(arg2), ProxyArgTranslator<ARG3OBJ>(arg3), ProxyArgTranslator<ARG4OBJ>(arg4) );
+ return 0; // void return-value
+ }
+ };
+
+ public:
+
+ /**
+ * Constructor.
+ *
+ * \param instance The objectinstance to which the \p method
+ * belongs to.
+ * \param method The method-pointer.
+ */
+ ProxyFunction(INSTANCE* instance, const METHOD& method, ARG1OBJ* defarg1 = 0, ARG2OBJ* defarg2 = 0, ARG3OBJ* defarg3 = 0, ARG4OBJ* defarg4 = 0)
+ : m_instance(instance), m_method(method), m_defarg1(defarg1), m_defarg2(defarg2), m_defarg3(defarg3), m_defarg4(defarg4) {}
+
+ /**
+ * This method got called if the wrapped method should be executed.
+ *
+ * \param args The optional list of arguments passed to the
+ * execution-call.
+ * \return The returnvalue of the functioncall. It will be NULL if
+ * the functioncall doesn't provide us a returnvalue (e.g.
+ * if the function has void as returnvalue).
+ */
+ Object::Ptr call(List::Ptr args) {
+ return ProxyFunctionCaller<ProxyFunction, RETURNOBJ>::exec(this,
+ args->item(0, m_defarg1),
+ args->item(1, m_defarg2),
+ args->item(2, m_defarg3),
+ args->item(3, m_defarg4)
+ );
+ }
+ };
+
+ /**
+ * Template-specialization of the \a ProxyFunction above with three arguments.
+ */
+ template<class INSTANCE, typename METHOD, class RETURNOBJ, class ARG1OBJ, class ARG2OBJ, class ARG3OBJ>
+ class ProxyFunction<INSTANCE, METHOD, RETURNOBJ, ARG1OBJ, ARG2OBJ, ARG3OBJ> : public Function
+ {
+ template<class PROXYFUNC, typename RETURNTYPE>
+ friend struct ProxyFunctionCaller;
+ private:
+ INSTANCE* m_instance;
+ const METHOD m_method;
+ KSharedPtr<ARG1OBJ> m_defarg1;
+ KSharedPtr<ARG2OBJ> m_defarg2;
+ KSharedPtr<ARG3OBJ> m_defarg3;
+
+ template<class PROXYFUNC, typename RETURNTYPE>
+ struct ProxyFunctionCaller {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1, Kross::Api::Object* arg2, Kross::Api::Object* arg3) {
+ return ProxyRetTranslator::cast<RETURNTYPE>(
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1), ProxyArgTranslator<ARG2OBJ>(arg2), ProxyArgTranslator<ARG3OBJ>(arg3) )
+ );
+ }
+ };
+
+ template<class PROXYFUNC>
+ struct ProxyFunctionCaller<PROXYFUNC, void> {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1, Kross::Api::Object* arg2, Kross::Api::Object* arg3) {
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1), ProxyArgTranslator<ARG2OBJ>(arg2), ProxyArgTranslator<ARG3OBJ>(arg3) );
+ return 0;
+ }
+ };
+
+ public:
+ ProxyFunction(INSTANCE* instance, const METHOD& method, ARG1OBJ* defarg1 = 0, ARG2OBJ* defarg2 = 0, ARG3OBJ* defarg3 = 0)
+ : m_instance(instance), m_method(method), m_defarg1(defarg1), m_defarg2(defarg2), m_defarg3(defarg3) {}
+ Object::Ptr call(List::Ptr args) {
+ return ProxyFunctionCaller<ProxyFunction, RETURNOBJ>::exec(this,
+ args->item(0, m_defarg1), args->item(1, m_defarg2), args->item(2, m_defarg3)
+ );
+ }
+ };
+
+ /**
+ * Template-specialization of the \a ProxyFunction above with two arguments.
+ */
+ template<class INSTANCE, typename METHOD, class RETURNOBJ, class ARG1OBJ, class ARG2OBJ>
+ class ProxyFunction<INSTANCE, METHOD, RETURNOBJ, ARG1OBJ, ARG2OBJ> : public Function
+ {
+ template<class PROXYFUNC, typename RETURNTYPE>
+ friend struct ProxyFunctionCaller;
+ private:
+ INSTANCE* m_instance;
+ const METHOD m_method;
+ KSharedPtr<ARG1OBJ> m_defarg1;
+ KSharedPtr<ARG2OBJ> m_defarg2;
+
+ template<class PROXYFUNC, typename RETURNTYPE>
+ struct ProxyFunctionCaller {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1, Kross::Api::Object* arg2) {
+ return ProxyRetTranslator::cast<RETURNTYPE>(
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1), ProxyArgTranslator<ARG2OBJ>(arg2) )
+ );
+ }
+ };
+
+ template<class PROXYFUNC>
+ struct ProxyFunctionCaller<PROXYFUNC, void> {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1, Kross::Api::Object* arg2) {
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1), ProxyArgTranslator<ARG2OBJ>(arg2) );
+ return 0;
+ }
+ };
+
+ public:
+ ProxyFunction(INSTANCE* instance, const METHOD& method, ARG1OBJ* defarg1 = 0, ARG2OBJ* defarg2 = 0)
+ : m_instance(instance), m_method(method), m_defarg1(defarg1), m_defarg2(defarg2) {}
+ Object::Ptr call(List::Ptr args) {
+ return ProxyFunctionCaller<ProxyFunction, RETURNOBJ>::exec(this,
+ args->item(0, m_defarg1), args->item(1, m_defarg2)
+ );
+ }
+ };
+
+ /**
+ * Template-specialization of the \a ProxyFunction above with one argument.
+ */
+ template<class INSTANCE, typename METHOD, class RETURNOBJ, class ARG1OBJ>
+ class ProxyFunction<INSTANCE, METHOD, RETURNOBJ, ARG1OBJ> : public Function
+ {
+ template<class PROXYFUNC, typename RETURNTYPE>
+ friend struct ProxyFunctionCaller;
+ private:
+ INSTANCE* m_instance;
+ const METHOD m_method;
+ KSharedPtr<ARG1OBJ> m_defarg1;
+
+ template<class PROXYFUNC, typename RETURNTYPE>
+ struct ProxyFunctionCaller {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1) {
+ return ProxyRetTranslator::cast<RETURNTYPE>(
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1) )
+ );
+ }
+ };
+
+ template<class PROXYFUNC>
+ struct ProxyFunctionCaller<PROXYFUNC, void> {
+ inline static Object::Ptr exec(PROXYFUNC* self, Kross::Api::Object* arg1) {
+ ( (self->m_instance)->*(self->m_method) )( ProxyArgTranslator<ARG1OBJ>(arg1) );
+ return 0;
+ }
+ };
+
+ public:
+ ProxyFunction(INSTANCE* instance, const METHOD& method, ARG1OBJ* defarg1 = 0)
+ : m_instance(instance), m_method(method), m_defarg1(defarg1) {}
+ Object::Ptr call(List::Ptr args) {
+ return ProxyFunctionCaller<ProxyFunction, RETURNOBJ>::exec(this,
+ args->item(0, m_defarg1)
+ );
+ }
+ };
+
+ /**
+ * Template-specialization of the \a ProxyFunction above with no arguments.
+ */
+ template<class INSTANCE, typename METHOD, class RETURNOBJ>
+ class ProxyFunction<INSTANCE, METHOD, RETURNOBJ> : public Function
+ {
+ template<class PROXYFUNC, typename RETURNTYPE>
+ friend struct ProxyFunctionCaller;
+ private:
+ INSTANCE* m_instance;
+ const METHOD m_method;
+
+ template<class PROXYFUNC, typename RETURNTYPE>
+ struct ProxyFunctionCaller {
+ inline static Object::Ptr exec(PROXYFUNC* self) {
+ return ProxyRetTranslator::cast<RETURNTYPE>(
+ ( (self->m_instance)->*(self->m_method) )()
+ );
+ }
+ };
+
+ template<class PROXYFUNC>
+ struct ProxyFunctionCaller<PROXYFUNC, void> {
+ inline static Object::Ptr exec(PROXYFUNC* self) {
+ ( (self->m_instance)->*(self->m_method) )();
+ return 0;
+ }
+ };
+
+ public:
+ ProxyFunction(INSTANCE* instance, const METHOD& method)
+ : m_instance(instance), m_method(method) {}
+ Object::Ptr call(List::Ptr) {
+ return ProxyFunctionCaller<ProxyFunction, RETURNOBJ>::exec(this);
+ }
+ };
+
+}}
+
+#endif
+