proxy.h

00001 /***************************************************************************
00002  * proxy.h
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #ifndef KROSS_API_PROXY_H
00021 #define KROSS_API_PROXY_H
00022 
00023 #include "../main/krossconfig.h"
00024 #include "object.h"
00025 #include "list.h"
00026 
00027 #include <qstring.h>
00028 
00029 namespace Kross { namespace Api {
00030 
00031     /**
00032      * The ProxyValue template-class is used to represent a single
00033      * value (returnvalue or argument) of a \a ProxyFunction .
00034      */
00035     template< class OBJECT, typename TYPE >
00036     class ProxyValue
00037     {
00038         public:
00039 
00040             /**
00041              * The C/C++ type of the value. This could be something
00042              * like a int, uint or a const QString&.
00043              */
00044             typedef TYPE type;
00045 
00046             /**
00047              * The \a Kross::Api::Object or a from it inherited class
00048              * that we should use internaly to wrap the C/C++ type. This
00049              * could be e.g. a \a Kross::Api::Variant to wrap an uint.
00050              */
00051             typedef OBJECT object;
00052     };
00053 
00054     /**
00055      * The ProxyFunction template-class is used to publish any C/C++
00056      * method (not only slots) of a struct or class instance as a
00057      * a \a Kross::Api::Function to Kross.
00058      *
00059      * With this class we don't need to have a method-wrapper for
00060      * each single function what a) should reduce the code needed for
00061      * wrappers and b) is more typesafe cause the connection to the
00062      * C/C++ method is done on compiletime.
00063      */
00064     template< class INSTANCE, // the objectinstance
00065               typename METHOD, // the method-signature
00066               class RET  = ProxyValue<Kross::Api::Object,void>, // returnvalue
00067               class ARG1 = ProxyValue<Kross::Api::Object,void>, // first argument
00068               class ARG2 = ProxyValue<Kross::Api::Object,void>, // second argument
00069               class ARG3 = ProxyValue<Kross::Api::Object,void>, // forth argument
00070               class ARG4 = ProxyValue<Kross::Api::Object,void> > // fifth argument
00071     class ProxyFunction : public Function
00072     {
00073         private:
00074             /// Pointer to the objectinstance which method should be called.
00075             INSTANCE* m_instance;
00076             /// Pointer to the method which should be called.
00077             const METHOD m_method;
00078 
00079             /**
00080              * Internal used struct that does the execution of the wrapped method.
00081              */
00082             template<class PROXYFUNC, typename RETURNRYPE>
00083             struct ProxyFunctionCaller {
00084                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1, typename ARG2::type arg2, typename ARG3::type arg3, typename ARG4::type arg4) {
00085                     return new class RET::object( ( (self->m_instance)->*(self->m_method) )(arg1,arg2,arg3,arg4) );
00086                 }
00087             };
00088 
00089             /**
00090              * Template-specialization of the \a ProxyFunctionCaller above which
00091              * handles void-returnvalues. We need to handle this special case
00092              * seperatly cause compilers deny to return void.
00093              */
00094             template<class PROXYFUNC>
00095             struct ProxyFunctionCaller<PROXYFUNC, void> {
00096                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1, typename ARG2::type arg2, typename ARG3::type arg3, typename ARG4::type arg4) {
00097                     ( (self->m_instance)->*(self->m_method) )(arg1,arg2,arg3,arg4);
00098                     return 0;
00099                 }
00100             };
00101 
00102         public:
00103 
00104             /**
00105              * Constructor.
00106              *
00107              * \param instance The objectinstance to which the \p method
00108              *        belongs to.
00109              * \param method The method-pointer.
00110              */
00111             ProxyFunction(INSTANCE* instance, const METHOD& method)
00112                 : m_instance(instance), m_method(method) {}
00113 
00114             /**
00115              * This method got called if the wrapped method should be executed.
00116              * 
00117              * \param args The optional list of arguments passed to the
00118              *        execution-call.
00119              * \return The returnvalue of the functioncall. It will be NULL if
00120              *        the functioncall doesn't provide us a returnvalue (e.g.
00121              *        if the function has void as returnvalue).
00122              */
00123             Object::Ptr call(List::Ptr args) {
00124                 return ProxyFunctionCaller<ProxyFunction, typename RET::type>::exec(this,
00125                     Kross::Api::Object::fromObject<typename ARG1::object>(args->item(0))->operator typename ARG1::type(),
00126                     Kross::Api::Object::fromObject<typename ARG2::object>(args->item(1))->operator typename ARG2::type(),
00127                     Kross::Api::Object::fromObject<typename ARG3::object>(args->item(2))->operator typename ARG3::type(),
00128                     Kross::Api::Object::fromObject<typename ARG4::object>(args->item(3))->operator typename ARG4::type()
00129                 );
00130             }
00131     };
00132 
00133     /**
00134      * Template-specialization of the \a ProxyFunction above with 3 arguments.
00135      */
00136     template<class INSTANCE, typename METHOD, class RET, class ARG1, class ARG2, class ARG3>
00137     class ProxyFunction<INSTANCE, METHOD, RET, ARG1, ARG2, ARG3 > : public Function
00138     {
00139         private:
00140             INSTANCE* m_instance;
00141             const METHOD m_method;
00142 
00143             template<class PROXYFUNC, typename RETURNRYPE>
00144             struct ProxyFunctionCaller {
00145                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1, typename ARG2::type arg2, typename ARG3::type arg3) {
00146                     return new class RET::object( ( (self->m_instance)->*(self->m_method) )(arg1,arg2,arg3) );
00147                 }
00148             };
00149 
00150             template<class PROXYFUNC>
00151             struct ProxyFunctionCaller<PROXYFUNC, void> {
00152                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1, typename ARG2::type arg2, typename ARG3::type arg3) {
00153                     ( (self->m_instance)->*(self->m_method) )(arg1,arg2,arg3);
00154                     return 0;
00155                 }
00156             };
00157 
00158         public:
00159             ProxyFunction(INSTANCE* instance, const METHOD& method)
00160                 : m_instance(instance), m_method(method) {}
00161             Object::Ptr call(List::Ptr args) {
00162                 return ProxyFunctionCaller<ProxyFunction, typename RET::type>::exec(this,
00163                     Kross::Api::Object::fromObject<typename ARG1::object>(args->item(0))->operator typename ARG1::type(),
00164                     Kross::Api::Object::fromObject<typename ARG2::object>(args->item(1))->operator typename ARG2::type(),
00165                     Kross::Api::Object::fromObject<typename ARG3::object>(args->item(2))->operator typename ARG3::type()
00166                 );
00167             }
00168     };
00169 
00170     /**
00171      * Template-specialization of the \a ProxyFunction above with 2 arguments.
00172      */
00173     template<class INSTANCE, typename METHOD, class RET, class ARG1, class ARG2>
00174     class ProxyFunction<INSTANCE, METHOD, RET, ARG1, ARG2 > : public Function
00175     {
00176         private:
00177             INSTANCE* m_instance;
00178             const METHOD m_method;
00179 
00180             template<class PROXYFUNC, typename RETURNRYPE>
00181             struct ProxyFunctionCaller {
00182                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1, typename ARG2::type arg2) {
00183                     return new class RET::object( ( (self->m_instance)->*(self->m_method) )(arg1,arg2) );
00184                 }
00185             };
00186 
00187             template<class PROXYFUNC>
00188             struct ProxyFunctionCaller<PROXYFUNC, void> {
00189                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1, typename ARG2::type arg2) {
00190                     ( (self->m_instance)->*(self->m_method) )(arg1,arg2);
00191                     return 0;
00192                 }
00193             };
00194 
00195         public:
00196             ProxyFunction(INSTANCE* instance, const METHOD& method)
00197                 : m_instance(instance), m_method(method) {}
00198             Object::Ptr call(List::Ptr args) {
00199                 return ProxyFunctionCaller<ProxyFunction, typename RET::type>::exec(this,
00200                     Kross::Api::Object::fromObject<typename ARG1::object>(args->item(0))->operator typename ARG1::type(),
00201                     Kross::Api::Object::fromObject<typename ARG2::object>(args->item(1))->operator typename ARG2::type()
00202                 );
00203             }
00204     };
00205 
00206     /**
00207      * Template-specialization of the \a ProxyFunction above with one argument.
00208      */
00209     template<class INSTANCE, typename METHOD, class RET, class ARG1>
00210     class ProxyFunction<INSTANCE, METHOD, RET, ARG1 > : public Function
00211     {
00212         private:
00213             INSTANCE* m_instance;
00214             const METHOD m_method;
00215 
00216             template<class PROXYFUNC, typename RETURNRYPE>
00217             struct ProxyFunctionCaller {
00218                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1) {
00219                     return new class RET::object( ( (self->m_instance)->*(self->m_method) )(arg1) );
00220                 }
00221             };
00222 
00223             template<class PROXYFUNC>
00224             struct ProxyFunctionCaller<PROXYFUNC, void> {
00225                 inline static Object::Ptr exec(PROXYFUNC* self, typename ARG1::type arg1) {
00226                     ( (self->m_instance)->*(self->m_method) )(arg1);
00227                     return 0;
00228                 }
00229             };
00230 
00231         public:
00232             ProxyFunction(INSTANCE* instance, const METHOD& method)
00233                 : m_instance(instance), m_method(method) {}
00234             Object::Ptr call(List::Ptr args) {
00235                 return ProxyFunctionCaller<ProxyFunction, typename RET::type>::exec(this,
00236                     Kross::Api::Object::fromObject<typename ARG1::object>(args->item(0))->operator typename ARG1::type()
00237                 );
00238             }
00239     };
00240 
00241     /**
00242      * Template-specialization of the \a ProxyFunction above with no arguments.
00243      */
00244     template<class INSTANCE, typename METHOD, class RET>
00245     class ProxyFunction<INSTANCE, METHOD, RET > : public Function
00246     {
00247         private:
00248             INSTANCE* m_instance;
00249             const METHOD m_method;
00250 
00251             template<class PROXYFUNC, typename RETURNRYPE>
00252             struct ProxyFunctionCaller {
00253                 inline static Object::Ptr exec(PROXYFUNC* self) {
00254                     return new class RET::object( ( (self->m_instance)->*(self->m_method) )() );
00255                 }
00256             };
00257 
00258             template<class PROXYFUNC>
00259             struct ProxyFunctionCaller<PROXYFUNC, void> {
00260                 inline static Object::Ptr exec(PROXYFUNC* self) {
00261                     ( (self->m_instance)->*(self->m_method) )();
00262                     return 0;
00263                 }
00264             };
00265 
00266         public:
00267             ProxyFunction(INSTANCE* instance, const METHOD& method)
00268                 : m_instance(instance), m_method(method) {}
00269             Object::Ptr call(List::Ptr) {
00270                 return ProxyFunctionCaller<ProxyFunction, typename RET::type>::exec(this);
00271             }
00272     };
00273 
00274 }}
00275 
00276 #endif
00277 

Generated on Thu Feb 9 17:59:10 2006 for Kross by  doxygen 1.4.6