sqclass.h

00001 /*  see copyright notice in squirrel.h */
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_

Generated on Sun Mar 15 22:49:44 2009 for openttd by  doxygen 1.5.6