GameMonkey Script

GameMonkey Script Forums
It is currently Wed Aug 15, 2018 1:38 am

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Brains
PostPosted: Mon Nov 08, 2010 12:53 pm 
Offline

Joined: Fri Jun 04, 2010 11:45 am
Posts: 8
Hi,

I know I can bind functions to classes, but can I bind functions to objects?
For example I have a robot class and I want to simulate their microchip control unit, their brain. And I do not want to make a class for every robot. So can I make e.g. a void think() function and bind different script functions to different objects, with something like overloaded functions?

Example:

Robot1.Think() does
this.rotate(1);
this.move(2);

and

Robot2.Think() does
this.move(1);
if(this.x>2)
this.rotate(-2);

greetings
greetings


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Tue Nov 09, 2010 12:35 am 
Offline

Joined: Tue Nov 11, 2008 9:03 am
Posts: 20
There is no class concept in native GameMonkey, the closest you'd get is implemeting a custom user type in C++.
But this is partly the point of GameMonkey, if you use table as your base type you can easily mimic dynamic classes and be very flexible.
eg:
Code:
local Robot1 = MakeRobot();
Robot1.Think = function()
{
 .rotate(1);
 .rotate(2);
};

local Robot2 = MakeRobot();
Robot2.Think = function()
{
 .move(1);
 if ( .x > 2 )
 {
   .rotate(-2);
 }
};


At lowest level everything is just table type.


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Tue Nov 09, 2010 4:19 am 
Offline

Joined: Fri Jun 04, 2010 11:45 am
Posts: 8
Thanks :)
That's exactly what I need.

greetings


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Wed Nov 17, 2010 6:55 am 
Offline

Joined: Fri Jun 04, 2010 11:45 am
Posts: 8
Hi,

I created a simple object/table setup and bound it to gamemonkey like described in this tutorial: http://www.gamedev.net/reference/progra ... /page8.asp

Code:
class CDoor : public gmTableObject{
public:
    CDoor(gmMachine *a_machine){
        Construct(a_machine);
        printf("I am a Door!\n");
    };
    ~CDoor(){printf("A Door I am no more!\n");};
};


I then tried this in a script:
Code:
somedoor = Door();
print("working");
somedoor.angle = 1234;
print("working");
print(somedoor.angle);
print("working");


The console output is this:
Code:
I am a Door!
working


If I use somedoor = table(); instead, it works like it should. How do I inherit the table type correctly?

greetings


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Wed Nov 17, 2010 3:00 pm 
Offline

Joined: Fri Jan 14, 2005 2:28 am
Posts: 439
I really advise against inheriting from gmTableObject. That was never the intent of that class.

I think the point was that you can fake inheritance with some relatively simple table scripting.

Basically the idea is that you 'construct' your object from the base class down to the derived class, allowing each derived class definition to overwrite whatever may be defined by the base class, ultimately resulting in a new 'object' table that is the result of the inherited tree of table information.

Off the top of my head.

Code:
base = {
   classType = "base";
   update = function() { ... }
};

derived1 = {
   classType = "derived1";
   inherits = base, // with a bit extra scripting, you could do multiple inheritance
   update = function() { ... },
   someFunc = function() { ... },

   someVar = 10,
   someOtherVar = "blah";
}

CopyTableRecursively = function( typeTable, destTable ) {
   // always go up to the top level parent to copy values first, so child classes can override the parent functions or default values, etc
   if ( typeTable.inherits != null ) {
      CopyTableRecursively( typeTable.inherits, destTable );
   }

   // copy all values from the type table into the new object table
   foreach( k, v in typeTable ) {
      destTable[ k ] = v;
   }

};

// returns a NEW table, that contains the collection of all the inherited table chain
AllocObjectType = function( typeTable ) {
   newObj = {}
   CopyTableRecursively ( typeTable, newObj );
   return newObj;
};

// example usage
myNewObject = AllocObjectType( derived1 );
assert( myNewObject.classType == "derived1" );
myNewObject.update();
myNewObject.someFunc();
print( myNewObject.someVar );
print( myNewObject.someOtherVar );


In my gmBinder library I wrote for GM, you can bind native side classes to script with inheritance. Basically the binding works in a similar way, by binding all the parent variables and functions to the script object type. Ultimately they are seen as discreet types within the scripting language, the binding just provides the convenience of not having to duplicate code in each child class to bind properties from parent classes.


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Wed Nov 17, 2010 7:59 pm 
Offline

