QDaq  0.2.6
Qt-based Data Aqcuisition
 All Classes Functions Variables Typedefs Enumerations Enumerator Properties Groups Pages
vectorclass.cpp
1 #include <QtScript/QScriptClassPropertyIterator>
2 #include <QtScript/QScriptContext>
3 #include <QtScript/QScriptEngine>
4 #include "vectorclass.h"
5 #include "vectorprototype.h"
6 
7 #include <stdlib.h>
8 
9 Q_DECLARE_METATYPE(QDaqVector*)
10 Q_DECLARE_METATYPE(VectorClass*)
11 
12 class VectorClassPropertyIterator : public QScriptClassPropertyIterator
13 {
14 public:
15  VectorClassPropertyIterator(const QScriptValue &object, const QList<QScriptString>& lst);
16  ~VectorClassPropertyIterator();
17 
18  bool hasNext() const;
19  void next();
20 
21  bool hasPrevious() const;
22  void previous();
23 
24  void toFront();
25  void toBack();
26 
27  QScriptString name() const;
28  uint id() const;
29 
30 private:
31  QList<QScriptString> m_names;
32  int m_index;
33  int m_last;
34  int m_offset;
35 };
36 
38 VectorClass::VectorClass(QScriptEngine *engine)
39  : QObject(engine), QScriptClass(engine)
40 {
41  qScriptRegisterMetaType<QDaqVector>(engine, toScriptValue, fromScriptValue);
42 
43  length = engine->toStringHandle(QLatin1String("length"));
44  circular = engine->toStringHandle(QLatin1String("circular"));
45  capacity = engine->toStringHandle(QLatin1String("capacity"));
46 
47  proto = engine->newQObject(new VectorPrototype(this),
48  QScriptEngine::QtOwnership,
49  // QScriptEngine::SkipMethodsInEnumeration |
50  QScriptEngine::ExcludeSuperClassMethods |
51  QScriptEngine::ExcludeSuperClassProperties);
52  QScriptValue global = engine->globalObject();
53  proto.setPrototype(global.property("Object").property("prototype"));
54 
55  ctor = engine->newFunction(construct, proto);
56  ctor.setData(engine->toScriptValue(this));
57 }
59 
60 VectorClass::~VectorClass()
61 {
62 }
63 
65 QScriptClass::QueryFlags VectorClass::queryProperty(const QScriptValue &object,
66  const QScriptString &name,
67  QueryFlags flags, uint *id)
68 {
69  QDaqVector *ba = qscriptvalue_cast<QDaqVector*>(object.data());
70  QString myname(name);
71  if (!ba)
72  return 0;
73  if (name == length ||
74  name == circular ||
75  name == capacity) {
76  return flags;
77  } else {
78  bool isArrayIndex;
79  qint32 pos = name.toArrayIndex(&isArrayIndex);
80  if (!isArrayIndex)
81  return 0;
82  *id = pos;
83  //if ((pos<0) || (pos >= ba->size())) return 0;
84  if ((flags & HandlesReadAccess) && (pos >= ba->size()))
85  flags &= ~HandlesReadAccess;
86  return flags;
87  }
88 }
90 
92 QScriptValue VectorClass::property(const QScriptValue &object,
93  const QScriptString &name, uint id)
94 {
95  QDaqVector *vec = qscriptvalue_cast<QDaqVector*>(object.data());
96  if (!vec)
97  return QScriptValue();
98  if (name == length) {
99  return vec->size();
100  } else if (name == circular) {
101  return vec->isCircular();
102  } else if (name == capacity) {
103  return vec->capacity();
104  } else {
105  qint32 pos = id;
106  if ((pos < 0) || (pos >= vec->size()))
107  return QScriptValue();
108  return vec->get(pos);
109  }
110  return QScriptValue();
111 }
113 
115 void VectorClass::setProperty(QScriptValue &object,
116  const QScriptString &name,
117  uint id, const QScriptValue &value)
118 {
119  QDaqVector *vec = qscriptvalue_cast<QDaqVector*>(object.data());
120  if (!vec)
121  return;
122  if (name == length) {
123  // resize(*vec, value.toInt32());
124  } else if (name == circular) {
125  vec->setCircular(value.toBool());
126  } else if (name == capacity) {
127  vec->setCapacity(value.toInt32());
128  } else {
129  qint32 pos = id;
130  if (pos < 0 || pos >= vec->size())
131  return;
132  (*vec)[pos] = value.toNumber();
133  }
134 }
136 
138 QScriptValue::PropertyFlags VectorClass::propertyFlags(
139  const QScriptValue &/*object*/, const QScriptString &/*name*/, uint /*id*/)
140 {
141 // if (name == length ||
142 // name == circular ||
143 // name == capacity) {
144 // return QScriptValue::Undeletable
145 // | QScriptValue::SkipInEnumeration;
146 // }
147  return QScriptValue::Undeletable;
148 }
150 
152 QScriptClassPropertyIterator *VectorClass::newIterator(const QScriptValue &object)
153 {
154  QList<QScriptString> L;
155  L << length << capacity << circular;
156  return new VectorClassPropertyIterator(object, L);
157 }
159 
160 QString VectorClass::name() const
161 {
162  return QLatin1String("Vector");
163 }
164 
165 QScriptValue VectorClass::prototype() const
166 {
167  return proto;
168 }
169 
170 QScriptValue VectorClass::constructor()
171 {
172  return ctor;
173 }
174 
176 QScriptValue VectorClass::newInstance(int size)
177 {
178  engine()->reportAdditionalMemoryCost(size*sizeof(double));
179  return newInstance(QDaqVector(size));
180 }
182 
184 QScriptValue VectorClass::newInstance(const QDaqVector &ba)
185 {
186  QScriptValue data = engine()->newVariant(QVariant::fromValue(ba));
187  return engine()->newObject(this, data);
188 }
190 
192 QScriptValue VectorClass::construct(QScriptContext *ctx, QScriptEngine *)
193 {
194  VectorClass *cls = qscriptvalue_cast<VectorClass*>(ctx->callee().data());
195  if (!cls)
196  return QScriptValue();
197  if (ctx->argumentCount()) {
198  QScriptValue arg = ctx->argument(0);
199  if (arg.instanceOf(ctx->callee()))
200  return cls->newInstance(qscriptvalue_cast<QDaqVector>(arg));
201  else if (arg.isArray()) {
202  quint32 len = arg.property("length").toUInt32();
203  QDaqVector vec;
204  vec.setCapacity(len);
205  for (quint32 i = 0; i < len; ++i)
206  vec << arg.property(i).toNumber();
207  return cls->newInstance(vec);
208  }
209  else if (arg.isNumber()) {
210  int size = arg.toInt32();
211  return cls->newInstance(size);
212  }
213  } else return cls->newInstance();
214  return QScriptValue();
215 }
217 
218 QScriptValue VectorClass::toScriptValue(QScriptEngine *eng, const QDaqVector &ba)
219 {
220  QScriptValue ctor = eng->globalObject().property("Vector");
221  VectorClass *cls = qscriptvalue_cast<VectorClass*>(ctor.data());
222  if (!cls)
223  return eng->newVariant(QVariant::fromValue(ba));
224  return cls->newInstance(ba);
225 }
226 
227 void VectorClass::fromScriptValue(const QScriptValue &obj, QDaqVector &v)
228 {
229  QVariant var = obj.data().toVariant();
230  if (var.userType()==qMetaTypeId<QDaqVector>()) {
231  v = qvariant_cast<QDaqVector>(var);
232  return;
233  }
234 
235  if (obj.isArray()) {
236  quint32 len = obj.property("length").toUInt32();
237  v.setCapacity(len);
238  for (quint32 i = 0; i < len; ++i)
239  v << obj.property(i).toNumber();
240  }
241 }
242 
244 void VectorClass::resize(QDaqVector &ba, int newSize)
245 {
246  int oldSize = ba.size();
247  ba.setCapacity(newSize);
248  if (newSize > oldSize)
249  engine()->reportAdditionalMemoryCost(newSize - oldSize);
250 }
252 
253 
254 
255 VectorClassPropertyIterator::VectorClassPropertyIterator(const QScriptValue &object, const QList<QScriptString> &lst)
256  : QScriptClassPropertyIterator(object), m_names(lst), m_offset(lst.size())
257 {
258  toFront();
259 }
260 
261 VectorClassPropertyIterator::~VectorClassPropertyIterator()
262 {
263 }
264 
266 bool VectorClassPropertyIterator::hasNext() const
267 {
268  QDaqVector *ba = qscriptvalue_cast<QDaqVector*>(object().data());
269  return m_index < ba->size() + m_offset;
270 }
271 
272 void VectorClassPropertyIterator::next()
273 {
274  m_last = m_index;
275  ++m_index;
276 }
277 
278 bool VectorClassPropertyIterator::hasPrevious() const
279 {
280  return (m_index > 0);
281 }
282 
283 void VectorClassPropertyIterator::previous()
284 {
285  --m_index;
286  m_last = m_index;
287 }
288 
289 void VectorClassPropertyIterator::toFront()
290 {
291  m_index = 0;
292  m_last = -1;
293 }
294 
295 void VectorClassPropertyIterator::toBack()
296 {
297  QDaqVector *ba = qscriptvalue_cast<QDaqVector*>(object().data());
298  m_index = ba->size()+m_offset;
299  m_last = -1;
300 }
301 
302 QScriptString VectorClassPropertyIterator::name() const
303 {
304  if (m_last<m_offset && m_last>=0) return m_names.at(m_last);
305  else
306  return object().engine()->toStringHandle(QString::number(m_last-m_offset));
307 }
308 
309 uint VectorClassPropertyIterator::id() const
310 {
311  return m_last-m_offset;
312 }
void setCapacity(int c)
Set the capacity.
Definition: QDaqVector.h:75
int size() const
Return the number of elememts stored in the buffer.
Definition: QDaqVector.h:64
The prototype for the Vector class.
A buffer for storing double numbers.
Definition: QDaqVector.h:40
double get(int i) const
Get the i-th element.
Definition: QDaqVector.h:79
void setCircular(bool on)
Set circular on or off.
Definition: QDaqVector.h:71
bool isCircular() const
Return true if Circular.
Definition: QDaqVector.h:69
int capacity() const
Return the currently allocated memory capacity (in number of elements).
Definition: QDaqVector.h:73