squirrel update
[supertux.git] / src / 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 SQClassMemeber {\r
8         SQClassMemeber(){}\r
9         SQClassMemeber(const SQClassMemeber &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<SQClassMemeber> SQClassMemeberVec;\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(const SQObjectPtr &key,const SQObjectPtr &val);\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() { sq_delete(this, SQClass);      }\r
57         void Finalize();\r
58         void Mark(SQCollectable ** );\r
59         SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
60         SQInstance *CreateInstance();\r
61         SQTable *_members;\r
62         //SQTable *_properties;\r
63         SQClass *_base;\r
64         SQClassMemeberVec _defaultvalues;\r
65         SQClassMemeberVec _methods;\r
66         SQObjectPtrVec _metamethods;\r
67         SQObjectPtr _attributes;\r
68         SQUserPointer _typetag;\r
69         bool _locked;\r
70 };\r
71 \r
72 #define calcinstancesize(_theclass_) \\r
73         (sizeof(SQInstance)+(sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))\r
74 struct SQInstance : public SQDelegable \r
75 {\r
76         void Init(SQSharedState *ss);\r
77         SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);\r
78         SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);\r
79 public:\r
80         static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {\r
81                 \r
82                 SQInteger size = calcinstancesize(theclass);\r
83                 SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
84                 new (newinst) SQInstance(ss, theclass,size);\r
85                 return newinst;\r
86         }\r
87         SQInstance *Clone(SQSharedState *ss)\r
88         {\r
89                 SQInteger size = calcinstancesize(_class);\r
90                 SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
91                 new (newinst) SQInstance(ss, this,size);\r
92                 return newinst;\r
93         }\r
94         ~SQInstance();\r
95         bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {\r
96                 if(_class->_members->Get(key,val)) {\r
97                         if(_isfield(val)) {\r
98                                 SQObjectPtr &o = _values[_member_idx(val)];\r
99                                 val = _realval(o);\r
100                         }\r
101                         else {\r
102                                 val = _class->_methods[_member_idx(val)].val;\r
103                         }\r
104                         return true;\r
105                 }\r
106                 return false;\r
107         }\r
108         bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {\r
109                 SQObjectPtr idx;\r
110                 if(_class->_members->Get(key,idx) && _isfield(idx)) {\r
111             _values[_member_idx(idx)] = val;\r
112                         return true;\r
113                 }\r
114                 return false;\r
115         }\r
116         void Release() { \r
117                 if (_hook) { _hook(_userpointer,0);}\r
118                 SQInteger size = _memsize;\r
119                 this->~SQInstance();\r
120                 SQ_FREE(this, size);\r
121         }\r
122         void Finalize();\r
123         void Mark(SQCollectable ** );\r
124         bool InstanceOf(SQClass *trg);\r
125         bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);\r
126 \r
127         SQClass *_class;\r
128         SQUserPointer _userpointer;\r
129         SQRELEASEHOOK _hook;\r
130         SQUnsignedInteger _nvalues;\r
131         SQInteger _memsize;\r
132         SQObjectPtr _values[1];\r
133 };\r
134 \r
135 #endif //_SQCLASS_H_\r