Joined: Fri Jun 04, 2010 11:45 am
Posts: 8
Ok, thanks, I think I get the idea.
You basically take a base table and copy the 'old' functions and variables to the new, overwriting some of them.

I made the code compilable:
Code:
base = {
   classType = "base",
   Update = function() {print("base update");}
};

derived1 = {
   classType = "derived1",
   inherits = base, // with a bit extra scripting, you could do multiple inheritance
   Update = function() {print("overwritten update");},
   someFunc = function() {print("some function");},

   someVar = 10,
   someOtherVar = "blah"
};

global CopyTableRecursively = function( typeTable, destTable ) {
   // always go up to the top level parent to copy values first, so child classes can override the parent functions or default values, etc
   if ( typeTable.inherits != null ) {
      CopyTableRecursively( typeTable.inherits, destTable );
   }

   // copy all values from the type table into the new object table
   foreach( k and v in typeTable ) {
      destTable[ k ] = v;
   }
};


// returns a NEW table, that contains the collection of all the inherited table chain
AllocObjectType = function( typeTable ) {
   newObj = table();
   CopyTableRecursively ( typeTable, newObj );
   return newObj;
};

// example usage
myNewObject = AllocObjectType( derived1 );
assert( myNewObject.classType == "derived1" );
myNewObject.Update();
myNewObject.someFunc();
print( myNewObject.someVar );
print( myNewObject.someOtherVar );


But I still cannot get my C++ class working with that concept. I simply tried replacing "inherits = base" with "inherits = Door" (trial & error method, I know might be stupid) but it didn't work.
So basically I want a user type like a table that can have overwritable methods.
Also, with usertypes I have to call myType:DoSomething(), while with tables I can call myTable.DoSomething().

Please be patient with me :|
greetings


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Thu Nov 18, 2010 5:14 pm 
Offline

Joined: Fri Jan 14, 2005 2:28 am
Posts: 439
So you basically want to extend a native bound type from script ? Basically inherit from a native type as a full script side object type(with script defined vars/functions)?


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Thu Nov 18, 2010 8:43 pm 
Offline

Joined: Fri Jun 04, 2010 11:45 am
Posts: 8
Yes, I want a native c++ class with script extendable/customizable functions and variables, e.g. to script different behaviour.

greetings


Top
 Profile  
Reply with quote  
 Post subject: Re: Brains
PostPosted: Fri Nov 19, 2010 2:08 pm 
Offline

Joined: Fri Jan 14, 2005 2:28 am
Posts: 439
If you start with something like gmBind or my gmBinder, these binding libraries create a gmTableObject for your native bound types, if you want them to be 'extensible' This table is where properties will go that don't exist on the core object. I'm not sure if they support this out of the box, but it's probably possible to tweak their setdot and setindex functions so that you can effectively assign a new function in place of a bound function that will be called instead. The annoying part of instantiating this extended object is how best to construct it. You might just have to write a script function that creates the native user type and sets the extension values on the object. If I were to extend my gmBinder to do this, I would probably add a default bound function where you could do something like this.

Code:
base = {
   constructor = CreateMyNativeObject, // reference to the script bound native function that actually constructs your object
   classType = "base";
   update = function() { ... }
};

derived1 = {
   classType = "derived1",
   inherits = base, // with a bit extra scripting, you could do multiple inheritance
   Update = function() {print("overwritten update");},
   someFunc = function() {print("some function");},

   someVar = 10,
   someOtherVar = "blah"
};

CopyTableRecursively = function( typeTable, destTable ) {
   // always go up to the top level parent to copy values first, so child classes can override the parent functions or default values, etc
   if ( typeTable.inherits != null ) {
      CopyTableRecursively( typeTable.inherits, destTable );
   }

   // copy all values from the type table into the new object table
   foreach( k, v in typeTable ) {
      destTable[ k ] = v;
   }
};

// returns a NEW table, that contains the collection of all the inherited table chain
AllocObjectType = function( typeTable ) {
   extensionTable = {}
   CopyTableRecursively ( typeTable, extensionTable );

   // invoke the 'constructor' to create the base native type
   newObj = extensionTable.constructor();
   newObj.SetExtensions( extensionTable ); <= native bound function that copies the table to the 'extensible' table of the object instance
   return newObj;
};


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group