1
0
cuberite-2a/squirrel_3_0_1_stable/sqrat/sqrat/sqratObject.h
lapayo94@gmail.com 083228a10d Squirrel Plugins
I worked a little bit on the squirrel Bindings
They work now on linux and windows :) (OSX is untested, but should work also) but they are very limited at the moment. (Only made OnChat working)
I also fixed some small bugs.


git-svn-id: http://mc-server.googlecode.com/svn/trunk@648 0a769ca7-a7f5-676a-18bf-c427514a06d6
2012-07-08 21:01:08 +00:00

311 lines
8.5 KiB
C++

//
// SqratObject: Referenced Squirrel Object Wrapper
//
//
// Copyright (c) 2009 Brandon Jones
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
#if !defined(_SCRAT_OBJECT_H_)
#define _SCRAT_OBJECT_H_
#include <squirrel.h>
#include <string.h>
#include "sqratTypes.h"
#include "sqratOverloadMethods.h"
#include "sqratUtil.h"
namespace Sqrat {
class Object {
protected:
HSQUIRRELVM vm;
HSQOBJECT obj;
bool release;
Object(HSQUIRRELVM v, bool releaseOnDestroy = true) : vm(v), release(releaseOnDestroy) {
sq_resetobject(&obj);
}
public:
Object() : vm(0), release(true) {
sq_resetobject(&obj);
}
Object(const Object& so) : vm(so.vm), obj(so.obj), release(so.release) {
sq_addref(vm, &obj);
}
Object(HSQOBJECT o, HSQUIRRELVM v = DefaultVM::Get()) : vm(v), obj(o), release(true) {
sq_addref(vm, &obj);
}
template<class T>
Object(T* instance, HSQUIRRELVM v = DefaultVM::Get()) : vm(v), release(true) {
ClassType<T>::PushInstance(vm, instance);
sq_getstackobj(vm, -1, &obj);
sq_addref(vm, &obj);
}
virtual ~Object() {
if(release) {
Release();
}
}
Object& operator=(const Object& so) {
if(release) {
Release();
}
vm = so.vm;
obj = so.obj;
release = so.release;
sq_addref(vm, &GetObject());
return *this;
}
HSQUIRRELVM& GetVM() {
return vm;
}
HSQUIRRELVM GetVM() const {
return vm;
}
SQObjectType GetType() const {
return GetObject()._type;
}
bool IsNull() const {
return sq_isnull(GetObject());
}
virtual HSQOBJECT GetObject() const {
return obj;
}
virtual HSQOBJECT& GetObject() {
return obj;
}
operator HSQOBJECT&() {
return GetObject();
}
void Release() {
sq_release(vm, &obj);
}
SQUserPointer GetInstanceUP(SQUserPointer tag = NULL) const {
SQUserPointer up;
sq_pushobject(vm, GetObject());
sq_getinstanceup(vm, -1, &up, tag);
sq_pop(vm, 1);
return up;
}
Object GetSlot(const SQChar* slot) const {
HSQOBJECT slotObj;
sq_pushobject(vm, GetObject());
sq_pushstring(vm, slot, -1);
if(SQ_FAILED(sq_get(vm, -2))) {
sq_pop(vm, 1);
return Object(vm); // Return a NULL object
} else {
sq_getstackobj(vm, -1, &slotObj);
Object ret(slotObj, vm); // must addref before the pop!
sq_pop(vm, 2);
return ret;
}
}
template <class T>
T Cast() const {
sq_pushobject(vm, GetObject());
T ret = Var<T>(vm, -1).value;
sq_pop(vm, 1);
return ret;
}
Object GetSlot(SQInteger index) const {
HSQOBJECT slotObj;
sq_pushobject(vm, GetObject());
sq_pushinteger(vm, index);
if(SQ_FAILED(sq_get(vm, -2))) {
sq_pop(vm, 1);
return Object(vm); // Return a NULL object
} else {
sq_getstackobj(vm, -1, &slotObj);
Object ret(slotObj, vm); // must addref before the pop!
sq_pop(vm, 2);
return ret;
}
}
template <class T>
inline Object operator[](T slot)
{
return GetSlot(slot);
}
SQInteger GetSize() const {
sq_pushobject(vm, GetObject());
SQInteger ret = sq_getsize(vm, -1);
sq_pop(vm, 1);
return ret;
}
protected:
// Bind a function and it's associated Squirrel closure to the object
inline void BindFunc(const SQChar* name, void* method, size_t methodSize, SQFUNCTION func, bool staticVar = false) {
sq_pushobject(vm, GetObject());
sq_pushstring(vm, name, -1);
SQUserPointer methodPtr = sq_newuserdata(vm, static_cast<SQUnsignedInteger>(methodSize));
memcpy(methodPtr, method, methodSize);
sq_newclosure(vm, func, 1);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
inline void BindFunc(const SQInteger index, void* method, size_t methodSize, SQFUNCTION func, bool staticVar = false) {
sq_pushobject(vm, GetObject());
sq_pushinteger(vm, index);
SQUserPointer methodPtr = sq_newuserdata(vm, static_cast<SQUnsignedInteger>(methodSize));
memcpy(methodPtr, method, methodSize);
sq_newclosure(vm, func, 1);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
// Bind a function and it's associated Squirrel closure to the object
inline void BindOverload(const SQChar* name, void* method, size_t methodSize, SQFUNCTION func, SQFUNCTION overload, int argCount, bool staticVar = false) {
string overloadName = SqOverloadName::Get(name, argCount);
sq_pushobject(vm, GetObject());
// Bind overload handler
sq_pushstring(vm, name, -1);
sq_pushstring(vm, name, -1); // function name is passed as a free variable
sq_newclosure(vm, overload, 1);
sq_newslot(vm, -3, staticVar);
// Bind overloaded function
sq_pushstring(vm, overloadName.c_str(), -1);
SQUserPointer methodPtr = sq_newuserdata(vm, static_cast<SQUnsignedInteger>(methodSize));
memcpy(methodPtr, method, methodSize);
sq_newclosure(vm, func, 1);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
// Set the value of a variable on the object. Changes to values set this way are not reciprocated
template<class V>
inline void BindValue(const SQChar* name, const V& val, bool staticVar = false) {
sq_pushobject(vm, GetObject());
sq_pushstring(vm, name, -1);
PushVar(vm, val);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
template<class V>
inline void BindValue(const SQInteger index, const V& val, bool staticVar = false) {
sq_pushobject(vm, GetObject());
sq_pushinteger(vm, index);
PushVar(vm, val);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
// Set the value of an instance on the object. Changes to values set this way are reciprocated back to the source instance
template<class V>
inline void BindInstance(const SQChar* name, V* val, bool staticVar = false) {
sq_pushobject(vm, GetObject());
sq_pushstring(vm, name, -1);
PushVar(vm, val);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
template<class V>
inline void BindInstance(const SQInteger index, V* val, bool staticVar = false) {
sq_pushobject(vm, GetObject());
sq_pushinteger(vm, index);
PushVar(vm, val);
sq_newslot(vm, -3, staticVar);
sq_pop(vm,1); // pop table
}
};
//
// Overridden Getter/Setter
//
template<>
struct Var<Object> {
Object value;
Var(HSQUIRRELVM vm, SQInteger idx) {
HSQOBJECT sqValue;
sq_getstackobj(vm, idx, &sqValue);
value = Object(sqValue, vm);
}
static void push(HSQUIRRELVM vm, Object& value) {
sq_pushobject(vm, value.GetObject());
}
};
template<>
struct Var<Object&> {
Object value;
Var(HSQUIRRELVM vm, SQInteger idx) {
HSQOBJECT sqValue;
sq_getstackobj(vm, idx, &sqValue);
value = Object(sqValue, vm);
}
static void push(HSQUIRRELVM vm, Object& value) {
sq_pushobject(vm, value.GetObject());
}
};
template<>
struct Var<const Object&> {
Object value;
Var(HSQUIRRELVM vm, SQInteger idx) {
HSQOBJECT sqValue;
sq_getstackobj(vm, idx, &sqValue);
value = Object(sqValue, vm);
}
static void push(HSQUIRRELVM vm, Object& value) {
sq_pushobject(vm, value.GetObject());
}
};
}
#endif