summaryrefslogtreecommitdiffstats
path: root/squirrel_3_0_1_stable/squirrel/sqclass.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--squirrel_3_0_1_stable/squirrel/sqclass.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/squirrel_3_0_1_stable/squirrel/sqclass.h b/squirrel_3_0_1_stable/squirrel/sqclass.h
new file mode 100644
index 000000000..996a3df70
--- /dev/null
+++ b/squirrel_3_0_1_stable/squirrel/sqclass.h
@@ -0,0 +1,158 @@
+/* see copyright notice in squirrel.h */
+#ifndef _SQCLASS_H_
+#define _SQCLASS_H_
+
+struct SQInstance;
+
+struct SQClassMember {
+ SQObjectPtr val;
+ SQObjectPtr attrs;
+};
+
+typedef sqvector<SQClassMember> SQClassMemberVec;
+
+#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);
+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(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
+ bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
+ if(_members->Get(key,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;
+ }
+ bool GetConstructor(SQObjectPtr &ctor)
+ {
+ if(_constructoridx != -1) {
+ ctor = _methods[_constructoridx].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() {
+ if (_hook) { _hook(_typetag,0);}
+ sq_delete(this, SQClass);
+ }
+ void Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable ** );
+ SQObjectType GetType() {return OT_CLASS;}
+#endif
+ SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+ SQInstance *CreateInstance();
+ SQTable *_members;
+ SQClass *_base;
+ SQClassMemberVec _defaultvalues;
+ SQClassMemberVec _methods;
+ SQObjectPtr _metamethods[MT_LAST];
+ SQObjectPtr _attributes;
+ SQUserPointer _typetag;
+ SQRELEASEHOOK _hook;
+ bool _locked;
+ SQInteger _constructoridx;
+ SQInteger _udsize;
+};
+
+#define calcinstancesize(_theclass_) \
+ (_theclass_->_udsize + sq_aligning(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, SQInteger memsize);
+ SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
+public:
+ static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
+
+ SQInteger size = calcinstancesize(theclass);
+ SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
+ new (newinst) SQInstance(ss, theclass,size);
+ if(theclass->_udsize) {
+ newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
+ }
+ return newinst;
+ }
+ SQInstance *Clone(SQSharedState *ss)
+ {
+ SQInteger size = calcinstancesize(_class);
+ SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
+ new (newinst) SQInstance(ss, this,size);
+ if(_class->_udsize) {
+ newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
+ }
+ return newinst;
+ }
+ ~SQInstance();
+ bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
+ if(_class->_members->Get(key,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) && _isfield(idx)) {
+ _values[_member_idx(idx)] = val;
+ return true;
+ }
+ return false;
+ }
+ void Release() {
+ _uiRef++;
+ if (_hook) { _hook(_userpointer,0);}
+ _uiRef--;
+ if(_uiRef > 0) return;
+ SQInteger size = _memsize;
+ this->~SQInstance();
+ SQ_FREE(this, size);
+ }
+ void Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable ** );
+ SQObjectType GetType() {return OT_INSTANCE;}
+#endif
+ bool InstanceOf(SQClass *trg);
+ bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
+
+ SQClass *_class;
+ SQUserPointer _userpointer;
+ SQRELEASEHOOK _hook;
+ SQInteger _memsize;
+ SQObjectPtr _values[1];
+};
+
+#endif //_SQCLASS_H_