Update SQUIRREL to 2.2.5
[supertux.git] / external / squirrel / squirrel / sqclass.h
1 /*      see copyright notice in squirrel.h */\r
2 #ifndef _SQCLASS_H_\r
3 #define _SQCLASS_H_\r
4 \r
5 struct SQInstance;\r
6 \r
7 struct SQClassMember {\r
8         SQClassMember(){}\r
9         SQClassMember(const SQClassMember &o) {\r
10                 val = o.val;\r
11                 attrs = o.attrs;\r
12         }\r
13         SQObjectPtr val;\r
14         SQObjectPtr attrs;\r
15 };\r
16 \r
17 typedef sqvector<SQClassMember> SQClassMemberVec;\r
18 \r
19 #define MEMBER_TYPE_METHOD 0x01000000\r
20 #define MEMBER_TYPE_FIELD 0x02000000\r
21 \r
22 #define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)\r
23 #define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)\r
24 #define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))\r
25 #define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))\r
26 #define _member_type(o) (_integer(o)&0xFF000000)\r
27 #define _member_idx(o) (_integer(o)&0x00FFFFFF)\r
28 \r
29 struct SQClass : public CHAINABLE_OBJ\r
30 {\r
31         SQClass(SQSharedState *ss,SQClass *base);\r
32 public:\r
33         static SQClass* Create(SQSharedState *ss,SQClass *base) {\r
34                 SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));\r
35                 new (newclass) SQClass(ss, base);\r
36                 return newclass;\r
37         }\r
38         ~SQClass();\r
39         bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);\r
40         bool Get(const SQObjectPtr &key,SQObjectPtr &val) {\r
41                 if(_members->Get(key,val)) {\r
42                         if(_isfield(val)) {\r
43                                 SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;\r
44                                 val = _realval(o);\r
45                         }\r
46                         else {\r
47                                 val = _methods[_member_idx(val)].val;\r
48                         }\r
49                         return true;\r
50                 }\r
51                 return false;\r
52         }\r
53         bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);\r
54         bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);\r
55         void Lock() { _locked = true; if(_base) _base->Lock(); }\r
56         void Release() { \r
57                 if (_hook) { _hook(_typetag,0);}\r
58                 sq_delete(this, SQClass);       \r
59         }\r
60         void Finalize();\r
61 #ifndef NO_GARBAGE_COLLECTOR\r
62         void Mark(SQCollectable ** );\r
63 #endif\r
64         SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
65         SQInstance *CreateInstance();\r
66         SQTable *_members;\r
67         SQClass *_base;\r
68         SQClassMemberVec _defaultvalues;\r
69         SQClassMemberVec _methods;\r
70         SQObjectPtrVec _metamethods;\r
71         SQObjectPtr _attributes;\r
72         SQUserPointer _typetag;\r
73         SQRELEASEHOOK _hook;\r
74         bool _locked;\r
75         SQInteger _udsize;\r
76 };\r
77 \r
78 #define calcinstancesize(_theclass_) \\r
79         (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))\r
80 \r
81 struct SQInstance : public SQDelegable \r
82 {\r
83         void Init(SQSharedState *ss);\r
84         SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);\r
85         SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);\r
86 public:\r
87         static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {\r
88                 \r
89                 SQInteger size = calcinstancesize(theclass);\r
90                 SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
91                 new (newinst) SQInstance(ss, theclass,size);\r
92                 if(theclass->_udsize) {\r
93                         newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);\r
94                 }\r
95                 return newinst;\r
96         }\r
97         SQInstance *Clone(SQSharedState *ss)\r
98         {\r
99                 SQInteger size = calcinstancesize(_class);\r
100                 SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
101                 new (newinst) SQInstance(ss, this,size);\r
102                 if(_class->_udsize) {\r
103                         newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);\r
104                 }\r
105                 return newinst;\r
106         }\r
107         ~SQInstance();\r
108         bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {\r
109                 if(_class->_members->Get(key,val)) {\r
110                         if(_isfield(val)) {\r
111                                 SQObjectPtr &o = _values[_member_idx(val)];\r
112                                 val = _realval(o);\r
113                         }\r
114                         else {\r
115                                 val = _class->_methods[_member_idx(val)].val;\r
116                         }\r
117                         return true;\r
118                 }\r
119                 return false;\r
120         }\r
121         bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {\r
122                 SQObjectPtr idx;\r
123                 if(_class->_members->Get(key,idx) && _isfield(idx)) {\r
124             _values[_member_idx(idx)] = val;\r
125                         return true;\r
126                 }\r
127                 return false;\r
128         }\r
129         void Release() {\r
130                 _uiRef++;\r
131                 if (_hook) { _hook(_userpointer,0);}\r
132                 _uiRef--;\r
133                 if(_uiRef > 0) return;\r
134                 SQInteger size = _memsize;\r
135                 this->~SQInstance();\r
136                 SQ_FREE(this, size);\r
137         }\r
138         void Finalize();\r
139 #ifndef NO_GARBAGE_COLLECTOR \r
140         void Mark(SQCollectable ** );\r
141 #endif\r
142         bool InstanceOf(SQClass *trg);\r
143         bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);\r
144 \r
145         SQClass *_class;\r
146         SQUserPointer _userpointer;\r
147         SQRELEASEHOOK _hook;\r
148         SQInteger _memsize;\r
149         SQObjectPtr _values[1];\r
150 };\r
151 \r
152 #endif //_SQCLASS_H_\r