New grow and skid sounds from remaxim
[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.raw)
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                 SQ_OBJECT_RAWINIT()
134                 _type=OT_NULL;
135                 _unVal.pUserPointer=NULL;
136         }
137         SQObjectPtr(const SQObjectPtr &o)
138         {
139                 SQ_OBJECT_RAWINIT()
140                 _type=o._type;
141                 _unVal=o._unVal;
142                 __AddRef(_type,_unVal);
143         }
144         SQObjectPtr(const SQObject &o)
145         {
146                 SQ_OBJECT_RAWINIT()
147                 _type=o._type;
148                 _unVal=o._unVal;
149                 __AddRef(_type,_unVal);
150         }
151         SQObjectPtr(SQTable *pTable)
152         {
153                 SQ_OBJECT_RAWINIT()
154                 _type=OT_TABLE;
155                 _unVal.pTable=pTable;
156                 assert(_unVal.pTable);
157                 __AddRef(_type,_unVal);
158         }
159         SQObjectPtr(SQClass *pClass)
160         {
161                 SQ_OBJECT_RAWINIT()
162                 _type=OT_CLASS;
163                 _unVal.pClass=pClass;
164                 assert(_unVal.pClass);
165                 __AddRef(_type,_unVal);
166         }
167         SQObjectPtr(SQInstance *pInstance)
168         {
169                 SQ_OBJECT_RAWINIT()
170                 _type=OT_INSTANCE;
171                 _unVal.pInstance=pInstance;
172                 assert(_unVal.pInstance);
173                 __AddRef(_type,_unVal);
174         }
175         SQObjectPtr(SQArray *pArray)
176         {
177                 SQ_OBJECT_RAWINIT()
178                 _type=OT_ARRAY;
179                 _unVal.pArray=pArray;
180                 assert(_unVal.pArray);
181                 __AddRef(_type,_unVal);
182         }
183         SQObjectPtr(SQClosure *pClosure)
184         {
185                 SQ_OBJECT_RAWINIT()
186                 _type=OT_CLOSURE;
187                 _unVal.pClosure=pClosure;
188                 assert(_unVal.pClosure);
189                 __AddRef(_type,_unVal);
190         }
191         SQObjectPtr(SQGenerator *pGenerator)
192         {
193                 SQ_OBJECT_RAWINIT()
194                 _type=OT_GENERATOR;
195                 _unVal.pGenerator=pGenerator;
196                 assert(_unVal.pGenerator);
197                 __AddRef(_type,_unVal);
198         }
199         SQObjectPtr(SQNativeClosure *pNativeClosure)
200         {
201                 SQ_OBJECT_RAWINIT()
202                 _type=OT_NATIVECLOSURE;
203                 _unVal.pNativeClosure=pNativeClosure;
204                 assert(_unVal.pNativeClosure);
205                 __AddRef(_type,_unVal);
206         }
207         SQObjectPtr(SQString *pString)
208         {
209                 SQ_OBJECT_RAWINIT()
210                 _type=OT_STRING;
211                 _unVal.pString=pString;
212                 assert(_unVal.pString);
213                 __AddRef(_type,_unVal);
214         }
215         SQObjectPtr(SQUserData *pUserData)
216         {
217                 SQ_OBJECT_RAWINIT()
218                 _type=OT_USERDATA;
219                 _unVal.pUserData=pUserData;
220                 assert(_unVal.pUserData);
221                 __AddRef(_type,_unVal);
222         }
223         SQObjectPtr(SQVM *pThread)
224         {
225                 SQ_OBJECT_RAWINIT()
226                 _type=OT_THREAD;
227                 _unVal.pThread=pThread;
228                 assert(_unVal.pThread);
229                 __AddRef(_type,_unVal);
230         }
231         SQObjectPtr(SQWeakRef *pWeakRef)
232         {
233                 SQ_OBJECT_RAWINIT()
234                 _type=OT_WEAKREF;
235                 _unVal.pWeakRef=pWeakRef;
236                 assert(_unVal.pWeakRef);
237                 __AddRef(_type,_unVal);
238         }
239         SQObjectPtr(SQFunctionProto *pFunctionProto)
240         {
241                 SQ_OBJECT_RAWINIT()
242                 _type=OT_FUNCPROTO;
243                 _unVal.pFunctionProto=pFunctionProto;
244                 assert(_unVal.pFunctionProto);
245                 __AddRef(_type,_unVal);
246         }
247         SQObjectPtr(SQInteger nInteger)
248         {
249                 SQ_OBJECT_RAWINIT()
250                 _type=OT_INTEGER;
251                 _unVal.nInteger=nInteger;
252         }
253         SQObjectPtr(SQFloat fFloat)
254         {
255                 SQ_OBJECT_RAWINIT()
256                 _type=OT_FLOAT;
257                 _unVal.fFloat=fFloat;
258         }
259         SQObjectPtr(bool bBool)
260         {
261                 SQ_OBJECT_RAWINIT()
262                 _type = OT_BOOL;
263                 _unVal.nInteger = bBool?1:0;
264         }
265         SQObjectPtr(SQUserPointer pUserPointer)
266         {
267                 SQ_OBJECT_RAWINIT()
268                 _type=OT_USERPOINTER;
269                 _unVal.pUserPointer=pUserPointer;
270         }
271         ~SQObjectPtr()
272         {
273                 __Release(_type,_unVal);
274         }
275         inline void Null()
276         {
277                 SQObjectType tOldType;
278                 SQObjectValue unOldVal;
279                 tOldType = _type;
280                 unOldVal = _unVal;
281                 _type = OT_NULL;
282                 _unVal.pUserPointer = NULL;
283                 __Release(tOldType,unOldVal);
284         }
285         inline SQObjectPtr& operator=(SQInteger i)
286         { 
287                 __Release(_type,_unVal);
288                 _unVal.nInteger = i;
289                 _type = OT_INTEGER;
290                 return *this;
291         }
292         inline SQObjectPtr& operator=(SQFloat f)
293         { 
294                 __Release(_type,_unVal);
295                 _unVal.fFloat = f;
296                 _type = OT_FLOAT;
297                 return *this;
298         }
299         inline SQObjectPtr& operator=(const SQObjectPtr& obj)
300         { 
301                 SQObjectType tOldType;
302                 SQObjectValue unOldVal;
303                 tOldType=_type;
304                 unOldVal=_unVal;
305                 _unVal = obj._unVal;
306                 _type = obj._type;
307                 __AddRef(_type,_unVal);
308                 __Release(tOldType,unOldVal);
309                 return *this;
310         }
311         inline SQObjectPtr& operator=(const SQObject& obj)
312         { 
313                 SQObjectType tOldType;
314                 SQObjectValue unOldVal;
315                 tOldType=_type;
316                 unOldVal=_unVal;
317                 _unVal = obj._unVal;
318                 _type = obj._type;
319                 __AddRef(_type,_unVal);
320                 __Release(tOldType,unOldVal);
321                 return *this;
322         }
323         private:
324                 SQObjectPtr(const SQChar *){} //safety
325 };
326 /////////////////////////////////////////////////////////////////////////////////////
327 #ifndef NO_GARBAGE_COLLECTOR
328 #define MARK_FLAG 0x80000000
329 struct SQCollectable : public SQRefCounted {
330         SQCollectable *_next;
331         SQCollectable *_prev;
332         SQSharedState *_sharedstate;
333         virtual void Release()=0;
334         virtual void Mark(SQCollectable **chain)=0;
335         void UnMark();
336         virtual void Finalize()=0;
337         static void AddToChain(SQCollectable **chain,SQCollectable *c);
338         static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
339 };
340
341
342 #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
343 #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
344 #define CHAINABLE_OBJ SQCollectable
345 #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
346 #else
347
348 #define ADD_TO_CHAIN(chain,obj) ((void)0)
349 #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
350 #define CHAINABLE_OBJ SQRefCounted
351 #define INIT_CHAIN() ((void)0)
352 #endif
353
354 struct SQDelegable : public CHAINABLE_OBJ {
355         bool SetDelegate(SQTable *m);
356         virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
357         SQTable *_delegate;
358 };
359
360 SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
361 typedef sqvector<SQObjectPtr> SQObjectPtrVec;
362 typedef sqvector<SQInteger> SQIntVec;
363 const SQChar *GetTypeName(const SQObjectPtr &obj1);
364 const SQChar *IdType2Name(SQObjectType type);
365
366
367
368 #endif //_SQOBJECT_H_