Code::Blocks  SVN r11506
sqclass.cpp
Go to the documentation of this file.
1 /*
2  see copyright notice in squirrel.h
3 */
4 #include "sqpcheader.h"
5 #include "sqvm.h"
6 #include "sqtable.h"
7 #include "sqclass.h"
8 #include "sqclosure.h"
9 
10 SQClass::SQClass(SQSharedState *ss,SQClass *base)
11 {
12  _base = base;
13  _typetag = 0;
14  _hook = NULL;
15  _udsize = 0;
16  _metamethods.resize(MT_LAST); //size it to max size
17  if(_base) {
18  _defaultvalues.copy(base->_defaultvalues);
19  _methods.copy(base->_methods);
20  _metamethods.copy(base->_metamethods);
21  __ObjAddRef(_base);
22  }
23  _members = base?base->_members->Clone() : SQTable::Create(ss,0);
24  __ObjAddRef(_members);
25  _locked = false;
26  INIT_CHAIN();
27  ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
28 }
29 
30 void SQClass::Finalize() {
31  _attributes = _null_;
32  _defaultvalues.resize(0);
33  _methods.resize(0);
34  _metamethods.resize(0);
35  __ObjRelease(_members);
36  if(_base) {
37  __ObjRelease(_base);
38  }
39 }
40 
41 SQClass::~SQClass()
42 {
43  REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
44  Finalize();
45 }
46 
47 bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
48 {
49  SQObjectPtr temp;
50  if(_locked)
51  return false; //the class already has an instance so cannot be modified
52  if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
53  {
54  _defaultvalues[_member_idx(temp)].val = val;
55  return true;
56  }
57  if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
58  SQInteger mmidx;
59  if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
60  (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
61  _metamethods[mmidx] = val;
62  }
63  else {
64  if(type(temp) == OT_NULL) {
65  SQClassMember m;
66  m.val = val;
67  _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
68  _methods.push_back(m);
69  }
70  else {
71  _methods[_member_idx(temp)].val = val;
72  }
73  }
74  return true;
75  }
76  SQClassMember m;
77  m.val = val;
78  _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
79  _defaultvalues.push_back(m);
80  return true;
81 }
82 
83 SQInstance *SQClass::CreateInstance()
84 {
85  if(!_locked) Lock();
86  return SQInstance::Create(_opt_ss(this),this);
87 }
88 
89 SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
90 {
91  SQObjectPtr oval;
92  SQInteger idx = _members->Next(false,refpos,outkey,oval);
93  if(idx != -1) {
94  if(_ismethod(oval)) {
95  outval = _methods[_member_idx(oval)].val;
96  }
97  else {
98  SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
99  outval = _realval(o);
100  }
101  }
102  return idx;
103 }
104 
105 bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
106 {
107  SQObjectPtr idx;
108  if(_members->Get(key,idx)) {
109  if(_isfield(idx))
110  _defaultvalues[_member_idx(idx)].attrs = val;
111  else
112  _methods[_member_idx(idx)].attrs = val;
113  return true;
114  }
115  return false;
116 }
117 
118 bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
119 {
120  SQObjectPtr idx;
121  if(_members->Get(key,idx)) {
122  outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
123  return true;
124  }
125  return false;
126 }
127 
129 void SQInstance::Init(SQSharedState *ss)
130 {
131  _userpointer = NULL;
132  _hook = NULL;
133  __ObjAddRef(_class);
134  _delegate = _class->_members;
135  INIT_CHAIN();
136  ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
137 }
138 
139 SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
140 {
141  _memsize = memsize;
142  _class = c;
143  SQUnsignedInteger nvalues = _class->_defaultvalues.size();
144  for(SQUnsignedInteger n = 0; n < nvalues; n++) {
145  new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
146  }
147  Init(ss);
148 }
149 
150 SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
151 {
152  _memsize = memsize;
153  _class = i->_class;
154  SQUnsignedInteger nvalues = _class->_defaultvalues.size();
155  for(SQUnsignedInteger n = 0; n < nvalues; n++) {
156  new (&_values[n]) SQObjectPtr(i->_values[n]);
157  }
158  Init(ss);
159 }
160 
161 void SQInstance::Finalize()
162 {
163  SQUnsignedInteger nvalues = _class->_defaultvalues.size();
164  __ObjRelease(_class);
165  for(SQUnsignedInteger i = 0; i < nvalues; i++) {
166  _values[i] = _null_;
167  }
168 }
169 
170 SQInstance::~SQInstance()
171 {
172  REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
173  if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
174 }
175 
176 // C::B patch: Make the compiler happy by commenting unused variables
177 bool SQInstance::GetMetaMethod(SQVM * /*v*/,SQMetaMethod mm,SQObjectPtr &res)
178 {
179  if(type(_class->_metamethods[mm]) != OT_NULL) {
180  res = _class->_metamethods[mm];
181  return true;
182  }
183  return false;
184 }
185 
186 bool SQInstance::InstanceOf(SQClass *trg)
187 {
188  SQClass *parent = _class;
189  while(parent != NULL) {
190  if(parent == trg)
191  return true;
192  parent = parent->_base;
193  }
194  return false;
195 }
SQObjectPtr _null_
Definition: sqstate.cpp:15
#define NULL
Definition: prefix.cpp:59