updated squirrel version
[supertux.git] / src / squirrel / squirrel / sqobject.h
1 /*      see copyright notice in squirrel.h */
2 #ifndef _SQOBJECT_H_
3 #define _SQOBJECT_H_
4
5 #include "squtils.h"
6
7 #define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
8 #define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
9 #define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
10
11 struct SQSharedState;
12
13 enum SQMetaMethod{
14         MT_ADD=0,
15         MT_SUB=1,
16         MT_MUL=2,
17         MT_DIV=3,
18         MT_UNM=4,
19         MT_MODULO=5,
20         MT_SET=6,
21         MT_GET=7,
22         MT_TYPEOF=8,
23         MT_NEXTI=9,
24         MT_CMP=10,
25         MT_CALL=11,
26         MT_CLONED=12,
27         MT_NEWSLOT=13,
28         MT_DELSLOT=14,
29         MT_LAST = 15,
30 };
31
32 #define MM_ADD          _SC("_add")
33 #define MM_SUB          _SC("_sub")
34 #define MM_MUL          _SC("_mul")
35 #define MM_DIV          _SC("_div")
36 #define MM_UNM          _SC("_unm")
37 #define MM_MODULO       _SC("_modulo")
38 #define MM_SET          _SC("_set")
39 #define MM_GET          _SC("_get")
40 #define MM_TYPEOF       _SC("_typeof")
41 #define MM_NEXTI        _SC("_nexti")
42 #define MM_CMP          _SC("_cmp")
43 #define MM_CALL         _SC("_call")
44 #define MM_CLONED       _SC("_cloned")
45 #define MM_NEWSLOT      _SC("_newslot")
46 #define MM_DELSLOT      _SC("_delslot")
47
48 #define MINPOWER2 4
49
50 struct SQRefCounted
51 {
52         unsigned int _uiRef;
53         virtual void Release()=0;
54 };
55
56 struct SQObjectPtr;
57
58 #define __AddRef(type,unval) if(ISREFCOUNTED(type))     \
59                 { \
60                         unval.pRefCounted->_uiRef++; \
61                 }  
62
63 #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0))      \
64                 {       \
65                         unval.pRefCounted->Release();   \
66                 }
67
68 #define __ObjRelease(obj) { \
69         if((obj)) {     \
70                 (obj)->_uiRef--; \
71                 if((obj)->_uiRef == 0) \
72                         (obj)->Release(); \
73                 (obj) = NULL;   \
74         } \
75 }
76
77 #define __ObjAddRef(obj) { \
78         (obj)->_uiRef++; \
79 }
80
81 #define type(obj) ((obj)._type)
82 #define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
83 #define raw_type(obj) _RAW_TYPE((obj)._type)
84
85 #define _integer(obj) ((obj)._unVal.nInteger)
86 #define _float(obj) ((obj)._unVal.fFloat)
87 #define _string(obj) ((obj)._unVal.pString)
88 #define _table(obj) ((obj)._unVal.pTable)
89 #define _array(obj) ((obj)._unVal.pArray)
90 #define _closure(obj) ((obj)._unVal.pClosure)
91 #define _generator(obj) ((obj)._unVal.pGenerator)
92 #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
93 #define _userdata(obj) ((obj)._unVal.pUserData)
94 #define _userpointer(obj) ((obj)._unVal.pUserPointer)
95 #define _thread(obj) ((obj)._unVal.pThread)
96 #define _funcproto(obj) ((obj)._unVal.pFunctionProto)
97 #define _class(obj) ((obj)._unVal.pClass)
98 #define _instance(obj) ((obj)._unVal.pInstance)
99 #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
100 #define _rawval(obj) ((obj)._unVal.pRefCounted)
101
102 #define _stringval(obj) (obj)._unVal.pString->_val
103 #define _userdataval(obj) (obj)._unVal.pUserData->_val
104
105 #define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
106 #define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
107 /////////////////////////////////////////////////////////////////////////////////////
108 /////////////////////////////////////////////////////////////////////////////////////
109 struct SQObjectPtr : public SQObject
110 {
111         SQObjectPtr()
112         {
113                 _type=OT_NULL;
114                 _unVal.pUserPointer=NULL;
115         }
116         SQObjectPtr(const SQObjectPtr &o)
117         {
118                 _type=o._type;
119                 _unVal=o._unVal;
120                 __AddRef(_type,_unVal);
121         }
122         SQObjectPtr(const SQObject &o)
123         {
124                 _type=o._type;
125                 _unVal=o._unVal;
126                 __AddRef(_type,_unVal);
127         }
128         SQObjectPtr(SQTable *pTable)
129         {
130                 _type=OT_TABLE;
131                 _unVal.pTable=pTable;
132                 assert(_unVal.pTable);
133                 __AddRef(_type,_unVal);
134         }
135         SQObjectPtr(SQClass *pClass)
136         {
137                 _type=OT_CLASS;
138                 _unVal.pClass=pClass;
139                 assert(_unVal.pClass);
140                 __AddRef(_type,_unVal);
141         }
142         SQObjectPtr(SQInstance *pInstance)
143         {
144                 _type=OT_INSTANCE;
145                 _unVal.pInstance=pInstance;
146                 assert(_unVal.pInstance);
147                 __AddRef(_type,_unVal);
148         }
149         SQObjectPtr(SQArray *pArray)
150         {
151                 _type=OT_ARRAY;
152                 _unVal.pArray=pArray;
153                 assert(_unVal.pArray);
154                 __AddRef(_type,_unVal);
155         }
156         SQObjectPtr(SQClosure *pClosure)
157         {
158                 _type=OT_CLOSURE;
159                 _unVal.pClosure=pClosure;
160                 assert(_unVal.pClosure);
161                 __AddRef(_type,_unVal);
162         }
163         SQObjectPtr(SQGenerator *pGenerator)
164         {
165                 _type=OT_GENERATOR;
166                 _unVal.pGenerator=pGenerator;
167                 assert(_unVal.pGenerator);
168                 __AddRef(_type,_unVal);
169         }
170         SQObjectPtr(SQNativeClosure *pNativeClosure)
171         {
172                 _type=OT_NATIVECLOSURE;
173                 _unVal.pNativeClosure=pNativeClosure;
174                 assert(_unVal.pNativeClosure);
175                 __AddRef(_type,_unVal);
176         }
177         SQObjectPtr(SQString *pString)
178         {
179                 _type=OT_STRING;
180                 _unVal.pString=pString;
181                 assert(_unVal.pString);
182                 __AddRef(_type,_unVal);
183         }
184         SQObjectPtr(SQUserData *pUserData)
185         {
186                 _type=OT_USERDATA;
187                 _unVal.pUserData=pUserData;
188                 assert(_unVal.pUserData);
189                 __AddRef(_type,_unVal);
190         }
191         SQObjectPtr(SQVM *pThread)
192         {
193                 _type=OT_THREAD;
194                 _unVal.pThread=pThread;
195                 assert(_unVal.pThread);
196                 __AddRef(_type,_unVal);
197         }
198         SQObjectPtr(SQFunctionProto *pFunctionProto)
199         {
200                 _type=OT_FUNCPROTO;
201                 _unVal.pFunctionProto=pFunctionProto;
202                 assert(_unVal.pFunctionProto);
203                 __AddRef(_type,_unVal);
204         }
205         SQObjectPtr(SQInteger nInteger)
206         {
207                 _type=OT_INTEGER;
208                 _unVal.nInteger=nInteger;
209         }
210         SQObjectPtr(SQFloat fFloat)
211         {
212                 _type=OT_FLOAT;
213                 _unVal.fFloat=fFloat;
214         }
215         SQObjectPtr(bool bBool)
216         {
217                 _type = OT_BOOL;
218                 _unVal.nInteger = bBool?1:0;
219         }
220         SQObjectPtr(SQUserPointer pUserPointer)
221         {
222                 _type=OT_USERPOINTER;
223                 _unVal.pUserPointer=pUserPointer;
224         }
225         ~SQObjectPtr()
226         {
227                 __Release(_type,_unVal);
228         }
229         inline void Null()
230         {
231                 __Release(_type,_unVal);
232                 _type=OT_NULL;
233                 _unVal.pUserPointer=NULL;
234         }
235         inline SQObjectPtr& operator=(const SQObjectPtr& obj)
236         { 
237                 SQObjectType tOldType;
238                 SQObjectValue unOldVal;
239                 tOldType=_type;
240                 unOldVal=_unVal;
241                 _unVal = obj._unVal;
242                 _type = obj._type;
243                 __AddRef(_type,_unVal);
244                 __Release(tOldType,unOldVal);
245                 return *this;
246         }
247         inline SQObjectPtr& operator=(const SQObject& obj)
248         { 
249                 SQObjectType tOldType;
250                 SQObjectValue unOldVal;
251                 tOldType=_type;
252                 unOldVal=_unVal;
253                 _unVal = obj._unVal;
254                 _type = obj._type;
255                 __AddRef(_type,_unVal);
256                 __Release(tOldType,unOldVal);
257                 return *this;
258         }
259         private:
260                 SQObjectPtr(const SQChar *){} //safety
261 };
262 /////////////////////////////////////////////////////////////////////////////////////
263 #ifndef NO_GARBAGE_COLLECTOR
264 #define MARK_FLAG 0x80000000
265 struct SQCollectable : public SQRefCounted {
266         SQCollectable *_next;
267         SQCollectable *_prev;
268         SQSharedState *_sharedstate;
269         virtual void Release()=0;
270         virtual void Mark(SQCollectable **chain)=0;
271         void UnMark();
272         virtual void Finalize()=0;
273         static void AddToChain(SQCollectable **chain,SQCollectable *c);
274         static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
275 };
276
277
278 #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
279 #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
280 #define CHAINABLE_OBJ SQCollectable
281 #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
282 #else
283
284 #define ADD_TO_CHAIN(chain,obj) ((void)0)
285 #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
286 #define CHAINABLE_OBJ SQRefCounted
287 #define INIT_CHAIN() ((void)0)
288 #endif
289
290 struct SQDelegable : public CHAINABLE_OBJ {
291         virtual bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);
292         SQTable *_delegate;
293 };
294
295 unsigned int TranslateIndex(const SQObjectPtr &idx);
296 typedef sqvector<SQObjectPtr> SQObjectPtrVec;
297 typedef sqvector<int> SQIntVec;
298
299 #endif //_SQOBJECT_H_