kjsembed
object_binding.h
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2005, 2006 Ian Reinhart Geiser <geiseri@kde.org> 00003 Copyright (C) 2005, 2006 Matt Broadstone <mbroadst@gmail.com> 00004 Copyright (C) 2005, 2006 Richard J. Moore <rich@kde.org> 00005 Copyright (C) 2005, 2006 Erik L. Bunce <kde@bunce.us> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 00023 00024 #ifndef OBJECT_BINDING_H 00025 #define OBJECT_BINDING_H 00026 00027 #include <kdemacros.h> 00028 00029 #include "static_binding.h" 00030 #include "variant_binding.h" 00031 #include "pointer.h" 00032 #include "kjseglobal.h" 00033 00040 #define START_OBJECT_METHOD( METHODNAME, TYPE) \ 00041 KJS::JSValue *METHODNAME( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) \ 00042 { \ 00043 Q_UNUSED(exec);\ 00044 Q_UNUSED(self);\ 00045 Q_UNUSED(args);\ 00046 KJS::JSValue *result = KJS::jsNull(); \ 00047 KJSEmbed::ObjectBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::ObjectBinding>(exec, self ); \ 00048 if( imp ) \ 00049 { \ 00050 TYPE *object = imp->object<TYPE>(); \ 00051 if( object ) \ 00052 { 00053 00057 #define END_OBJECT_METHOD \ 00058 } \ 00059 else \ 00060 KJS::throwError(exec, KJS::ReferenceError, QString("O: The internal object died."));\ 00061 } \ 00062 else \ 00063 KJS::throwError(exec, KJS::GeneralError, QString("Object cast failed."));\ 00064 return result; \ 00065 } 00066 00067 #define START_STATIC_OBJECT_METHOD( METHODNAME ) \ 00068 KJS::JSValue *METHODNAME( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) \ 00069 {\ 00070 Q_UNUSED(exec);\ 00071 Q_UNUSED(self);\ 00072 Q_UNUSED(args);\ 00073 KJS::JSValue *result = KJS::jsNull(); \ 00074 00075 #define END_STATIC_OBJECT_METHOD \ 00076 return result; \ 00077 } 00078 00079 namespace KJSEmbed 00080 { 00081 class KJSEMBED_EXPORT ObjectFactory 00082 { 00083 public: 00084 static const Method ObjectMethods[]; 00085 static const Method *methods(){ return ObjectMethods;} 00086 }; 00087 00088 class KJSEMBED_EXPORT ObjectBinding : public ProxyBinding 00089 { 00090 public: 00091 enum Ownership { CPPOwned, QObjOwned, JSOwned }; 00092 static const KJS::ClassInfo info; 00093 00094 private: 00095 const char *m_name; 00096 mutable PointerBase *m_value; 00097 Ownership m_owner; 00098 00099 public: 00100 template <typename T> 00101 ObjectBinding( KJS::ExecState *exec, const char *typeName, T *ptr ) 00102 : ProxyBinding(exec), 00103 m_name(typeName) 00104 { 00105 StaticBinding::publish( exec, this, ObjectFactory::methods() ); 00106 00107 m_owner = CPPOwned; 00108 m_value = new Pointer<T>(ptr); 00109 } 00110 00111 virtual ~ObjectBinding(); 00112 00113 const char *typeName() const; 00114 00118 template <typename T> 00119 T *object() const 00120 { 00121 if( m_value ) 00122 return pointer_cast<T>(m_value); 00123 else 00124 return 0; 00125 } 00126 00127 void *voidStar() const 00128 { 00129 return m_value->voidStar(); 00130 } 00131 00132 template <typename T> 00133 void setObject( T *ptr ) 00134 { 00135 if( m_owner == JSOwned ) 00136 { 00137 //qDebug("object cleans up"); 00138 m_value->cleanup(); 00139 } 00140 delete m_value; 00141 m_value = new Pointer<T>(ptr); 00142 } 00143 00144 KJS::UString toString( KJS::ExecState *exec ) const; 00145 KJS::UString className() const; 00146 KJS::JSType type() const; 00147 00148 Ownership ownership() const; 00149 void setOwnership( Ownership owner ); 00150 00151 }; 00152 00157 template< typename T> 00158 T * extractObject( KJS::ExecState *exec, KJS::JSValue *arg, T *defaultValue ) 00159 { 00160 if( !arg ) 00161 return defaultValue; 00162 else 00163 { 00164 T *returnValue = 0; 00165 KJSEmbed::ObjectBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::ObjectBinding>(exec, arg ); 00166 if( imp ) 00167 { 00168 // GCC 3.3 has problems calling template functions in another class from a template class. 00169 // returnValue = imp->object<T>(); 00170 00171 returnValue = (T *)imp->voidStar(); 00172 } 00173 if( returnValue ) 00174 return returnValue; 00175 else 00176 return defaultValue; 00177 } 00178 } 00179 00184 template< typename T> 00185 T * extractObject( KJS::ExecState *exec, const KJS::List &args, int idx, T *defaultValue = 0L) 00186 { 00187 if( args.size() > idx ) 00188 { 00189 return extractObject<T>( exec, args[idx], defaultValue ); 00190 } 00191 else 00192 return defaultValue; 00193 } 00194 00199 template< typename T> 00200 KJS::JSValue *createObject(KJS::ExecState *exec, const KJS::UString &className, const T *value, KJSEmbed::ObjectBinding::Ownership owner = KJSEmbed::ObjectBinding::JSOwned ) 00201 { 00202 if ( 0 == value ) 00203 return KJS::jsNull(); 00204 00205 KJS::JSObject *parent = exec->dynamicInterpreter()->globalObject(); 00206 KJS::JSObject *returnValue = StaticConstructor::construct( exec, parent, className ); 00207 if( returnValue ) 00208 { 00209 // If it is a value type setValue 00210 KJSEmbed::ObjectBinding *imp = extractBindingImp<KJSEmbed::ObjectBinding>(exec, returnValue ); 00211 if( imp ) 00212 { 00213 imp->setOwnership( KJSEmbed::ObjectBinding::JSOwned ); 00214 imp->setObject( value ); 00215 imp->setOwnership( owner ); 00216 } 00217 else 00218 { 00219 throwError(exec, KJS::TypeError, i18n("%1 is not an Object type", className.ascii())); 00220 return KJS::jsNull(); 00221 } 00222 } 00223 else 00224 { 00225 throwError(exec, KJS::GeneralError, "Could not construct value"); 00226 //throwError(exec, "Could not construct value" ); 00227 return KJS::jsNull(); 00228 } 00229 00230 return returnValue; 00231 } 00232 00233 template< typename T > 00234 T extractParameter( KJS::ExecState *exec, KJS::JSValue *arg, const T &defaultValue ) 00235 { 00236 if( !arg ) 00237 return defaultValue; 00238 else 00239 { 00240 switch (arg->type()) 00241 { 00242 case KJS::NumberType: 00243 return extractInt(exec, arg, defaultValue); 00244 break; 00245 case KJS::BooleanType: 00246 return extractBool(exec, arg, 0); 00247 break; 00248 case KJS::UnspecifiedType: 00249 case KJS::UndefinedType: 00250 case KJS::NullType: 00251 case KJS::GetterSetterType: 00252 case KJS::StringType: 00253 return defaultValue; 00254 break; 00255 } 00256 00257 KJS::JSObject* object = arg->toObject(exec); 00258 if(object->inherits(&VariantBinding::info)) 00259 { 00260 return extractVariant<T>(exec, arg, defaultValue); 00261 } 00262 else if(object->inherits(&ObjectBinding::info)) 00263 { 00264 return extractObject<T>(exec, arg, defaultValue); 00265 } 00266 else 00267 return defaultValue; 00268 } 00269 } 00270 } 00271 #endif 00272 00273 //kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;
KDE 4.6 API Reference