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