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