fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / squirrel / squirrel / sqclass.h
index 5c12d7e..a451eed 100644 (file)
@@ -16,6 +16,16 @@ struct SQClassMemeber {
 
 typedef sqvector<SQClassMemeber> SQClassMemeberVec;
 
+#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);
@@ -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,90 @@ 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;
        SQObjectPtrVec _metamethods;
        SQObjectPtr _attributes;
-       unsigned int _typetag;
+       SQUserPointer _typetag;
+       SQRELEASEHOOK _hook;
        bool _locked;
 };
 
-struct SQInstance : public SQDelegable 
+#define calcinstancesize(_theclass_) \
+       (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);
                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);
                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() {
                if (_hook) { _hook(_userpointer,0);}
-               sq_delete(this, SQInstance);
+               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;
+       SQUnsignedInteger _nvalues;
+       SQInteger _memsize;
+       SQObjectPtr _values[1];
 };
 
 #endif //_SQCLASS_H_