sqclass.cpp
00001
00002
00003
00004 #include "sqpcheader.h"
00005 #include "sqvm.h"
00006 #include "sqtable.h"
00007 #include "sqclass.h"
00008 #include "sqclosure.h"
00009
00010 SQClass::SQClass(SQSharedState *ss,SQClass *base)
00011 {
00012 _base = base;
00013 _typetag = 0;
00014 _hook = NULL;
00015 _udsize = 0;
00016 _metamethods.resize(MT_LAST);
00017 if(_base) {
00018 _defaultvalues.copy(base->_defaultvalues);
00019 _methods.copy(base->_methods);
00020 _metamethods.copy(base->_metamethods);
00021 __ObjAddRef(_base);
00022 }
00023 _members = base?base->_members->Clone() : SQTable::Create(ss,0);
00024 __ObjAddRef(_members);
00025 _locked = false;
00026 INIT_CHAIN();
00027 ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
00028 }
00029
00030 void SQClass::Finalize() {
00031 _attributes = _null_;
00032 _defaultvalues.resize(0);
00033 _methods.resize(0);
00034 _metamethods.resize(0);
00035 __ObjRelease(_members);
00036 if(_base) {
00037 __ObjRelease(_base);
00038 }
00039 }
00040
00041 SQClass::~SQClass()
00042 {
00043 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
00044 Finalize();
00045 }
00046
00047 bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
00048 {
00049 SQObjectPtr temp;
00050 if(_locked)
00051 return false;
00052 if(_members->Get(key,temp) && _isfield(temp))
00053 {
00054 _defaultvalues[_member_idx(temp)].val = val;
00055 return true;
00056 }
00057 if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
00058 SQInteger mmidx;
00059 if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
00060 (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
00061 _metamethods[mmidx] = val;
00062 }
00063 else {
00064 if(type(temp) == OT_NULL) {
00065 SQClassMember m;
00066 m.val = val;
00067 _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
00068 _methods.push_back(m);
00069 }
00070 else {
00071 _methods[_member_idx(temp)].val = val;
00072 }
00073 }
00074 return true;
00075 }
00076 SQClassMember m;
00077 m.val = val;
00078 _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
00079 _defaultvalues.push_back(m);
00080 return true;
00081 }
00082
00083 SQInstance *SQClass::CreateInstance()
00084 {
00085 if(!_locked) Lock();
00086 return SQInstance::Create(_opt_ss(this),this);
00087 }
00088
00089 SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
00090 {
00091 SQObjectPtr oval;
00092 SQInteger idx = _members->Next(false,refpos,outkey,oval);
00093 if(idx != -1) {
00094 if(_ismethod(oval)) {
00095 outval = _methods[_member_idx(oval)].val;
00096 }
00097 else {
00098 SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
00099 outval = _realval(o);
00100 }
00101 }
00102 return idx;
00103 }
00104
00105 bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
00106 {
00107 SQObjectPtr idx;
00108 if(_members->Get(key,idx)) {
00109 if(_isfield(idx))
00110 _defaultvalues[_member_idx(idx)].attrs = val;
00111 else
00112 _methods[_member_idx(idx)].attrs = val;
00113 return true;
00114 }
00115 return false;
00116 }
00117
00118 bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
00119 {
00120 SQObjectPtr idx;
00121 if(_members->Get(key,idx)) {
00122 outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
00123 return true;
00124 }
00125 return false;
00126 }
00127
00129 void SQInstance::Init(SQSharedState *ss)
00130 {
00131 _userpointer = NULL;
00132 _hook = NULL;
00133 __ObjAddRef(_class);
00134 _delegate = _class->_members;
00135 INIT_CHAIN();
00136 ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
00137 }
00138
00139 SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
00140 {
00141 _memsize = memsize;
00142 _class = c;
00143 SQUnsignedInteger nvalues = _class->_defaultvalues.size();
00144 for(SQUnsignedInteger n = 0; n < nvalues; n++) {
00145 new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
00146 }
00147 Init(ss);
00148 }
00149
00150 SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
00151 {
00152 _memsize = memsize;
00153 _class = i->_class;
00154 SQUnsignedInteger nvalues = _class->_defaultvalues.size();
00155 for(SQUnsignedInteger n = 0; n < nvalues; n++) {
00156 new (&_values[n]) SQObjectPtr(i->_values[n]);
00157 }
00158 Init(ss);
00159 }
00160
00161 void SQInstance::Finalize()
00162 {
00163 SQUnsignedInteger nvalues = _class->_defaultvalues.size();
00164 __ObjRelease(_class);
00165 for(SQUnsignedInteger i = 0; i < nvalues; i++) {
00166 _values[i] = _null_;
00167 }
00168 }
00169
00170 SQInstance::~SQInstance()
00171 {
00172 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
00173 if(_class){ Finalize(); }
00174 }
00175
00176 bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
00177 {
00178 if(type(_class->_metamethods[mm]) != OT_NULL) {
00179 res = _class->_metamethods[mm];
00180 return true;
00181 }
00182 return false;
00183 }
00184
00185 bool SQInstance::InstanceOf(SQClass *trg)
00186 {
00187 SQClass *parent = _class;
00188 while(parent != NULL) {
00189 if(parent == trg)
00190 return true;
00191 parent = parent->_base;
00192 }
00193 return false;
00194 }