| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- /* see copyright notice in squirrel.h */
- #ifndef _SQCLASS_H_
- #define _SQCLASS_H_
- struct SQInstance;
- struct SQClassMember {
- SQObjectPtr val;
- SQObjectPtr attrs;
- void Null() {
- val.Null();
- attrs.Null();
- }
- };
- typedef sqvector<SQClassMember> 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
- {
- SQClass(SQSharedState *ss,SQClass *base);
- public:
- static SQClass* Create(SQSharedState *ss,SQClass *base) {
- SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
- new (newclass) SQClass(ss, base);
- return newclass;
- }
- ~SQClass();
- bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_members->Get(key,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;
- }
- bool GetConstructor(SQObjectPtr &ctor)
- {
- if(_constructoridx != -1) {
- ctor = _methods[_constructoridx].val;
- return true;
- }
- return false;
- }
- 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() {
- if (_hook) { _hook(_typetag,0);}
- sq_delete(this, SQClass);
- }
- void Finalize();
- #ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
- SQObjectType GetType() {return OT_CLASS;}
- #endif
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- SQInstance *CreateInstance();
- SQTable *_members;
- SQClass *_base;
- SQClassMemberVec _defaultvalues;
- SQClassMemberVec _methods;
- SQObjectPtr _metamethods[MT_LAST];
- SQObjectPtr _attributes;
- SQUserPointer _typetag;
- SQRELEASEHOOK _hook;
- bool _locked;
- SQInteger _constructoridx;
- SQInteger _udsize;
- };
- #define calcinstancesize(_theclass_) \
- (_theclass_->_udsize + sq_aligning(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, SQInteger memsize);
- SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
- public:
- static SQInstance* Create(SQSharedState *ss,SQClass *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)
- {
- 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)) {
- 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) && _isfield(idx)) {
- _values[_member_idx(idx)] = val;
- return true;
- }
- return false;
- }
- void Release() {
- _uiRef++;
- if (_hook) { _hook(_userpointer,0);}
- _uiRef--;
- if(_uiRef > 0) return;
- SQInteger size = _memsize;
- this->~SQInstance();
- SQ_FREE(this, size);
- }
- void Finalize();
- #ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
- SQObjectType GetType() {return OT_INSTANCE;}
- #endif
- bool InstanceOf(SQClass *trg);
- bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
- SQClass *_class;
- SQUserPointer _userpointer;
- SQRELEASEHOOK _hook;
- SQInteger _memsize;
- SQObjectPtr _values[1];
- };
- #endif //_SQCLASS_H_
|