sqclass.h
00001
00002 #ifndef _SQCLASS_H_
00003 #define _SQCLASS_H_
00004
00005 struct SQInstance;
00006
00007 struct SQClassMember {
00008 SQClassMember(){}
00009 SQClassMember(const SQClassMember &o) {
00010 val = o.val;
00011 attrs = o.attrs;
00012 }
00013 SQObjectPtr val;
00014 SQObjectPtr attrs;
00015 };
00016
00017 typedef sqvector<SQClassMember> SQClassMemberVec;
00018
00019 #define MEMBER_TYPE_METHOD 0x01000000
00020 #define MEMBER_TYPE_FIELD 0x02000000
00021
00022 #define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
00023 #define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
00024 #define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
00025 #define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
00026 #define _member_type(o) (_integer(o)&0xFF000000)
00027 #define _member_idx(o) (_integer(o)&0x00FFFFFF)
00028
00029 struct SQClass : public CHAINABLE_OBJ
00030 {
00031 SQClass(SQSharedState *ss,SQClass *base);
00032 public:
00033 static SQClass* Create(SQSharedState *ss,SQClass *base) {
00034 SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
00035 new (newclass) SQClass(ss, base);
00036 return newclass;
00037 }
00038 ~SQClass();
00039 bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
00040 bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
00041 if(_members->Get(key,val)) {
00042 if(_isfield(val)) {
00043 SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
00044 val = _realval(o);
00045 }
00046 else {
00047 val = _methods[_member_idx(val)].val;
00048 }
00049 return true;
00050 }
00051 return false;
00052 }
00053 bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
00054 bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
00055 void Lock() { _locked = true; if(_base) _base->Lock(); }
00056 void Release() {
00057 if (_hook) { _hook(_typetag,0);}
00058 sq_delete(this, SQClass);
00059 }
00060 void Finalize();
00061 #ifndef NO_GARBAGE_COLLECTOR
00062 void Mark(SQCollectable ** );
00063 #endif
00064 SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
00065 SQInstance *CreateInstance();
00066 SQTable *_members;
00067 SQClass *_base;
00068 SQClassMemberVec _defaultvalues;
00069 SQClassMemberVec _methods;
00070 SQObjectPtrVec _metamethods;
00071 SQObjectPtr _attributes;
00072 SQUserPointer _typetag;
00073 SQRELEASEHOOK _hook;
00074 bool _locked;
00075 SQInteger _udsize;
00076 };
00077
00078 #define calcinstancesize(_theclass_) \
00079 (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))
00080
00081 struct SQInstance : public SQDelegable
00082 {
00083 void Init(SQSharedState *ss);
00084 SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
00085 SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
00086 public:
00087 static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
00088
00089 SQInteger size = calcinstancesize(theclass);
00090 SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
00091 new (newinst) SQInstance(ss, theclass,size);
00092 if(theclass->_udsize) {
00093 newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
00094 }
00095 return newinst;
00096 }
00097 SQInstance *Clone(SQSharedState *ss)
00098 {
00099 SQInteger size = calcinstancesize(_class);
00100 SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
00101 new (newinst) SQInstance(ss, this,size);
00102 if(_class->_udsize) {
00103 newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
00104 }
00105 return newinst;
00106 }
00107 ~SQInstance();
00108 bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
00109 if(_class->_members->Get(key,val)) {
00110 if(_isfield(val)) {
00111 SQObjectPtr &o = _values[_member_idx(val)];
00112 val = _realval(o);
00113 }
00114 else {
00115 val = _class->_methods[_member_idx(val)].val;
00116 }
00117 return true;
00118 }
00119 return false;
00120 }
00121 bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
00122 SQObjectPtr idx;
00123 if(_class->_members->Get(key,idx) && _isfield(idx)) {
00124 _values[_member_idx(idx)] = val;
00125 return true;
00126 }
00127 return false;
00128 }
00129 void Release() {
00130 _uiRef++;
00131 if (_hook) { _hook(_userpointer,0);}
00132 _uiRef--;
00133 if(_uiRef > 0) return;
00134 SQInteger size = _memsize;
00135 this->~SQInstance();
00136 SQ_FREE(this, size);
00137 }
00138 void Finalize();
00139 #ifndef NO_GARBAGE_COLLECTOR
00140 void Mark(SQCollectable ** );
00141 #endif
00142 bool InstanceOf(SQClass *trg);
00143 bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
00144
00145 SQClass *_class;
00146 SQUserPointer _userpointer;
00147 SQRELEASEHOOK _hook;
00148 SQInteger _memsize;
00149 SQObjectPtr _values[1];
00150 };
00151
00152 #endif //_SQCLASS_H_