2 see copyright notice in squirrel.h
\r
4 #include "sqpcheader.h"
\r
8 #include "sqfuncproto.h"
\r
9 #include "sqclosure.h"
\r
13 SQClass::SQClass(SQSharedState *ss,SQClass *base)
\r
20 _constructoridx = -1;
\r
22 _constructoridx = _base->_constructoridx;
\r
23 _udsize = _base->_udsize;
\r
24 _defaultvalues.copy(base->_defaultvalues);
\r
25 _methods.copy(base->_methods);
\r
26 _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
\r
29 _members = base?base->_members->Clone() : SQTable::Create(ss,0);
\r
30 __ObjAddRef(_members);
\r
33 ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
\r
36 void SQClass::Finalize() {
\r
38 _defaultvalues.resize(0);
\r
40 _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
\r
41 __ObjRelease(_members);
\r
43 __ObjRelease(_base);
\r
49 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
\r
53 bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
\r
56 bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic;
\r
57 if(_locked && !belongs_to_static_table)
\r
58 return false; //the class already has an instance so cannot be modified
\r
59 if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
\r
61 _defaultvalues[_member_idx(temp)].val = val;
\r
64 if(belongs_to_static_table) {
\r
66 if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
\r
67 (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
\r
68 _metamethods[mmidx] = val;
\r
71 SQObjectPtr theval = val;
\r
72 if(_base && type(val) == OT_CLOSURE) {
\r
73 theval = _closure(val)->Clone();
\r
74 _closure(theval)->_base = _base;
\r
75 __ObjAddRef(_base); //ref for the closure
\r
77 if(type(temp) == OT_NULL) {
\r
79 SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
\r
81 _constructoridx = (SQInteger)_methods.size();
\r
85 _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
\r
86 _methods.push_back(m);
\r
89 _methods[_member_idx(temp)].val = theval;
\r
96 _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
\r
97 _defaultvalues.push_back(m);
\r
101 SQInstance *SQClass::CreateInstance()
\r
103 if(!_locked) Lock();
\r
104 return SQInstance::Create(_opt_ss(this),this);
\r
107 SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
\r
110 SQInteger idx = _members->Next(false,refpos,outkey,oval);
\r
112 if(_ismethod(oval)) {
\r
113 outval = _methods[_member_idx(oval)].val;
\r
116 SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
\r
117 outval = _realval(o);
\r
123 bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
\r
126 if(_members->Get(key,idx)) {
\r
128 _defaultvalues[_member_idx(idx)].attrs = val;
\r
130 _methods[_member_idx(idx)].attrs = val;
\r
136 bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
\r
139 if(_members->Get(key,idx)) {
\r
140 outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
\r
146 ///////////////////////////////////////////////////////////////////////
\r
147 void SQInstance::Init(SQSharedState *ss)
\r
149 _userpointer = NULL;
\r
151 __ObjAddRef(_class);
\r
152 _delegate = _class->_members;
\r
154 ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
\r
157 SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
\r
159 _memsize = memsize;
\r
161 SQUnsignedInteger nvalues = _class->_defaultvalues.size();
\r
162 for(SQUnsignedInteger n = 0; n < nvalues; n++) {
\r
163 new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
\r
168 SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
\r
170 _memsize = memsize;
\r
171 _class = i->_class;
\r
172 SQUnsignedInteger nvalues = _class->_defaultvalues.size();
\r
173 for(SQUnsignedInteger n = 0; n < nvalues; n++) {
\r
174 new (&_values[n]) SQObjectPtr(i->_values[n]);
\r
179 void SQInstance::Finalize()
\r
181 SQUnsignedInteger nvalues = _class->_defaultvalues.size();
\r
182 __ObjRelease(_class);
\r
183 _NULL_SQOBJECT_VECTOR(_values,nvalues);
\r
184 //for(SQUnsignedInteger i = 0; i < nvalues; i++) {
\r
185 // _values[i].Null();
\r
189 SQInstance::~SQInstance()
\r
191 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
\r
192 if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
\r
195 bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
\r
197 if(type(_class->_metamethods[mm]) != OT_NULL) {
\r
198 res = _class->_metamethods[mm];
\r
204 bool SQInstance::InstanceOf(SQClass *trg)
\r
206 SQClass *parent = _class;
\r
207 while(parent != NULL) {
\r
210 parent = parent->_base;
\r