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     try {
00132       if (_hook) { _hook(_userpointer,0);}
00133     } catch (...) {
00134       _uiRef--;
00135       if (_uiRef == 0) {
00136         SQInteger size = _memsize;
00137         this->~SQInstance();
00138         SQ_FREE(this, size);
00139       }
00140       throw;
00141     }
00142     _uiRef--;
00143     if(_uiRef > 0) return;
00144     SQInteger size = _memsize;
00145     this->~SQInstance();
00146     SQ_FREE(this, size);
00147   }
00148   void Finalize();
00149 #ifndef NO_GARBAGE_COLLECTOR
00150   void Mark(SQCollectable ** );
00151 #endif
00152   bool InstanceOf(SQClass *trg);
00153   bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
00154 
00155   SQClass *_class;
00156   SQUserPointer _userpointer;
00157   SQRELEASEHOOK _hook;
00158   SQInteger _memsize;
00159   SQObjectPtr _values[1];
00160 };
00161 
00162 #endif //_SQCLASS_H_

Generated on Mon Dec 14 20:59:56 2009 for OpenTTD by  doxygen 1.5.6