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