diff options
Diffstat (limited to 'squirrel_3_0_1_stable/sqplus/SquirrelVM.h')
-rw-r--r-- | squirrel_3_0_1_stable/sqplus/SquirrelVM.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelVM.h b/squirrel_3_0_1_stable/sqplus/SquirrelVM.h new file mode 100644 index 000000000..ee66a2b76 --- /dev/null +++ b/squirrel_3_0_1_stable/sqplus/SquirrelVM.h @@ -0,0 +1,179 @@ +#ifndef _SQUIRREL_VM_H_ +#define _SQUIRREL_VM_H_ + +#include "SquirrelObject.h" + +struct SquirrelError { + SquirrelError(); + SquirrelError(const SQChar* s):desc(s){} + const SQChar *desc; +}; + +// This class can hold a reference to a SquirrelVM. It keeps a Squirrel ref +// to the VM to protect it from being deleted while held. +struct SquirrelVMSys { + SquirrelVMSys() { } + ~SquirrelVMSys(); + + void Set( HSQUIRRELVM v ); + void Set( const SquirrelObject& ov ); + void Reset( ){ _vm.Reset(); } + + SquirrelVMSys& operator = (HSQUIRRELVM v){ Set(v); return *this; } + operator HSQUIRRELVM () const; + +protected: + void PushRefVM(HSQUIRRELVM v); + void PopRefVM(); + SquirrelObject _vm; + friend class SquirrelVM; +}; + +// Notes on creating / destroying SquirrelVM:s: +// +// VM:s created through sq_open are special since they create a new +// SQSharedState. That shared state is later shared by any new thread +// or friend VM. sq_close can be used for closing VM:s created through +// sq_open (but not for friend VMs). +// +// Using squirrel references in SquirrelVMSys and SquirrelVM, one must +// make sure that these are all reset if one calls sq_close manually. +// +// When there are no more references to a VM, it is destroyed automatically, +// but the shared state is not! For VM:s created by SquirrelVM, it keeps +// a list of shared states it has created and will destroy them all on +// app shutdown. + +class SquirrelVM { + friend class SquirrelObject; + friend struct SquirrelError; + friend struct SquirrelVMSys; + +public: + // If a VM is passed as arg here, Init will not alter it. Otherwise + // a new VM is created and initialized. A squirrel reference is kept + // while it is the current VM. + static bool Init( HSQUIRRELVM v=NULL ); + + // Initialize with an externally created VM, without adding a ref + // on it. NOTE: This may not be compatible with Set/GetVMSys as + // we're just working with raw pointers here. + static bool InitNoRef( HSQUIRRELVM v ); + static BOOL IsInitialized(){return _VM == NULL?FALSE:TRUE;} + + static void Release(); // Release ref on VM and reset VM pointer + static void Shutdown(){ Release(); } + static void AppFinalShutdown(); // Call when finally shutting down app + + static BOOL Update(); //debugger and maybe GC later + + static SquirrelObject CompileScript(const SQChar *s); + static SquirrelObject CompileBuffer(const SQChar *s,const SQChar * debugInfo=_SC("console_buffer")); + static SquirrelObject RunScript(const SquirrelObject &o,SquirrelObject *_this = NULL); + + static void PrintFunc(HSQUIRRELVM v,const SQChar* s,...); + + static BOOL BeginCall(const SquirrelObject &func); + static BOOL BeginCall(const SquirrelObject &func,SquirrelObject &_this); + + static void PushParam(const SquirrelObject &o); + static void PushParam(const SQChar *s); + static void PushParam(SQInteger n); + static void PushParam(SQFloat f); + static void PushParam(SQUserPointer up); + static void PushParamNull(); + + static SquirrelObject EndCall(); + static SquirrelObject CreateString(const SQChar *s); + static SquirrelObject CreateTable(); + static SquirrelObject CreateArray(int size); + static SquirrelObject CreateInstance(SquirrelObject &oclass); // oclass is an existing class. Create an 'instance' (OT_INSTANCE) of oclass. + static SquirrelObject CreateFunction(SQFUNCTION func); + static SquirrelObject CreateUserData(int size); + + static const SquirrelObject &GetRootTable(); + static HSQUIRRELVM GetVMPtr() { return _VM; } + + // The sandbox VM ptr is one which cannot access functions bound with + // SqPlus. It is suitable for running non-trusted scripts that can only + // access basic functionality. + static void SetSandboxVMPtr(HSQUIRRELVM v) { + _sandboxVM = v; + } // SetSandboxVMPtr + + static HSQUIRRELVM GetSandboxVMPtr() { + return _sandboxVM; + } // GetSandboxVMPtr + + static void GetVMSys(SquirrelVMSys & vmSys) { + vmSys.Set( _vm ); + } // GetVMSys + + static void SetVMSys(const SquirrelVMSys & vmSys) { + Release(); + HSQUIRRELVM v = (HSQUIRRELVM)vmSys; + if( v ) + Init( v ); + } // SetVMSys + + static void PushValue(INT val) { + sq_pushinteger(_VM,val); + } // PushValue + static void PushValue(FLOAT val) { + sq_pushfloat(_VM,val); + } // PushValue + static void PushValue(bool val) { // Compiler treats SQBool as INT. + sq_pushbool(_VM,val); + } // PushValue + static void PushValue(SQChar * val) { + sq_pushstring(_VM,val,-1); + } // PushValue + static void PushValue(SQUserPointer val) { + sq_pushuserpointer(_VM,val); + } // PushValue + static void PushValue(const SQChar * val) { + sq_pushstring(_VM,val,-1); + } // PushValue + static void PushObject(SquirrelObject & so) { + sq_pushobject(_VM,so._o); + } // PushObject + static void Pop(SQInteger nelemstopop) { + sq_pop(_VM,nelemstopop); + } // Pop + + static void PushRootTable(void); + + // Create/bind a function on the table currently on the stack. + static SquirrelObject CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + // Create/bind a function on the table so. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. + static SquirrelObject CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + // Create/bind a function to the root table. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. + static SquirrelObject CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + + // This is a helper to correct a difference in referncing new VM:s in + // ref counted versus garbage collected modes. NOTE: Only use after creating + // a VM with: 1 - sq_open() 2 - Creating a ref to the VM (SquirrelObject) + static void DropVMRefIfRefCounted( HSQUIRRELVM v ); + + +private: + static SquirrelObject _vm; // This is a Squirrel reference to the VM + static HSQUIRRELVM _VM; // The raw C++ pointer + static bool _no_vm_ref; // Set if we only keep the raw C++ pointer and no ref + static int _CallState; + static SquirrelObject * _root; // Cached root table if non NULL + static HSQUIRRELVM _sandboxVM; // The sandbox VM (that cannot use bound functions) +}; + + +template<typename T> +inline BOOL SquirrelObject::ArrayAppend(T item) { + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + SquirrelVM::PushValue(item); + BOOL res = sq_arrayappend(SquirrelVM::_VM,-2) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); + return res; +} // ArrayAppend + +#endif //_SQUIRREL_VM_H_ + |