00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef VALUE_BINDING_H
00025 #define VALUE_BINDING_H
00026
00027 #include <kjs/object.h>
00028 #include <kjs/interpreter.h>
00029
00030 #include "static_binding.h"
00031 #include "pointer.h"
00032
00039 #define START_VALUE_METHOD( METHODNAME, TYPE) \
00040 KJS::JSValue *METHODNAME( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) \
00041 { \
00042 Q_UNUSED(exec);\
00043 Q_UNUSED(self);\
00044 Q_UNUSED(args);\
00045 KJS::JSValue *result = KJS::jsNull(); \
00046 KJSEmbed::ValueBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::ValueBinding>(exec, self ); \
00047 if( imp ) \
00048 { \
00049 TYPE value = imp->value<TYPE>();
00050
00053 #define END_VALUE_METHOD \
00054 imp->setValue(value); \
00055 } \
00056 else { \
00057 KJS::throwError(exec, KJS::GeneralError, "Problem in ValueBinding here");\
00058 }\
00059 return result; \
00060 }
00061
00062 #define KJSO_VALUE_SIMPLE_BINDING_CTOR( NAME, JSNAME, TYPE, BASENAME ) \
00063 NAME::NAME(KJS::ExecState *exec, const char* typeName ) \
00064 : BASENAME( exec, typeName ) \
00065 { \
00066 StaticBinding::publish( exec, this, NAME::methods() ); \
00067 } \
00068 NAME::NAME(KJS::ExecState *exec, const TYPE & value) \
00069 : BASENAME( exec, #JSNAME , value ) \
00070 { \
00071 StaticBinding::publish( exec, this, NAME::methods() ); \
00072 }
00073
00074 #define KJSO_VALUE_DERIVED_BINDING_CTOR( NAME, JSNAME, TYPE, BASENAME ) \
00075 NAME::NAME(KJS::ExecState *exec, const char* typeName ) \
00076 : BASENAME( exec, typeName ) \
00077 { \
00078 StaticBinding::publish( exec, this, NAME::methods() ); \
00079 } \
00080 NAME::NAME(KJS::ExecState *exec, const TYPE & value) \
00081 : BASENAME( exec, #JSNAME ) \
00082 { \
00083 setValue(value); \
00084 StaticBinding::publish( exec, this, NAME::methods() ); \
00085 }
00086
00087
00088 namespace KJSEmbed
00089 {
00093 class ValueFactory
00094 {
00095 public:
00096 static const Method ValueMethods[];
00097 static const Method *methods();
00098 };
00099
00103 class ValueBinding : public ProxyBinding
00104 {
00105 public:
00106 template <typename T>
00107 ValueBinding( KJS::ExecState *exec, const char *typeName, T val )
00108 : ProxyBinding( exec ),
00109 m_name(typeName)
00110 {
00111 m_value = new Value<T>(val);
00112 StaticBinding::publish( exec, this, ValueFactory::methods() );
00113 }
00114 ValueBinding( KJS::ExecState *exec, const char *typeName);
00115 virtual ~ValueBinding();
00116
00117 KJS::UString toString(KJS::ExecState *exec) const;
00118 KJS::UString className() const { return m_name; }
00119
00123 template< typename T>
00124 T value() const
00125 {
00126 const T *ptr = reinterpret_cast<const T*>(m_value->voidStar());
00127 if( ptr )
00128 return *ptr;
00129 else
00130 return T();
00131 }
00132
00136 template< typename T>
00137 void setValue( const T &val )
00138 {
00139 delete m_value;
00140 m_value = new Value<T>(val);
00141 }
00142
00143 template< typename T>
00144 static T castValue( ValueBinding *imp)
00145 {
00146 const T *ptr = reinterpret_cast<const T*>( imp->m_value->voidStar() );
00147 if( ptr )
00148 return *ptr;
00149 else
00150 return T();
00151 }
00152 static const KJS::ClassInfo info;
00153
00154 private:
00155 virtual const KJS::ClassInfo* classInfo() const { return &info; }
00156
00157 PointerBase *m_value;
00158 const char *m_name;
00159
00160 };
00161
00166 template< typename T>
00167 T extractValue( KJS::ExecState *exec, KJS::JSValue *arg, const T &defaultValue )
00168 {
00169 if( arg )
00170 {
00171 KJSEmbed::ValueBinding *imp =
00172 KJSEmbed::extractBindingImp<KJSEmbed::ValueBinding>(exec, arg );
00173 if( imp )
00174 return ValueBinding::castValue<T>( imp );
00175 }
00176 return defaultValue;
00177 }
00178
00183 template< typename T>
00184 T extractValue( KJS::ExecState *exec, const KJS::List &args, int idx, const T &defaultValue = T())
00185 {
00186 if( args.size() > idx )
00187 {
00188 return extractValue<T>( exec, args[idx], defaultValue );
00189 }
00190 else
00191 return defaultValue;
00192 }
00193
00194 template< typename T>
00195 KJS::JSValue *createValue(KJS::ExecState *exec, const KJS::UString &className, const T &value)
00196 {
00197 KJS::JSObject *parent = exec->dynamicInterpreter()->globalObject();
00198 KJS::JSObject *returnValue = StaticConstructor::construct( exec, parent, className );
00199 if( returnValue )
00200 {
00201
00202 KJSEmbed::ValueBinding *imp =
00203 extractBindingImp<KJSEmbed::ValueBinding>(exec, returnValue );
00204 if( imp )
00205 imp->setValue( value );
00206 else
00207 {
00208 KJS::throwError(exec, KJS::TypeError, toUString(QString("Created failed to cast to %1 failed").arg(toQString(className))));
00209 return KJS::jsNull();
00210 }
00211 }
00212 else
00213 {
00214 KJS::throwError(exec, KJS::TypeError, toUString(QString("Could not construct a %1").arg(toQString(className) )));
00215 return KJS::jsNull();
00216 }
00217 return returnValue;
00218 }
00219 }
00220
00221 #endif
00222
00223