this shouldn't be in svn
[supertux.git] / src / squirrel / squirrel / sqclass.h
index c9de102..460e591 100644 (file)
-/*     see copyright notice in squirrel.h */
-#ifndef _SQCLASS_H_
-#define _SQCLASS_H_
-
-struct SQInstance;
-
-struct SQClassMember {
-       SQClassMember(){}
-       SQClassMember(const SQClassMember &o) {
-               val = o.val;
-               attrs = o.attrs;
-       }
-       SQObjectPtr val;
-       SQObjectPtr attrs;
-};
-
-typedef sqvector<SQClassMember> SQClassMemberVec;
-
-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(const SQObjectPtr &key,const SQObjectPtr &val);
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
-               if(_members->Get(key,val)) {
-                       val = (type(val) == OT_INTEGER?_defaultvalues[_integer(val)].val:_methods[_integer(val)].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() { sq_delete(this, SQClass);      }
-       void Finalize();
-       void Mark(SQCollectable ** );
-       int Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-       SQInstance *CreateInstance();
-       SQTable *_members;
-       //SQTable *_properties;
-       SQClass *_base;
-       SQClassMemberVec _defaultvalues;
-       SQClassMemberVec _methods;
-       SQObjectPtrVec _metamethods;
-       SQObjectPtr _attributes;
-       unsigned int _typetag;
-       bool _locked;
-};
-
-struct SQInstance : public SQDelegable 
-{
-       void Init(SQSharedState *ss);
-       SQInstance(SQSharedState *ss, SQClass *c);
-       SQInstance(SQSharedState *ss, SQInstance *c);
-public:
-       static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
-               SQInstance *newinst = (SQInstance *)SQ_MALLOC(sizeof(SQInstance));
-               new (newinst) SQInstance(ss, theclass);
-               return newinst;
-       }
-       SQInstance *Clone(SQSharedState *ss)
-       {
-               SQInstance *newinst = (SQInstance *)SQ_MALLOC(sizeof(SQInstance));
-               new (newinst) SQInstance(ss, this);
-               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[_integer(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;
-                       return true;
-               }
-               return false;
-       }
-       void Release() { 
-               if (_hook) { _hook(_userpointer,0);}
-               sq_delete(this, SQInstance);
-       }
-       void Finalize();
-       void Mark(SQCollectable ** );
-       bool InstanceOf(SQClass *trg);
-       bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res);
-
-       SQClass *_class;
-       SQUserPointer _userpointer;
-       SQRELEASEHOOK _hook;
-       SQObjectPtrVec _values;
-};
-
-#endif //_SQCLASS_H_
+/*     see copyright notice in squirrel.h */\r
+#ifndef _SQCLASS_H_\r
+#define _SQCLASS_H_\r
+\r
+struct SQInstance;\r
+\r
+struct SQClassMemeber {\r
+       SQClassMemeber(){}\r
+       SQClassMemeber(const SQClassMemeber &o) {\r
+               val = o.val;\r
+               attrs = o.attrs;\r
+       }\r
+       SQObjectPtr val;\r
+       SQObjectPtr attrs;\r
+};\r
+\r
+typedef sqvector<SQClassMemeber> SQClassMemeberVec;\r
+\r
+#define MEMBER_TYPE_METHOD 0x01000000\r
+#define MEMBER_TYPE_FIELD 0x02000000\r
+\r
+#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)\r
+#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)\r
+#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))\r
+#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))\r
+#define _member_type(o) (_integer(o)&0xFF000000)\r
+#define _member_idx(o) (_integer(o)&0x00FFFFFF)\r
+\r
+struct SQClass : public CHAINABLE_OBJ\r
+{\r
+       SQClass(SQSharedState *ss,SQClass *base);\r
+public:\r
+       static SQClass* Create(SQSharedState *ss,SQClass *base) {\r
+               SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));\r
+               new (newclass) SQClass(ss, base);\r
+               return newclass;\r
+       }\r
+       ~SQClass();\r
+       bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);\r
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val) {\r
+               if(_members->Get(key,val)) {\r
+                       if(_isfield(val)) {\r
+                               SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;\r
+                               val = _realval(o);\r
+                       }\r
+                       else {\r
+                               val = _methods[_member_idx(val)].val;\r
+                       }\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);\r
+       bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);\r
+       void Lock() { _locked = true; if(_base) _base->Lock(); }\r
+       void Release() { \r
+               if (_hook) { _hook(_typetag,0);}\r
+               sq_delete(this, SQClass);       \r
+       }\r
+       void Finalize();\r
+#ifndef NO_GARBAGE_COLLECTOR\r
+       void Mark(SQCollectable ** );\r
+#endif\r
+       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
+       SQInstance *CreateInstance();\r
+       SQTable *_members;\r
+       SQClass *_base;\r
+       SQClassMemeberVec _defaultvalues;\r
+       SQClassMemeberVec _methods;\r
+       SQObjectPtrVec _metamethods;\r
+       SQObjectPtr _attributes;\r
+       SQUserPointer _typetag;\r
+       SQRELEASEHOOK _hook;\r
+       bool _locked;\r
+};\r
+\r
+#define calcinstancesize(_theclass_) \\r
+       (sizeof(SQInstance)+(sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))\r
+struct SQInstance : public SQDelegable \r
+{\r
+       void Init(SQSharedState *ss);\r
+       SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);\r
+       SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);\r
+public:\r
+       static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {\r
+               \r
+               SQInteger size = calcinstancesize(theclass);\r
+               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
+               new (newinst) SQInstance(ss, theclass,size);\r
+               return newinst;\r
+       }\r
+       SQInstance *Clone(SQSharedState *ss)\r
+       {\r
+               SQInteger size = calcinstancesize(_class);\r
+               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
+               new (newinst) SQInstance(ss, this,size);\r
+               return newinst;\r
+       }\r
+       ~SQInstance();\r
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {\r
+               if(_class->_members->Get(key,val)) {\r
+                       if(_isfield(val)) {\r
+                               SQObjectPtr &o = _values[_member_idx(val)];\r
+                               val = _realval(o);\r
+                       }\r
+                       else {\r
+                               val = _class->_methods[_member_idx(val)].val;\r
+                       }\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {\r
+               SQObjectPtr idx;\r
+               if(_class->_members->Get(key,idx) && _isfield(idx)) {\r
+            _values[_member_idx(idx)] = val;\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       void Release() { \r
+               if (_hook) { _hook(_userpointer,0);}\r
+               SQInteger size = _memsize;\r
+               this->~SQInstance();\r
+               SQ_FREE(this, size);\r
+       }\r
+       void Finalize();\r
+#ifndef NO_GARBAGE_COLLECTOR \r
+       void Mark(SQCollectable ** );\r
+#endif\r
+       bool InstanceOf(SQClass *trg);\r
+       bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);\r
+\r
+       SQClass *_class;\r
+       SQUserPointer _userpointer;\r
+       SQRELEASEHOOK _hook;\r
+       SQUnsignedInteger _nvalues;\r
+       SQInteger _memsize;\r
+       SQObjectPtr _values[1];\r
+};\r
+\r
+#endif //_SQCLASS_H_\r