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