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