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