#include "squirrel.h" #include "squirrel_object.h" //#include "SquirrelVM.h" SquirrelObject::SquirrelObject(HSQUIRRELVM v) { vm = v; sq_resetobject(&_o); } SquirrelObject::~SquirrelObject() { if(vm) sq_release(vm,&_o); } SquirrelObject::SquirrelObject(const SquirrelObject &o) { vm = o.vm; _o = o._o; sq_addref(vm,&_o); } SquirrelObject::SquirrelObject(HSQOBJECT &o) { _o = o; sq_addref(vm,&_o); } SquirrelObject SquirrelObject::Clone() { SquirrelObject ret(vm); if(GetType() == OT_TABLE || GetType() == OT_ARRAY) { sq_pushobject(vm,_o); sq_clone(vm,-1); ret.AttachToStackObject(-1); sq_pop(vm,2); } return ret; } SquirrelObject & SquirrelObject::operator =(const SquirrelObject &o) { HSQOBJECT t; t = o._o; sq_addref(vm,&t); sq_release(vm,&_o); _o = t; return *this; } SquirrelObject & SquirrelObject::operator =(int n) { sq_pushinteger(vm,n); AttachToStackObject(-1); sq_pop(vm,1); return *this; } void SquirrelObject::Append(const SquirrelObject &o) { if(sq_isarray(_o)) { sq_pushobject(vm,_o); sq_pushobject(vm,o._o); sq_arrayappend(vm,-2); sq_pop(vm,1); } } void SquirrelObject::AttachToStackObject(int idx) { HSQOBJECT t; sq_getstackobj(vm,idx,&t); sq_addref(vm,&t); sq_release(vm,&_o); _o = t; } bool SquirrelObject::SetDelegate(SquirrelObject &obj) { if(obj.GetType() == OT_TABLE || obj.GetType() == OT_NULL) { switch(_o._type) { case OT_USERDATA: case OT_TABLE: sq_pushobject(vm,_o); sq_pushobject(vm,obj._o); if(SQ_SUCCEEDED(sq_setdelegate(vm,-2))) return true; break; } } return false; } SquirrelObject SquirrelObject::GetDelegate() { SquirrelObject ret(vm); if(_o._type == OT_TABLE || _o._type == OT_USERDATA) { sq_pushobject(vm,_o); sq_getdelegate(vm,-1); ret.AttachToStackObject(-1); sq_pop(vm,2); } return ret; } bool SquirrelObject::IsNull() const { return sq_isnull(_o); } bool SquirrelObject::IsNumeric() const { return sq_isnumeric(_o) ? true : false; } int SquirrelObject::Len() const { int ret = 0; if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) { sq_pushobject(vm,_o); ret = sq_getsize(vm,-1); sq_pop(vm,1); } return ret; } #define _SETVALUE_INT_BEGIN \ bool ret = false; \ int top = sq_gettop(vm); \ sq_pushobject(vm,_o); \ sq_pushinteger(vm,key); #define _SETVALUE_INT_END \ if(SQ_SUCCEEDED(sq_rawset(vm,-3))) { \ ret = true; \ } \ sq_settop(vm,top); \ return ret; bool SquirrelObject::SetValue(SQInteger key,const SquirrelObject &val) { _SETVALUE_INT_BEGIN sq_pushobject(vm,val._o); _SETVALUE_INT_END } bool SquirrelObject::SetValue(int key,int n) { _SETVALUE_INT_BEGIN sq_pushinteger(vm,n); _SETVALUE_INT_END } bool SquirrelObject::SetValue(int key,float f) { _SETVALUE_INT_BEGIN sq_pushfloat(vm,f); _SETVALUE_INT_END } bool SquirrelObject::SetValue(int key,const SQChar *s) { _SETVALUE_INT_BEGIN sq_pushstring(vm,s,-1); _SETVALUE_INT_END } bool SquirrelObject::SetValue(int key,bool b) { _SETVALUE_INT_BEGIN sq_pushbool(vm,b); _SETVALUE_INT_END } bool SquirrelObject::SetValue(const SquirrelObject &key,const SquirrelObject &val) { bool ret = false; int top = sq_gettop(vm); sq_pushobject(vm,_o); sq_pushobject(vm,key._o); sq_pushobject(vm,val._o); if(SQ_SUCCEEDED(sq_rawset(vm,-3))) { ret = true; } sq_settop(vm,top); return ret; } #define _SETVALUE_STR_BEGIN \ bool ret = false; \ int top = sq_gettop(vm); \ sq_pushobject(vm,_o); \ sq_pushstring(vm,key,-1); #define _SETVALUE_STR_END \ if(SQ_SUCCEEDED(sq_rawset(vm,-3))) { \ ret = true; \ } \ sq_settop(vm,top); \ return ret; bool SquirrelObject::SetValue(const SQChar *key,const SquirrelObject &val) { _SETVALUE_STR_BEGIN sq_pushobject(vm,val._o); _SETVALUE_STR_END } bool SquirrelObject::SetValue(const SQChar *key,int n) { _SETVALUE_STR_BEGIN sq_pushinteger(vm,n); _SETVALUE_STR_END } bool SquirrelObject::SetValue(const SQChar *key,float f) { _SETVALUE_STR_BEGIN sq_pushfloat(vm,f); _SETVALUE_STR_END } bool SquirrelObject::SetValue(const SQChar *key,const SQChar *s) { _SETVALUE_STR_BEGIN sq_pushstring(vm,s,-1); _SETVALUE_STR_END } bool SquirrelObject::SetValue(const SQChar *key,bool b) { _SETVALUE_STR_BEGIN sq_pushbool(vm,b); _SETVALUE_STR_END } SQObjectType SquirrelObject::GetType() { return _o._type; } bool SquirrelObject::GetSlot(int key) const { sq_pushobject(vm,_o); sq_pushinteger(vm,key); if(SQ_SUCCEEDED(sq_get(vm,-2))) { return true; } return false; } SquirrelObject SquirrelObject::GetValue(int key)const { SquirrelObject ret(vm); if(GetSlot(key)) { ret.AttachToStackObject(-1); sq_pop(vm,1); } sq_pop(vm,1); return ret; } float SquirrelObject::GetFloat(int key) const { float ret = 0.0f; if(GetSlot(key)) { sq_getfloat(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return ret; } int SquirrelObject::GetInt(int key) const { SQInteger ret = 0; if(GetSlot(key)) { sq_getinteger(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return (int)ret; } const SQChar *SquirrelObject::GetString(int key) const { const SQChar *ret = 0; if(GetSlot(key)) { sq_getstring(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return ret; } bool SquirrelObject::GetBool(int key) const { SQBool ret = false; if(GetSlot(key)) { sq_getbool(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return ret?true:false; } bool SquirrelObject::Exists(const SQChar *key) const { bool ret = false; if(GetSlot(key)) { ret = true; } sq_pop(vm,1); return ret; } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// bool SquirrelObject::GetSlot(const SQChar *name) const { sq_pushobject(vm,_o); sq_pushstring(vm,name,-1); if(SQ_SUCCEEDED(sq_get(vm,-2))) { return true; } return false; } SquirrelObject SquirrelObject::GetValue(const SQChar *key)const { SquirrelObject ret(vm); if(GetSlot(key)) { ret.AttachToStackObject(-1); sq_pop(vm,1); } sq_pop(vm,1); return ret; } float SquirrelObject::GetFloat(const SQChar *key) const { float ret = 0.0f; if(GetSlot(key)) { sq_getfloat(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return ret; } int SquirrelObject::GetInt(const SQChar *key) const { SQInteger ret = 0; if(GetSlot(key)) { sq_getinteger(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return (int)ret; } const SQChar *SquirrelObject::GetString(const SQChar *key) const { const SQChar *ret = 0; if(GetSlot(key)) { sq_getstring(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return ret; } bool SquirrelObject::GetBool(const SQChar *key) const { SQBool ret = false; if(GetSlot(key)) { sq_getbool(vm,-1,&ret); sq_pop(vm,1); } sq_pop(vm,1); return ret?true:false; } SQUserPointer SquirrelObject::GetInstanceUP(SQUserPointer tag) const { SQUserPointer up = 0; sq_pushobject(vm,_o); sq_getinstanceup(vm,-1,(SQUserPointer*)&up,(SQUserPointer)tag); sq_pop(vm,1); return up; } bool SquirrelObject::SetInstanceUP(SQUserPointer up) { if(!sq_isinstance(_o)) return false; sq_pushobject(vm,_o); sq_setinstanceup(vm,-1,up); sq_pop(vm,1); return true; } SquirrelObject SquirrelObject::GetAttributes(const SQChar *key) { SquirrelObject ret(vm); int top = sq_gettop(vm); sq_pushobject(vm,_o); if(key) sq_pushstring(vm,key,-1); else sq_pushnull(vm); if(SQ_SUCCEEDED(sq_getattributes(vm,-2))) { ret.AttachToStackObject(-1); } sq_settop(vm,top); return ret; } bool SquirrelObject::BeginIteration() { if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o)) return false; sq_pushobject(vm,_o); sq_pushnull(vm); return true; } bool SquirrelObject::Next(SquirrelObject &key,SquirrelObject &val) { if(SQ_SUCCEEDED(sq_next(vm,-2))) { key.AttachToStackObject(-2); val.AttachToStackObject(-1); sq_pop(vm,2); return true; } return false; } const SQChar* SquirrelObject::ToString() { return sq_objtostring(&_o); } SQInteger SquirrelObject::ToInteger() { return sq_objtointeger(&_o); } SQFloat SquirrelObject::ToFloat() { return sq_objtofloat(&_o); } bool SquirrelObject::ToBool() { //<> return _o._unVal.nInteger?true:false; } void SquirrelObject::EndIteration() { sq_pop(vm,2); }