6
static SQInteger getVarInfo(StackHandler & sa,VarRefPtr & vr) {
7
HSQOBJECT htable = sa.GetObjectHandle(1);
8
SquirrelObject table(htable);
10
SQObjectType type = (SQObjectType)sa.GetType(2);
12
const SQChar * el = sa.GetString(2);
13
ScriptStringVar256 varNameTag;
14
getVarNameTag(varNameTag,sizeof(varNameTag),el);
16
if (!table.RawGetUserData(varNameTag,&data)) {
17
// throw SquirrelError("getVarInfo: Could not retrieve UserData");
18
return sa.ThrowError(sqT("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error.
24
static SQInteger getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) {
25
HSQOBJECT ho = sa.GetObjectHandle(1);
26
SquirrelObject instance(ho);
28
SQObjectType type = (SQObjectType)sa.GetType(2);
30
const SQChar * el = sa.GetString(2);
31
ScriptStringVar256 varNameTag;
32
getVarNameTag(varNameTag,sizeof(varNameTag),el);
33
SQUserPointer ivrData=0;
34
if (!instance.RawGetUserData(varNameTag,&ivrData)) {
35
// throw SquirrelError("getInstanceVarInfo: Could not retrieve UserData");
36
return sa.ThrowError(sqT("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error.
38
vr = (VarRefPtr)ivrData;
40
if (!(vr->access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) {
41
#ifdef SQ_USE_CLASS_INHERITANCE
42
SQUserPointer typetag; instance.GetTypeTag(&typetag);
43
if (typetag != vr->instanceType) {
44
SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME);
45
up = (unsigned char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // <TODO> 64-bit compatible version.
47
throw SquirrelError(sqT("Invalid Instance Type"));
50
up = (unsigned char *)instance.GetInstanceUP(0);
53
up = (unsigned char *)instance.GetInstanceUP(0);
55
up += (size_t)vr->offsetOrAddrOrConst; // Offset
57
up = (unsigned char *)vr->offsetOrAddrOrConst; // Address
61
} // getInstanceVarInfo
63
static SQInteger setVar(StackHandler & sa,VarRef * vr,void * data) {
64
if (vr->access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) {
65
ScriptStringVar256 msg;
66
const SQChar * el = sa.GetString(2);
67
SCSNPRINTF(msg.s,sizeof(msg),sqT("setVar(): Cannot write to constant: %s"),el);
68
throw SquirrelError(msg.s);
71
case TypeInfo<INT>::TypeID: {
72
INT * val = (INT *)data; // Address
75
return sa.Return(*val);
79
case TypeInfo<FLOAT>::TypeID: {
80
FLOAT * val = (FLOAT *)data; // Address
82
*val = sa.GetFloat(3);
83
return sa.Return(*val);
87
case TypeInfo<bool>::TypeID: {
88
bool * val = (bool *)data; // Address
90
*val = sa.GetBool(3) ? true : false;
91
return sa.Return(*val);
95
case VAR_TYPE_INSTANCE: {
96
// C::B patch: Comment out unused variable
97
//HSQUIRRELVM v = sa.GetVMPtr();
98
// vr->copyFunc is the LHS variable type: the RHS var's type is ClassType<>::type() (both point to ClassType<>::copy()).
99
// src will be null if the LHS and RHS types don't match.
100
SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->copyFunc); // Effectively performs: ClassType<>::type() == ClassType<>getCopyFunc().
101
if (!src) throw SquirrelError(sqT("INSTANCE type assignment mismatch"));
102
vr->copyFunc(data,src);
103
#if 0 // Return an instance on the stack (allocates memory)
104
if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address
105
ScriptStringVar256 msg;
106
SCSNPRINTF(msg.s,sizeof(msg),sqT("getVar(): Could not create instance: %s"),vr->typeName);
107
throw SquirrelError(msg.s);
110
#else // Don't return on stack.
114
case TypeInfo<SQUserPointer>::TypeID: {
115
ScriptStringVar256 msg;
116
const SQChar * el = sa.GetString(2);
117
SCSNPRINTF(msg.s,sizeof(msg),sqT("setVar(): Cannot write to an SQUserPointer: %s"),el);
118
throw SquirrelError(msg.s);
120
case TypeInfo<ScriptStringVarBase>::TypeID: {
121
ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address
123
const SQChar * strVal = sa.GetString(3);
126
return sa.Return(val->s);
131
// C::B patch: Handle all switch cases
137
static SQInteger getVar(StackHandler & sa,VarRef * vr,void * data) {
139
case TypeInfo<INT>::TypeID: {
140
if (!(vr->access & VAR_ACCESS_CONSTANT)) {
141
INT * val = (INT *)data; // Address
143
return sa.Return(*val);
146
INT * val = (INT *)&data; // Constant value
147
return sa.Return(*val);
151
case TypeInfo<FLOAT>::TypeID: {
152
if (!(vr->access & VAR_ACCESS_CONSTANT)) {
153
FLOAT * val = (FLOAT *)data; // Address
155
return sa.Return(*val);
158
FLOAT * val = (FLOAT *)&data; // Constant value
159
return sa.Return(*val);
163
case TypeInfo<bool>::TypeID: {
164
if (!(vr->access & VAR_ACCESS_CONSTANT)) {
165
bool * val = (bool *)data; // Address
167
return sa.Return(*val);
170
bool * val = (bool *)&data; // Constant value
171
return sa.Return(*val);
175
case VAR_TYPE_INSTANCE:
176
if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address. Allocates memory.
177
ScriptStringVar256 msg;
178
SCSNPRINTF(msg.s,sizeof(msg),sqT("getVar(): Could not create instance: %s"),vr->typeName);
179
throw SquirrelError(msg.s);
182
case TypeInfo<SQUserPointer>::TypeID: {
183
return sa.Return(data); // The address of member variable, not the variable itself.
185
case TypeInfo<ScriptStringVarBase>::TypeID: {
186
if (!(vr->access & VAR_ACCESS_CONSTANT)) {
187
ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address
189
return sa.Return(val->s);
192
throw SquirrelError(sqT("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)"));
196
case TypeInfo<const SQChar *>::TypeID: {
197
if (!(vr->access & VAR_ACCESS_CONSTANT)) {
198
throw SquirrelError(sqT("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT"));
200
return sa.Return((const SQChar *)data); // Address
204
// C::B patch: Handle all switch cases
210
// === Global Vars ===
212
SQInteger setVarFunc(HSQUIRRELVM v) {
214
if (sa.GetType(1) == OT_TABLE) {
216
SQInteger res = getVarInfo(sa,vr);
217
if (res != SQ_OK) return res;
218
return setVar(sa,vr,vr->offsetOrAddrOrConst);
223
SQInteger getVarFunc(HSQUIRRELVM v) {
225
if (sa.GetType(1) == OT_TABLE) {
227
SQInteger res = getVarInfo(sa,vr);
228
if (res != SQ_OK) return res;
229
return getVar(sa,vr,vr->offsetOrAddrOrConst);
234
// === Instance Vars ===
236
SQInteger setInstanceVarFunc(HSQUIRRELVM v) {
238
if (sa.GetType(1) == OT_INSTANCE) {
241
SQInteger res = getInstanceVarInfo(sa,vr,data);
242
if (res != SQ_OK) return res;
243
return setVar(sa,vr,data);
246
} // setInstanceVarFunc
248
SQInteger getInstanceVarFunc(HSQUIRRELVM v) {
250
if (sa.GetType(1) == OT_INSTANCE) {
253
SQInteger res = getInstanceVarInfo(sa,vr,data);
254
if (res != SQ_OK) return res;
255
return getVar(sa,vr,data);
258
} // getInstanceVarFunc
262
BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName) {
263
// C::B patch: Comment out unused variable
265
SQInteger oldtop = sq_gettop(v);
267
sq_pushstring(v,name,-1);
269
sq_pushstring(v,baseName,-1);
270
if (SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by baseName.
275
if (SQ_FAILED(sq_newclass(v,baseName ? 1 : 0))) { // Will inherit from base class on stack from sq_get() above.
279
newClass.AttachToStackObject(-1);
280
sq_settypetag(v,-1,classType);
286
SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,SQUserPointer classType,SQFUNCTION constructor) {
287
SQInteger top = sq_gettop(v);
288
SquirrelObject newClass;
289
if (CreateClass(v,newClass,classType,scriptClassName)) {
290
SquirrelVM::CreateFunction(newClass,constructor,sqT("constructor"));
294
} // RegisterClassType
296
}; // namespace SqPlus