Johan Wikman / SQUIRREL3

Dependents:   Squirrel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sqclass.h Source File

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