GameMonkey Script

GameMonkey Script Forums
It is currently Tue Mar 19, 2019 7:25 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Fri Feb 19, 2010 3:24 am 
Offline

Joined: Fri Feb 19, 2010 2:34 am
Posts: 3
Hello, I'm new to GameMonkey, and while I've been able to figure most of it out from the tutorials on gamedev.net, I've run into a bit of trouble binding C++ functions for use in GameMonkey scripts. Eventually, I plan on using it to script effects for a rogue-like I'm writing, but before I start implementing it there, I want to get a basic demo of sorts running, so I can be sure I understand how it works.

I've managed to call functions from scripts without any trouble, but I can't figure out how to use my "wrapped" C++ functions from my GameMonkey scripts. I've put an incredibly simple function in the source file, but it isn't called from the script properly. I'm probably skipping something important, but here's what I have so far.
Code:
//This is the function from the source code...
int GM_CDECL test(gmThread *a_thread)
{
  std::cout << "It worked.";

  return GM_OK;
}

Code:
//This is the script file.
global add = function() {  test(); };

Code:
//This is the code that calls the function from the script.
gmLoadAndExecuteScript ( gm, "data/scripts/effects/testeffect.gm" );

gmCall call;
call.BeginGlobalFunction( &gm, "add");
call.End();


Is there more I have to do to allow the function to be called from the script?

Thanks!

Tim


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 19, 2010 6:17 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
Welcome to the forum timmeh :)

At quick glance I don't see any problem, I will have a closer look when I have some more time later today.
Are you registering your native bound function before calling it? Something like this:
Code:
gm.RegisterLibraryFunction("test", &test);


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 19, 2010 12:17 pm 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
I've had another look and still don't see any specific problem, so here's some thoughts:

o Check for (and report here if necessary) any error messages from C/C++ and script. Make sure you are logging the error messages by purposely creating some compile time and runtime errors.

o Compare your code to the example bindings and samples. (For a paranoid test, modify one of the sample programs with similar test code to what you show here.)

o Set break points in your C bound function to see if it is called. If not, call a function that is built in binding and break on that. Just in case cout or other logging functions do not show visible output.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 19, 2010 2:40 pm 
Offline

Joined: Fri Feb 19, 2010 2:34 am
Posts: 3
Greg wrote:
Welcome to the forum timmeh :)

At quick glance I don't see any problem, I will have a closer look when I have some more time later today.
Are you registering your native bound function before calling it? Something like this:
Code:
gm.RegisterLibraryFunction("test", &test);

Thanks :)

That was it, it works now... thanks! Now I'm going to have to go back over the tutorial and see how the heck I missed that :P

Out of curiosity, while the game I want to use GameMonkey with is object-oriented, I don't actually need GameMonkey to know it. I'm going to start by using for things like status effects, which will only need to know about the player, or the mob they're affecting (and the functions would be the same either way). If I were to register a function inside the enemy class, right before running the script (also from within the enemy class), would the functions (all of which are part of the enemy class) be run from the same instance of the object who's functions were registered with it?

I guess a better way of putting it would be, after wrapping the functions in the enemy class, if, as part of a function of that class, I registered the functions, and then ran a script, when those functions were called from the script, would they take effect on the enemy instance that's functions were registered (and called the script)?

Thanks again!


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 19, 2010 2:47 pm 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
timmeh wrote:
...I guess a better way of putting it would be, after wrapping the functions in the enemy class, if, as part of a function of that class, I registered the functions, and then ran a script, when those functions were called from the script, would they take effect on the enemy instance that's functions were registered (and called the script)?...

I think I know what you are getting at.
You probably want to do something like this...
1) Use static functions within C++ classes to store GM bound functions. This way, they have access to the related classes non-public members but still encapsulate nicely.
2) Bind a 'gameobject' 'entity' or whatever kind of user type. That user type will contain a reference or pointer which will allow you to access a C++ class instance for the real game object. Then you can identify which instance it is and call member functions directly. Doing part (1) makes this easier.

I recommend using a 'flatter' script class hierarchy (if any at all). Use type identifiers when you need to determine what type an object it is, or if specific behaviors exist. There is little value in duplicating C++ classes into unique script user types. In fact people often get away with a very small handful like 'Entity' 'Level' 'Game' and some of those may just be global table entries. The rest are Vector, and basic types. Keeps native <--> script interops simple.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 19, 2010 4:00 pm 
Offline

Joined: Fri Feb 19, 2010 2:34 am
Posts: 3
Greg wrote:
I think I know what you are getting at.
You probably want to do something like this...
1) Use static functions within C++ classes to store GM bound functions. This way, they have access to the related classes non-public members but still encapsulate nicely.
2) Bind a 'gameobject' 'entity' or whatever kind of user type. That user type will contain a reference or pointer which will allow you to access a C++ class instance for the real game object. Then you can identify which instance it is and call member functions directly. Doing part (1) makes this easier.

I recommend using a 'flatter' script class hierarchy (if any at all). Use type identifiers when you need to determine what type an object it is, or if specific behaviors exist. There is little value in duplicating C++ classes into unique script user types. In fact people often get away with a very small handful like 'Entity' 'Level' 'Game' and some of those may just be global table entries. The rest are Vector, and basic types. Keeps native <--> script interops simple.


Can I bind only part of an 'entity'? The GameDev tutorial is a little hard to follow in the section on types... Problem is, I only want to expose 5-7 of the class' functions to the script, and only for the single instance of the class that the script is operating on, otherwise there'd be no end to the strange and buggy things people could do accidentally :P

My first thought was to bind functions like this: "gm.RegisterLibraryFunction("set_value", &test1.setMyValue);" But it doesn't work.

The tutorial sounds like it would let me pass a sort of reference to the member's of a class, is there a way to do this with only specific public members, or would I have to expose the whole thing to the script?


Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 20, 2010 12:09 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
timmeh wrote:
...Can I bind only part of an 'entity'?...
Sure, you can bind as little or as much of a entity as you like. The lovely thing about GM is you can even specialize individual instances by adding or removing functionality. Have a play with it all and it will start to become clear what you can do and what the 'right' or 'nice' way to use it is. You won't end up accidentally exposing more than you intend to scriptwriters.


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

All times are UTC


Who is online

Users browsing this forum: Baidu [Spider] and 3 guests


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