sqrat  0.9
sqrat
 All Classes Functions Variables Enumerations Enumerator Pages
sqratArray.h
1 //
2 // SqratArray: Array Binding
3 //
4 
5 //
6 // Copyright 2011 Alston Chen
7 //
8 // This software is provided 'as-is', without any express or implied
9 // warranty. In no event will the authors be held liable for any damages
10 // arising from the use of this software.
11 //
12 // Permission is granted to anyone to use this software for any purpose,
13 // including commercial applications, and to alter it and redistribute it
14 // freely, subject to the following restrictions:
15 //
16 // 1. The origin of this software must not be misrepresented; you must not
17 // claim that you wrote the original software. If you use this software
18 // in a product, an acknowledgment in the product documentation would be
19 // appreciated but is not required.
20 //
21 // 2. Altered source versions must be plainly marked as such, and must not be
22 // misrepresented as being the original software.
23 //
24 // 3. This notice may not be removed or altered from any source
25 // distribution.
26 //
27 
28 #if !defined(_SCRAT_ARRAY_H_)
29 #define _SCRAT_ARRAY_H_
30 
31 #include <squirrel.h>
32 #include <string.h>
33 
34 #include "sqratObject.h"
35 #include "sqratFunction.h"
36 #include "sqratGlobalMethods.h"
37 
38 namespace Sqrat {
39 
43 class ArrayBase : public Object {
44 public:
45 
52  ArrayBase(HSQUIRRELVM v = DefaultVM::Get()) : Object(v, true) {
53  }
54 
61  ArrayBase(const Object& obj) : Object(obj) {
62  }
63 
71  ArrayBase(HSQOBJECT o, HSQUIRRELVM v = DefaultVM::Get()) : Object(o, v) {
72  }
73 
84  void Bind(const SQInteger index, Object& obj) {
85  sq_pushobject(vm, GetObject());
86  sq_pushinteger(vm, index);
87  sq_pushobject(vm, obj.GetObject());
88  sq_set(vm, -3);
89  sq_pop(vm,1); // pop array
90  }
91 
101  ArrayBase& SquirrelFunc(const SQInteger index, SQFUNCTION func) {
102  sq_pushobject(vm, GetObject());
103  sq_pushinteger(vm, index);
104  sq_newclosure(vm, func, 0);
105  sq_set(vm, -3);
106  sq_pop(vm,1); // pop array
107  return *this;
108  }
109 
121  template<class V>
122  ArrayBase& SetValue(const SQInteger index, const V& val) {
123  sq_pushobject(vm, GetObject());
124  sq_pushinteger(vm, index);
125  PushVar(vm, val);
126  sq_set(vm, -3);
127  sq_pop(vm,1); // pop array
128  return *this;
129  }
130 
142  template<class V>
143  ArrayBase& SetInstance(const SQInteger index, V* val) {
144  BindInstance<V>(index, val, false);
145  return *this;
146  }
147 
159  template<class F>
160  ArrayBase& Func(const SQInteger index, F method) {
161  BindFunc(index, &method, sizeof(method), SqGlobalFunc(method));
162  return *this;
163  }
164 
165  //template<class F>
166  //ArrayBase& Overload(const SQChar* name, F method) {
167  // BindOverload(name, &method, sizeof(method), SqGlobalFunc(method), SqOverloadFunc(method), SqGetArgCount(method));
168  // return *this;
169  //}
170 
184  template <typename T>
186  {
187  sq_pushobject(vm, obj);
188  sq_pushinteger(vm, index);
189 #if !defined (SCRAT_NO_ERROR_CHECKING)
190  if (SQ_FAILED(sq_get(vm, -2))) {
191  sq_pop(vm, 1);
192  Error::Instance().Throw(vm, _SC("illegal index"));
193  return SharedPtr<T>();
194  }
195 #else
196  sq_get(vm, -2);
197 #endif
198  Var<SharedPtr<T> > element(vm, -1);
199 #if !defined (SCRAT_NO_ERROR_CHECKING)
200  if (Error::Instance().Occurred(vm)) {
201  sq_pop(vm, 2);
202  return SharedPtr<T>();
203  }
204 #endif
205  sq_pop(vm, 2);
206  return element.value;
207  }
208 
217  Function GetFunction(const SQInteger index) {
218  HSQOBJECT funcObj;
219  sq_pushobject(vm, GetObject());
220  sq_pushinteger(vm, index);
221 #if !defined (SCRAT_NO_ERROR_CHECKING)
222  if(SQ_FAILED(sq_get(vm, -2))) {
223  sq_pop(vm, 1);
224  return Function();
225  }
226  SQObjectType value_type = sq_gettype(vm, -1);
227  if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) {
228  sq_pop(vm, 2);
229  return Function();
230  }
231 #else
232  sq_get(vm, -2);
233 #endif
234  sq_getstackobj(vm, -1, &funcObj);
235  Function ret(vm, GetObject(), funcObj); // must addref before the pop!
236  sq_pop(vm, 2);
237  return ret;
238  }
239 
252  template <typename T>
253  void GetArray(T* array, int size)
254  {
255  HSQOBJECT value = GetObject();
256  sq_pushobject(vm, value);
257 #if !defined (SCRAT_NO_ERROR_CHECKING)
258  if (size > sq_getsize(vm, -1)) {
259  sq_pop(vm, 1);
260  Error::Instance().Throw(vm, _SC("array buffer size too big"));
261  return;
262  }
263 #endif
264  sq_pushnull(vm);
265  SQInteger i;
266  while (SQ_SUCCEEDED(sq_next(vm, -2))) {
267  sq_getinteger(vm, -2, &i);
268  if (i >= size) break;
269  Var<const T&> element(vm, -1);
270  sq_pop(vm, 2);
271 #if !defined (SCRAT_NO_ERROR_CHECKING)
272  if (Error::Instance().Occurred(vm)) {
273  sq_pop(vm, 2);
274  return;
275  }
276 #endif
277  array[i] = element.value;
278  }
279  sq_pop(vm, 2); // pops the null iterator and the array object
280  }
281 
292  template<class V>
293  ArrayBase& Append(const V& val) {
294  sq_pushobject(vm, GetObject());
295  PushVar(vm, val);
296  sq_arrayappend(vm, -2);
297  sq_pop(vm,1); // pop array
298  return *this;
299  }
300 
311  template<class V>
312  ArrayBase& Append(V* val) {
313  sq_pushobject(vm, GetObject());
314  PushVar(vm, val);
315  sq_arrayappend(vm, -2);
316  sq_pop(vm,1); // pop array
317  return *this;
318  }
319 
331  template<class V>
332  ArrayBase& Insert(const SQInteger destpos, const V& val) {
333  sq_pushobject(vm, GetObject());
334  PushVar(vm, val);
335  sq_arrayinsert(vm, -2, destpos);
336  sq_pop(vm,1); // pop array
337  return *this;
338  }
339 
351  template<class V>
352  ArrayBase& Insert(const SQInteger destpos, V* val) {
353  sq_pushobject(vm, GetObject());
354  PushVar(vm, val);
355  sq_arrayinsert(vm, -2, destpos);
356  sq_pop(vm,1); // pop array
357  return *this;
358  }
359 
367  HSQOBJECT slotObj;
368  sq_pushobject(vm, GetObject());
369  if(SQ_FAILED(sq_arraypop(vm, -1, true))) {
370  sq_pop(vm, 1);
371  return Object(); // Return a NULL object
372  } else {
373  sq_getstackobj(vm, -1, &slotObj);
374  Object ret(slotObj, vm);
375  sq_pop(vm, 2);
376  return ret;
377  }
378  }
379 
388  ArrayBase& Remove(const SQInteger itemidx) {
389  sq_pushobject(vm, GetObject());
390  sq_arrayremove(vm, -1, itemidx);
391  sq_pop(vm,1); // pop array
392  return *this;
393  }
394 
403  ArrayBase& Resize(const SQInteger newsize) {
404  sq_pushobject(vm, GetObject());
405  sq_arrayresize(vm, -1, newsize);
406  sq_pop(vm,1); // pop array
407  return *this;
408  }
409 
417  sq_pushobject(vm, GetObject());
418  sq_arrayreverse(vm, -1);
419  sq_pop(vm,1); // pop array
420  return *this;
421  }
422 
429  SQInteger Length() const
430  {
431  sq_pushobject(vm, obj);
432  SQInteger r = sq_getsize(vm, -1);
433  sq_pop(vm, 1);
434  return r;
435  }
436 };
437 
441 class Array : public ArrayBase {
442 public:
443 
451  Array() {
452  }
453 
461  Array(HSQUIRRELVM v, const SQInteger size = 0) : ArrayBase(v) {
462  sq_newarray(vm, size);
463  sq_getstackobj(vm,-1,&obj);
464  sq_addref(vm, &obj);
465  sq_pop(vm,1);
466  }
467 
474  Array(const Object& obj) : ArrayBase(obj) {
475  }
476 
484  Array(HSQOBJECT o, HSQUIRRELVM v = DefaultVM::Get()) : ArrayBase(o, v) {
485  }
486 };
487 
491 template<>
492 struct Var<Array> {
493 
495 
506  Var(HSQUIRRELVM vm, SQInteger idx) {
507  HSQOBJECT obj;
508  sq_resetobject(&obj);
509  sq_getstackobj(vm,idx,&obj);
510  value = Array(obj, vm);
511 #if !defined (SCRAT_NO_ERROR_CHECKING)
512  SQObjectType value_type = sq_gettype(vm, idx);
513  if (value_type != OT_ARRAY) {
514  Error::Instance().Throw(vm, Sqrat::Error::FormatTypeError(vm, idx, _SC("array")));
515  }
516 #endif
517  }
518 
526  static void push(HSQUIRRELVM vm, const Array& value) {
527  HSQOBJECT obj;
528  sq_resetobject(&obj);
529  obj = value.GetObject();
530  sq_pushobject(vm,obj);
531  }
532 };
533 
537 template<>
538 struct Var<Array&> {
539 
541 
552  Var(HSQUIRRELVM vm, SQInteger idx) {
553  HSQOBJECT obj;
554  sq_resetobject(&obj);
555  sq_getstackobj(vm,idx,&obj);
556  value = Array(obj, vm);
557  SQObjectType value_type = sq_gettype(vm, idx);
558 #if !defined (SCRAT_NO_ERROR_CHECKING)
559  if (value_type != OT_ARRAY) {
560  Error::Instance().Throw(vm, Sqrat::Error::FormatTypeError(vm, idx, _SC("array")));
561  }
562 #endif
563  }
564 
572  static void push(HSQUIRRELVM vm, Array value) {
573  HSQOBJECT obj;
574  sq_resetobject(&obj);
575  obj = value.GetObject();
576  sq_pushobject(vm,obj);
577  }
578 };
579 
580 }
581 
582 #endif
static HSQUIRRELVM Get()
Definition: sqratUtil.h:92
Array(const Object &obj)
Definition: sqratArray.h:474
T value
The actual value of get operations.
Definition: sqratTypes.h:152
static void push(HSQUIRRELVM vm, Array value)
Definition: sqratArray.h:572
ArrayBase(HSQUIRRELVM v=DefaultVM::Get())
Definition: sqratArray.h:52
Definition: sqratTypes.h:150
ArrayBase & Resize(const SQInteger newsize)
Definition: sqratArray.h:403
static string FormatTypeError(HSQUIRRELVM vm, SQInteger idx, const string &expectedType)
Definition: sqratUtil.h:149
ArrayBase(const Object &obj)
Definition: sqratArray.h:61
ArrayBase & Reverse()
Definition: sqratArray.h:416
ArrayBase & SquirrelFunc(const SQInteger index, SQFUNCTION func)
Definition: sqratArray.h:101
ArrayBase & Insert(const SQInteger destpos, const V &val)
Definition: sqratArray.h:332
Var(HSQUIRRELVM vm, SQInteger idx)
Definition: sqratArray.h:506
Array(HSQUIRRELVM v, const SQInteger size=0)
Definition: sqratArray.h:461
Definition: sqratTypes.h:331
ArrayBase & Append(V *val)
Definition: sqratArray.h:312
ArrayBase & Remove(const SQInteger itemidx)
Definition: sqratArray.h:388
Array value
The actual value of get operations.
Definition: sqratArray.h:540
ArrayBase & Func(const SQInteger index, F method)
Definition: sqratArray.h:160
ArrayBase & SetInstance(const SQInteger index, V *val)
Definition: sqratArray.h:143
Represents a function in Squirrel.
Definition: sqratFunction.h:40
Array()
Definition: sqratArray.h:451
void Bind(const SQInteger index, Object &obj)
Definition: sqratArray.h:84
Array value
The actual value of get operations.
Definition: sqratArray.h:494
Function GetFunction(const SQInteger index)
Definition: sqratArray.h:217
Definition: sqratUtil.h:291
virtual HSQOBJECT GetObject() const
Definition: sqratObject.h:182
SQInteger Length() const
Definition: sqratArray.h:429
Object()
Definition: sqratObject.h:65
Definition: sqratObject.h:48
static Error & Instance()
Definition: sqratUtil.h:134
The base class for Array that implements almost all of its functionality.
Definition: sqratArray.h:43
ArrayBase(HSQOBJECT o, HSQUIRRELVM v=DefaultVM::Get())
Definition: sqratArray.h:71
void Throw(HSQUIRRELVM vm, const string &err)
Definition: sqratUtil.h:210
const T & value
The actual value of get operations.
Definition: sqratTypes.h:333
Object Pop()
Definition: sqratArray.h:366
ArrayBase & Insert(const SQInteger destpos, V *val)
Definition: sqratArray.h:352
SharedPtr< T > GetValue(int index)
Definition: sqratArray.h:185
ArrayBase & Append(const V &val)
Definition: sqratArray.h:293
static void push(HSQUIRRELVM vm, const Array &value)
Definition: sqratArray.h:526
Array(HSQOBJECT o, HSQUIRRELVM v=DefaultVM::Get())
Definition: sqratArray.h:484
ArrayBase & SetValue(const SQInteger index, const V &val)
Definition: sqratArray.h:122
Represents an array in Squirrel.
Definition: sqratArray.h:441
void GetArray(T *array, int size)
Definition: sqratArray.h:253
Var(HSQUIRRELVM vm, SQInteger idx)
Definition: sqratArray.h:552