X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fsquirrel%2Fsquirrel%2Fsqclass.h;h=4faff8395ee321df84eaad7d65c491a4014b4feb;hb=fea3446f05e1e7673607b835c269d3e8d1929ab3;hp=5c12d7e21b75567a5f0d7388b603d9f6132eb3fb;hpb=c81e5d255303f56a3fc33bef1fd0124c4b62cfcf;p=supertux.git diff --git a/src/squirrel/squirrel/sqclass.h b/src/squirrel/squirrel/sqclass.h index 5c12d7e21..4faff8395 100644 --- a/src/squirrel/squirrel/sqclass.h +++ b/src/squirrel/squirrel/sqclass.h @@ -4,9 +4,9 @@ struct SQInstance; -struct SQClassMemeber { - SQClassMemeber(){} - SQClassMemeber(const SQClassMemeber &o) { +struct SQClassMember { + SQClassMember(){} + SQClassMember(const SQClassMember &o) { val = o.val; attrs = o.attrs; } @@ -14,7 +14,17 @@ struct SQClassMemeber { SQObjectPtr attrs; }; -typedef sqvector SQClassMemeberVec; +typedef sqvector SQClassMemberVec; + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) struct SQClass : public CHAINABLE_OBJ { @@ -26,10 +36,16 @@ public: return newclass; } ~SQClass(); - bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); + bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); bool Get(const SQObjectPtr &key,SQObjectPtr &val) { if(_members->Get(key,val)) { - val = (type(val) == OT_INTEGER?_defaultvalues[_integer(val)].val:_methods[(int)_userpointer(val)].val); + if(_isfield(val)) { + SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; + val = _realval(o); + } + else { + val = _methods[_member_idx(val)].val; + } return true; } return false; @@ -37,68 +53,100 @@ public: bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); void Lock() { _locked = true; if(_base) _base->Lock(); } - void Release() { sq_delete(this, SQClass); } + void Release() { + if (_hook) { _hook(_typetag,0);} + sq_delete(this, SQClass); + } void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR void Mark(SQCollectable ** ); - int Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); +#endif + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); SQInstance *CreateInstance(); SQTable *_members; - //SQTable *_properties; SQClass *_base; - SQClassMemeberVec _defaultvalues; - SQClassMemeberVec _methods; + SQClassMemberVec _defaultvalues; + SQClassMemberVec _methods; SQObjectPtrVec _metamethods; SQObjectPtr _attributes; - unsigned int _typetag; + SQUserPointer _typetag; + SQRELEASEHOOK _hook; bool _locked; + SQInteger _udsize; }; +#define calcinstancesize(_theclass_) \ + (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))) + struct SQInstance : public SQDelegable { void Init(SQSharedState *ss); - SQInstance(SQSharedState *ss, SQClass *c); - SQInstance(SQSharedState *ss, SQInstance *c); + SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); + SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); public: static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { - SQInstance *newinst = (SQInstance *)SQ_MALLOC(sizeof(SQInstance)); - new (newinst) SQInstance(ss, theclass); + + SQInteger size = calcinstancesize(theclass); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } return newinst; } SQInstance *Clone(SQSharedState *ss) { - SQInstance *newinst = (SQInstance *)SQ_MALLOC(sizeof(SQInstance)); - new (newinst) SQInstance(ss, this); + SQInteger size = calcinstancesize(_class); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } return newinst; } ~SQInstance(); bool Get(const SQObjectPtr &key,SQObjectPtr &val) { if(_class->_members->Get(key,val)) { - val = (type(val) == OT_INTEGER?_values[_integer(val)]:_class->_methods[(int)_userpointer(val)].val); + if(_isfield(val)) { + SQObjectPtr &o = _values[_member_idx(val)]; + val = _realval(o); + } + else { + val = _class->_methods[_member_idx(val)].val; + } return true; } return false; } bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { SQObjectPtr idx; - if(_class->_members->Get(key,idx) && type(idx) == OT_INTEGER) { - _values[_integer(idx)] = val; + if(_class->_members->Get(key,idx) && _isfield(idx)) { + _values[_member_idx(idx)] = val; return true; } return false; } - void Release() { + void Release() { + _uiRef++; if (_hook) { _hook(_userpointer,0);} - sq_delete(this, SQInstance); + _uiRef--; + if(_uiRef > 0) return; + SQInteger size = _memsize; + this->~SQInstance(); + SQ_FREE(this, size); } void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR void Mark(SQCollectable ** ); +#endif bool InstanceOf(SQClass *trg); - bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res); + bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); SQClass *_class; SQUserPointer _userpointer; SQRELEASEHOOK _hook; - SQObjectPtrVec _values; + SQInteger _memsize; + SQObjectPtr _values[1]; }; #endif //_SQCLASS_H_