Utility library for providing native functionality to the Squirrel environment.

Dependents:   Squirrel

Revision:
0:a9a5c12f2d30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/sqbind_usage.txt	Tue Dec 16 08:15:55 2014 +0000
@@ -0,0 +1,304 @@
+
+SQBind (c) 2009 Juan Linietsky
+
+--Introduction:--
+
+ SQBind is a pretty simple, yet powerful binding library for the Squirrel
+language. It supports for binding classes, methods, static methods, member
+variables, functions, enums, C types. It can either manage pointers, or let
+them unmanaged. It also recognizes functions that receive pointers or
+references, and it passes values accordingly. On top of all that, SQBind
+easily lets you use your own types for taking care of native Squirrel types,
+such as your own (or std::) string class, table class, array class, etc.
+  SQBind is _really_ simple. It consists of an only header file and a
+binders file, so you don't need to link against it. However, since SQBind 
+uses C++ Partial Specialization very heavily, it will probably not work on 
+older compilers. SQBind produces lightweight bindings, as it is designed
+to reuse template symbols as much as possible when binding methods/functions.
+
+--Compilation:--
+
+ Just drop sbind.h and .inc in a directory and include it. Alternatively,
+you may wish to define a SQBIND_CUSTOMIZE header, to allow SQBind to adapt
+to your project better. You can configure the following macros:
+
+SQBIND_NEW() - replaces new
+SQBIND_DELETE() - replaces delete
+SQBIND_INLINE - replaces inline
+SQBIND_DEBUG - catches/prints more errors, but becomes slower.
+
+ Customizing is done by defining SQBIND_CUSTOMIZE right before including
+sqbind.h, like this:
+
+#define SQBIND_CUSTOMIZE "sqbind_custom.h"
+#include "sqbind.h" 
+
+--Usage:--
+
+ -Initializing-
+
+ Before a class is ready for usage, it must be initialized. This is done 
+with a single line (note , 'vm' is the actual HSQUIRRELVM instance):
+
+	SqBind<MyClass>::init(vm,_SC("MyClass"));
+
+//note that _SC is used because Squirrel may be in unicode mode.
+
+ Optionally, inheritance can be defined, as well as non-instantiation
+property. Full initialization lines are:
+
+	SqBind<T>::init(HSQUIRRELVM v,const SQChar * p_name,const SQChar
+*p_base_class_name, bool p_instantiable=true);
+
+or
+
+	SqBind<T>::init(HSQUIRRELVM v,const SQChar * p_name,HSQOBJECT *p_base_class=NULL, bool p_instantiable=true)'
+
+ -Binding a Method-
+
+ Binding a method is done with the "sqbind_method" function. Just pass the
+method pointer (with up to seven parameters) and desired name:
+
+	sqbind_method( vm, "say_hello", &MyClass::say_hello );
+
+  SQBind will recognize the class and pointer from it and it will bind it
+automatically.
+
+-Binding a Function/Static Method-
+
+ Binding a function or a static method is pretty much the same. The catch
+is that static methods need to be passed the class_id owner in the end
+(which can be obtained by calling to SqBind<MyClass>::get_id() )
+
+  :function:
+
+	sqbind_function( vm, "say_goodbye", my_function );
+
+  :static method:
+
+	sqbind_function( vm, "say_goodbye", &SqBind<MyClass>::get_id() );
+
+ -Binding a Squirrel-Native method-
+
+ Native Squirrel methods (SQFUNCTION) is done this way:
+
+	SqBind<MyClass>::bind_method( vm, _SC("difficult_to_bind"), difficult_method);
+
+ Optionally a "static" parameter can be passed to make it static.
+
+ -Binding a Member Variable-
+
+  Binding member variables gets a little trickier, because even if the usage
+of offsetof is valid for this case, C++ compilers advise against it. So, you
+either make your own (more compatible) offsetof, or bind your own _get /
+_set metamethods:
+
+#define OFFSET_OF(st, m) \
+((size_t) ( (char *)&(_nullptr<st>()->m) - (char *)0 ))
+
+	class MyClass {
+	public:
+	
+		int a;
+		float b;
+	};
+
+	SqBind<MyClass>::bind_member_variable<int>( vm, _SC("a"), OFFSET_OF( MyClass, a) );
+	SqBind<MyClass>::bind_member_variable<float>( vm, _SC("b"), OFFSET_OF( MyClass, b) );
+
+ Note that it's very easy to make mistakes when using this helper, so be very careful
+with the types and offsets passed.
+
+ -Binding Enums-
+
+ Before binding any function that returns or takes an enum as parameter,
+SQBind must be told that we are dealing with an integer-like type. This is
+done by defining (globally) the following macro:
+
+	// not inside a function or method!
+	// note that if vm is not passed, this is not "called"
+	SQBIND_INTEGER( MyEnum );
+
+ -Binding Enum-Values and Constants-
+
+ Depending on wether we are dealing with global, or member enums or
+constants, there are 2 macros supplied for this:
+
+	// call to bind
+	SQBIND_CLASS_CONSTANT( vm, MyClass, CONSTANT );
+
+ This will make MyClass::CONSTANT accesible to the script. For global
+constants:
+
+	SQBIND_CONSTANT( vm, CONSTANT );
+
+ -Constructing / Destructing-
+
+ SQBind assumes that the classes you ar binding have a default constructor,
+a default copy constructor, and that they can be deleted using "delete" (or
+wathever is supplied in SQBIND_CUSTOMIZE). This is not always the case,
+specially with classes that contain pure virtual methods, or that are just
+not designed for it. To solve this issue, am "SqBindAllocator" specialization for
+a given class must be provided like this:
+
+
+template<>
+struct SqBindAllocator<MyClass> {
+ 
+	static MyClass *construct() {
+	
+		return NULL; // make it not able to construct
+	}
+	static SQBIND_INLINE MyClass *copy_construct(const MyClass* p_from) {
+	
+		return NULL; // make it not able to copy-construct
+	}
+	static SQBIND_INLINE bool assign(MyClass* p_val, const MyClass* p_from) {
+	
+		return false; // make it not able to assign
+	}
+	static SQBIND_INLINE void destruct(MyClass* p_instance) {
+	
+		// make it ignore destruction
+	}
+	
+	static SQBIND_INLINE MyClass& get_empty() {
+		// if someone tries to assign, this will crash.	
+		// however, this will likely never be called anyway.
+		static MyClass *crashplease=NULL;
+		return *crashplease;
+	}
+}
+
+ By simply defining this allocator before using SqBind<MyClass>, the
+behavior for such operations will be customized.
+
+ -Custom Constructor-
+
+ By default, SQBind doesn't understand extra construction parameters. It
+is up to the programmer to create an instance from them. This is done by 
+setting a custom constructor. SqBind will still ease the task of the
+programmer by not calling the custom constructor when no parameters or copy
+constructor is required. If you still want to take complete control of
+the construction stage, bind a "constructor" function manually.
+
+// class to bind
+
+class Vector3 {
+public:
+
+  float x;
+  float y;
+  float z;
+
+  Vector3(float _x=0, float _y=0, float _z=0) {
+
+	x=_x;
+	y=_y;
+	z=_z;
+  }
+};
+
+// custom constructor
+
+static Vector3* vector3_constructor(HSQUIRRELVM v) {
+
+	// regular and copycon handled by sqbind
+	
+	int params=sq_gettop(v);
+	
+	if (params!=4)
+		return NULL; // need 3 params
+				
+	SQFloat x;
+	SQFloat y;
+	SQFloat z;
+	
+	if (SQ_FAILED( sq_getfloat(v,2,&x) ) )
+		return NULL;
+	if (SQ_FAILED( sq_getfloat(v,3,&y) ) )
+		return NULL;
+	if (SQ_FAILED( sq_getfloat(v,4,&z) ) )
+		return NULL;
+	
+	return new Vector3(x,y,z);
+
+}
+
+..
+
+int main() {
+
+	SqBind<Vector3>::init(vm,_SC("Vector3"));
+	SqBind<Vector3>::set_custom_constructor( vector3_constructor );
+}
+
+-Creating Binders for Native Types-
+
+ Creating binders for C++ types that translate to nativetypes must be done
+by specializing SqBind. Following is an example for binding std::string with
+the native Squirrel string:
+
+template<>
+class SqBind<std::string> {
+public:
+	struct Getter {
+		SQBIND_INLINE std::string get(HSQUIRRELVM v, int p_idx) {
+			return SqBind<std::string>::get(v,2);
+		}
+	};
+	struct GetterPtr {
+		std::string temp;
+		SQBIND_INLINE std::string* get(HSQUIRRELVM v, int p_idx) {
+			temp=SqBind<std::string>::get(v,2);
+			return &temp;
+		}
+	};
+	static std::string get(HSQUIRRELVM v, int p_idx) {
+		if (sq_gettype(v,p_idx)!=OT_STRING) {
+			sqbind_throwerror(v,"Type is not string!");
+			return std::string();
+		}
+		const SQChar * str;
+		sq_getstring(v,p_idx,&str);
+		return std::string(str);
+	}
+
+	static void push(HSQUIRRELVM v, const std::string& p_value) {
+		sq_pushstring(v,p_value.c_str(),-1);
+	}
+};
+
+
+--License--
+
+ SQBind is provided under the MIT license:
+
+Copyright (c) 2009 Juan Linietsky
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+--Contact--
+
+ You can contact the author (Juan Linietsky) via e-mail at:
+	 reduzio@gmail.com
+