fix cr/lfs and remove trailing whitespaces...
[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                 __Release(_type,_unVal);
262                 _type=OT_NULL;
263                 _unVal.pUserPointer=NULL;
264         }
265         inline SQObjectPtr& operator=(const SQObjectPtr& obj)
266         {
267                 SQObjectType tOldType;
268                 SQObjectValue unOldVal;
269                 tOldType=_type;
270                 unOldVal=_unVal;
271                 _unVal = obj._unVal;
272                 _type = obj._type;
273                 __AddRef(_type,_unVal);
274                 __Release(tOldType,unOldVal);
275                 return *this;
276         }
277         inline SQObjectPtr& operator=(const SQObject& obj)
278         {
279                 SQObjectType tOldType;
280                 SQObjectValue unOldVal;
281                 tOldType=_type;
282                 unOldVal=_unVal;
283                 _unVal = obj._unVal;
284                 _type = obj._type;
285                 __AddRef(_type,_unVal);
286                 __Release(tOldType,unOldVal);
287                 return *this;
288         }
289         private:
290                 SQObjectPtr(const SQChar *){} //safety
291 };
292 /////////////////////////////////////////////////////////////////////////////////////
293 #ifndef NO_GARBAGE_COLLECTOR
294 #define MARK_FLAG 0x80000000
295 struct SQCollectable : public SQRefCounted {
296         SQCollectable *_next;
297         SQCollectable *_prev;
298         SQSharedState *_sharedstate;
299         virtual void Release()=0;
300         virtual void Mark(SQCollectable **chain)=0;
301         void UnMark();
302         virtual void Finalize()=0;
303         static void AddToChain(SQCollectable **chain,SQCollectable *c);
304         static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
305 };
306
307
308 #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
309 #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
310 #define CHAINABLE_OBJ SQCollectable
311 #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
312 #else
313
314 #define ADD_TO_CHAIN(chain,obj) ((void)0)
315 #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
316 #define CHAINABLE_OBJ SQRefCounted
317 #define INIT_CHAIN() ((void)0)
318 #endif
319
320 struct SQDelegable : public CHAINABLE_OBJ {
321         bool SetDelegate(SQTable *m);
322         virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
323         SQTable *_delegate;
324 };
325
326 SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
327 typedef sqvector<SQObjectPtr> SQObjectPtrVec;
328 typedef sqvector<SQInteger> SQIntVec;
329
330
331 #endif //_SQOBJECT_H_