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