• entries
437
1000
• views
337401

# gmBind2

191 views

I doubt anyone's used the original gmBind, my simple C++ binding library for GameMonkey Script. If you haven't, I'd recommend that you don't anyway as it was a pile of crap.

gmBind2 is coming along nicely and binds objects in a completely different way.

Take the example class:

class TestClass{public:	TestClass() : m_int(900), m_string("test"), m_float(800.0f) { }	TestClass( int a_int, float a_float, const std::string &a_string ) : m_int(a_int), m_string(a_string), m_float(a_float) { }	void test_method() { std::cout << "test_method" << std::endl; }	int test_method0() { std::cout << "test_method0" << std::endl; return 100; }	int test_method1( int a_num ) { std::cout << "test_method1 " << a_num << std::endl; return a_num; }	int m_int;	float m_float;	std::string m_string;};

Using the new gmBind, we bind it in a way similar to the following:-

    gmMachine gm;    // define the class    Class< TestClass > gmTestClass( "TestClass" );		 gmTestClass.cons( "construct" )		 .cons< int, float, std::string >( "construct0" )		 .var( "f", &TestClass::m_float )		 .var( "i", &TestClass::m_int )		 .var( "s", &TestClass::m_string )		 .func( "test_method", &TestClass::test_method )		 .func( "test_method0", &TestClass::test_method0 )		 .func( "test_method1", &TestClass::test_method1 )		 ;     // bind it     gmTestClass.bind( &gm );

From here you can use the class within GameMonkey Scripts with ease:-

test = TestClass.construct();// show default valuesprint( test.f, test.s, test.i );// change valuestest.f = 100.6;test.s = "string";test.i = 999;// show changed valuesprint( test.f, test.s, test.i );// Call bound methods:-test.test_method();print ( test.test_method0() );print ( test.test_method1( 700 ) );

Works a charm.

Now, the tricky part is when we start having multiple bound classes and types which then have members of exotic types. The issue here is that we need to have a way of figuring out that a type of "int", "float", "MyClass", "AnotherClass" relates to a given gmType number in the gmMachine. For this, I'm experimenting with a simple trick I found.

template< typename T >struct TypeInfo{  static size_t get_hash() { return (size_t)&TypeInfo< T >::get_hash; }};

This returns the address of the get_hash() function within that templated struct. Because it's templated, we have a different address for each type we compile it with. If you do a bit more template magic, you can determine the type of a given variable:-

template< typename T >inline size_t get_type_hash( T a ) { return TypeInfo< T >::get_hash(); }

Calling it using int i = 70; get_type_hash( i ); returns the address of the int-typed TypeInfo member. Pretty neat.

So using this method, I should, in theory, be able to correlate types within a user's program to gmType variables that GameMonkey uses.

NOTE: RTTI isn't a option here

Along with this, I have some additional features planned for gmBind2. The first is the virtual type 'namespace' (eg table) that contains a bunch of useful functions for a given type - things such as initialising a bound type from a table. In the example above, I had to set test.s, .f and .i individually. What I'm planning is the ability to do the following:-

test = TestClass.construct();TestClass.init_object( test, { s = "test", i = 68, f = 89.4 } );

Boom, the object 'test' has now had values m_int, m_float and m_string set from script using the values contained in the table. This method would allow people to say, load values into the table from a file and then use them to init objects within script.

I also want to allow users to bind get/set methods in their classes to a given GM property. So imagine your class:-

class Test{public:  ...  int get_myint() const { return m_int; }  void set_myint( int a_val ) { m_int = a_val; }private:  int m_int;     ...};

Having a get/set method called in script is just fugly eg:
test = Test.construct();test.set_myint( 50 );print( test.get_myint() );

The better way would be to allow the user to specify their own get/set methods and tie it to a single property. So the following works:-

test = Test.construct();test.myint = 50;print( test.myint );

Much better. I'm looking into ways of doing this now. Naturally the get/set method interface would HAVE to be uniform.

Aside from this, I also want to give the user power over the operators that they can expose to GameMonkey.

There's a bunch more that's going in there, but I guess, for now, I'll leave you alone :P

There are no comments to display.

## Create an account

Register a new account