KJsEmbed

object_binding.h
1 /* This file is part of the KDE libraries
2  Copyright (C) 2005, 2006 Ian Reinhart Geiser <[email protected]>
3  Copyright (C) 2005, 2006 Matt Broadstone <[email protected]>
4  Copyright (C) 2005, 2006 Richard J. Moore <[email protected]>
5  Copyright (C) 2005, 2006 Erik L. Bunce <[email protected]>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #ifndef OBJECT_BINDING_H
24 #define OBJECT_BINDING_H
25 
26 #include "static_binding.h"
27 #include "variant_binding.h"
28 #include "pointer.h"
29 #include "kjseglobal.h"
30 
31 /**
32 * A simple pointer style method.
33 * This will extract the pointer, cast it to the native type and place it in "value".
34 * Any data that should be returned from this method should be placed into "result";
35 *
36 */
37 #define START_OBJECT_METHOD( METHODNAME, TYPE) \
38  KJS::JSValue *METHODNAME( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) \
39  { \
40  Q_UNUSED(exec);\
41  Q_UNUSED(self);\
42  Q_UNUSED(args);\
43  KJS::JSValue *result = KJS::jsNull(); \
44  KJSEmbed::ObjectBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::ObjectBinding>(exec, self ); \
45  if( imp ) \
46  { \
47  TYPE *object = imp->object<TYPE>(); \
48  if( object ) \
49  {
50 
51 /**
52 * End a variant method started by START_OBJECT_METHOD
53 */
54 #define END_OBJECT_METHOD \
55  } \
56  else \
57  KJS::throwError(exec, KJS::ReferenceError, QString("O: The internal object died."));\
58  } \
59  else \
60  KJS::throwError(exec, KJS::GeneralError, QString("Object cast failed."));\
61  return result; \
62  }
63 
64 #define START_STATIC_OBJECT_METHOD( METHODNAME ) \
65  KJS::JSValue *METHODNAME( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) \
66  {\
67  Q_UNUSED(exec);\
68  Q_UNUSED(self);\
69  Q_UNUSED(args);\
70  KJS::JSValue *result = KJS::jsNull(); \
71 
72 #define END_STATIC_OBJECT_METHOD \
73  return result; \
74  }
75 
76 namespace KJSEmbed
77 {
78 class KJSEMBED_EXPORT ObjectFactory
79 {
80 public:
81  static const Method ObjectMethods[];
82  static const Method *methods()
83  {
84  return ObjectMethods;
85  }
86 };
87 
88 class KJSEMBED_EXPORT ObjectBinding : public ProxyBinding
89 {
90 public:
91  enum Ownership { CPPOwned, QObjOwned, JSOwned };
92  static const KJS::ClassInfo info;
93 
94 private:
95  const char *m_name;
96  mutable PointerBase *m_value;
97  Ownership m_owner;
98 
99 public:
100  template <typename T>
101  ObjectBinding(KJS::ExecState *exec, const char *typeName, T *ptr)
102  : ProxyBinding(exec),
103  m_name(typeName)
104  {
105  StaticBinding::publish(exec, this, ObjectFactory::methods());
106 
107  m_owner = CPPOwned;
108  m_value = new Pointer<T>(ptr);
109  }
110 
111  ~ObjectBinding() override;
112 
113  const char *typeName() const;
114 
115  /**
116  * \return the internal object as a pointer of type T
117  */
118  template <typename T>
119  T *object() const
120  {
121  if (m_value) {
122  return pointer_cast<T>(m_value);
123  } else {
124  return nullptr;
125  }
126  }
127 
128  void *voidStar() const
129  {
130  return m_value->voidStar();
131  }
132 
133  template <typename T>
134  void setObject(T *ptr)
135  {
136  if (m_owner == JSOwned) {
137  //qDebug("object cleans up");
138  m_value->cleanup();
139  }
140  delete m_value;
141  m_value = new Pointer<T>(ptr);
142  }
143 
144  KJS::UString toString(KJS::ExecState *exec) const override;
145  KJS::UString className() const override;
146  KJS::JSType type() const override;
147 
148  Ownership ownership() const;
149  void setOwnership(Ownership owner);
150 
151 };
152 
153 /**
154 * Extracts a pointer based type from an ObjectBinding object. Care should be taken that this method
155 * is not used with KJSEmbed::ObjectBinding objects because the cast will fail.
156 */
157 template< typename T>
158 T *extractObject(KJS::ExecState *exec, KJS::JSValue *arg, T *defaultValue)
159 {
160  if (!arg) {
161  return defaultValue;
162  } else {
163  T *returnValue = nullptr;
164  KJSEmbed::ObjectBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::ObjectBinding>(exec, arg);
165  if (imp) {
166  // GCC 3.3 has problems calling template functions in another class from a template class.
167  // returnValue = imp->object<T>();
168 
169  returnValue = (T *)imp->voidStar();
170  }
171  if (returnValue) {
172  return returnValue;
173  } else {
174  return defaultValue;
175  }
176  }
177 }
178 
179 /**
180 * Extracts a pointer from a KJS::List of KJS::JSValues. If the argument is out of range the default value
181 * is returned.
182 */
183 template< typename T>
184 T *extractObject(KJS::ExecState *exec, const KJS::List &args, int idx, T *defaultValue = nullptr)
185 {
186  if (args.size() > idx) {
187  return extractObject<T>(exec, args[idx], defaultValue);
188  } else {
189  return defaultValue;
190  }
191 }
192 
193 /**
194 * Can create any known KJSEmbed::ObjectBinding object and set the value.
195 * On failure a KJS::jsNull will be returned and the exception set.
196 */
197 template< typename T>
198 KJS::JSValue *createObject(KJS::ExecState *exec, const KJS::UString &className, const T *value, KJSEmbed::ObjectBinding::Ownership owner = KJSEmbed::ObjectBinding::JSOwned)
199 {
200  if (nullptr == value) {
201  return KJS::jsNull();
202  }
203 
204  KJS::JSObject *parent = exec->dynamicInterpreter()->globalObject();
205  KJS::JSObject *returnValue = StaticConstructor::construct(exec, parent, className);
206  if (returnValue) {
207  // If it is a value type setValue
208  KJSEmbed::ObjectBinding *imp = extractBindingImp<KJSEmbed::ObjectBinding>(exec, returnValue);
209  if (imp) {
210  imp->setOwnership(KJSEmbed::ObjectBinding::JSOwned);
211  imp->setObject(value);
212  imp->setOwnership(owner);
213  } else {
214  throwError(exec, KJS::TypeError, i18n("%1 is not an Object type", className.ascii()));
215  return KJS::jsNull();
216  }
217  } else {
218  throwError(exec, KJS::GeneralError, "Could not construct value");
219  //throwError(exec, "Could not construct value" );
220  return KJS::jsNull();
221  }
222 
223  return returnValue;
224 }
225 
226 template< typename T >
227 T extractParameter(KJS::ExecState *exec, KJS::JSValue *arg, const T &defaultValue)
228 {
229  if (!arg) {
230  return defaultValue;
231  } else {
232  switch (arg->type()) {
233  case KJS::NumberType:
234  return extractInt(exec, arg, defaultValue);
235  break;
236  case KJS::BooleanType:
237  return extractBool(exec, arg, 0);
238  break;
239  case KJS::UnspecifiedType:
240  case KJS::UndefinedType:
241  case KJS::NullType:
242  case KJS::GetterSetterType:
243  case KJS::StringType:
244  return defaultValue;
245  break;
246  }
247 
248  KJS::JSObject *object = arg->toObject(exec);
249  if (object->inherits(&VariantBinding::info)) {
250  return extractVariant<T>(exec, arg, defaultValue);
251  } else if (object->inherits(&ObjectBinding::info)) {
252  return extractObject<T>(exec, arg, defaultValue);
253  } else {
254  return defaultValue;
255  }
256  }
257 }
258 }
259 #endif
260 
JSGlobalObject * globalObject() const
Type type(const QSqlDatabase &db)
int size() const
QString typeName(const QJsonObject &obj)
QString i18n(const char *text, const TYPE &arg...)
KJS::JSObject * construct(KJS::ExecState *exec, const KJS::List &args) override
Calls the callback that will in turn create a new instance of this object with the arguments passed i...
static void publish(KJS::ExecState *exec, KJS::JSObject *object, const Method *methods)
Publishes an array of Methods to an object.
Interpreter * dynamicInterpreter() const
char * toString(const EngineQuery &query)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Dec 10 2023 03:59:19 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.