GameMonkey Script

GameMonkey Script Forums
It is currently Wed Jan 23, 2019 1:55 pm

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Few questions
PostPosted: Sat Jul 25, 2009 1:37 am 
Offline

Joined: Fri Jul 24, 2009 1:09 pm
Posts: 27
Hey. I have a few questions regarding the use of GM script:

  1. Is there a preferable choice between a singleton and a global for the gmMachine object? My project uses singletons for anything that provides global access, so I'm thinking of making it the gmMachine object a singleton as well, but wanted to see if there were any downsides to this.
  2. In my attempt to cut down on them, I chose not to make my Dialogue_Manager a singleton. But now I'm wondering how GM scripts will get hold of the instance of Dialogue_Manager. If my engine doesn't care what the script is doing and instead provides an interface for the script to do what it needs to, how will it know what C++ objects to pass to the script?
  3. Where and how should I register the C++ functions that I want to provide for GM script? Do I just keep adding to some giant array of functions? Should I use a static "init" flag to ensure the functions are only registered once? Is there a better approach that everyone else uses?
  4. What is a thread in GM script? I am trying to find the definition of it but I can't seem to.

Cheers. :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Few questions
PostPosted: Sat Jul 25, 2009 2:36 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
I'll have a quick go at answering some of your questions. Hopefully other people might pop in to share their opinions...

1) gmMachine singleton - There is nothing wrong with doing things this way. You might want to use a singleton style accessor but manually initialize and destroy the gmMachine instance, just so you have fine control over this for initialization order. You can still make multiple machine instances if you like, just take care with passing the correct instance to functions that need it. Take care if you use multiple OS threads as there is nothing specific in GM to work this way.

2 & 3) Interfacing with C/C++. I recommend using a binding aid like the one developed by DrEvil and Downgraded:
viewtopic.php?f=14&t=422
You may also want to look at how scripts are bound in other games and use a registration system with minimal macros and templates.
If you do C style function binding, there is no reason not to contain the functions in a class as a collection of static functions.
You will also have to think about the life of 'objects' in script and native (C/C++). If you do things like check for null, use handles and type checks, you can safely work with objects in script or natively without instability.
Keep things simple. Do you need to pass object handles to script at all? Do you need to replicate many native types in script? There are many possible solutions, you want the simplest code and cleanest interface.

4) A gmThread is a 'cooperative routine'. You can think of it as a safe independent thread, but in practice they are executed in sequence and do not automatically relinquish their execution. They are convenient to control multiple things (apparently) at once, but you should regularly sleep, yield or block them to prevent CPU hogging. Ideally you want your scripts to wake up and run for short periods, or execute in response to (logical) events, not run continuously and in large numbers and get along by yielding and arbitrary sleeping. (Downgraded has a brilliant new tutorial due later this month on this very subject.)


Top
 Profile  
Reply with quote  
 Post subject: Re: Few questions
PostPosted: Sat Jul 25, 2009 4:11 am 
Offline

Joined: Fri Jul 24, 2009 1:09 pm
Posts: 27
Thanks for the prompt reply. :)

Greg wrote:
You might want to use a singleton style accessor but manually initialize and destroy the gmMachine instance, just so you have fine control over this for initialization order.

How does this look:
Code:
#ifndef _GMMACHINESINGLETON_H_
#define _GMMACHINESINGLETON_H_

#include "gmMachine.h"

class gmMachineSingleton
{
public:
    // Initialise gmMachine instance.
    // Returns true if initialised, false if was already initiliased.
   static bool Initialise();
    // Destroy gmMachine instance.
    // Returns true if destroyed, false if was already destroyed.
    static bool CleanUp();
   static gmMachineSingleton& Get();
private:
   gmMachineSingleton();
   ~gmMachineSingleton();

   static gmMachineSingleton instance;
   static bool initialised;

    gmMachine machine;
};

#define GM_MACHINE gmMachineSingleton::Get()

#endif

Code:
#include "stdafx.h"

#include "gmMachineSingleton.h"

gmMachineSingleton gmMachineSingleton::instance;
bool gmMachineSingleton::initialised = false;

bool gmMachineSingleton::Initialise()
{
    if(!initialised)
    {
        // Extra initialisation.

       initialised = true;

        return true;
    }
   
    return false;
}

bool gmMachineSingleton::CleanUp()
{
    if(!initialised)
    {
        return false;
    }

    initialised = false;

    // Extra clean up.

    return true;
}

gmMachineSingleton& gmMachineSingleton::Get()
{
   if(!initialised)
   {
      throw GM_EXCEPTION;
   }
   return instance;
}

gmMachineSingleton::gmMachineSingleton()
{
}

gmMachineSingleton::~gmMachineSingleton()
{
}


Greg wrote:
Interfacing with C/C++. I recommend using a binding aid like the one developed by DrEvil and Downgraded:
I can't find any files on the source forge link, nor can I find a url to checkout with SVN. :(

Greg wrote:
If you do C style function binding, there is no reason not to contain the functions in a class as a collection of static functions.
You will also have to think about the life of 'objects' in script and native (C/C++). If you do things like check for null, use handles and type checks, you can safely work with objects in script or natively without instability.
I'm not sure what you mean by this, sorry. Haha.

Greg wrote:
Keep things simple. Do you need to pass object handles to script at all? Do you need to replicate many native types in script? There are many possible solutions, you want the simplest code and cleanest interface.
For many things - like sound for example - I have used singletons and so it would be easy to create a free function play_sound() for example. However, for things like rendering animations, if the script called a create_animation() function or something, the animation would have to be stored in some kind of animation manager that handles animation rendering and updating for the duration of the animation. Does this sound ok?

Greg wrote:
4) A gmThread is a 'cooperative routine'. You can think of it as a safe independent thread, but in practice they are executed in sequence and do not automatically relinquish their execution. They are convenient to control multiple things (apparently) at once, but you should regularly sleep, yield or block them to prevent CPU hogging. Ideally you want your scripts to wake up and run for short periods, or execute in response to (logical) events, not run continuously and in large numbers and get along by yielding and arbitrary sleeping. (Downgraded has a brilliant new tutorial due later this month on this very subject.)
So would creation of a gmThread technically implement the thread count in Windows Task Manager? I don't know much about threads, and from what you say, I should be fine to ignore them if I only use the script to respond to events (which is pretty much what I'll be doing).

Cheers.


Top
 Profile  
Reply with quote  
 Post subject: Re: Few questions
PostPosted: Sat Jul 25, 2009 5:05 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
I'll answer quickly because there is otherwise too much to discuss...
Quote:
How does this look: ...

That is all fine, but you may not need much more than a stored pointer, public access function and debug build null check.

Quote:
I can't find any files on the source forge link, nor can I find a url to checkout with SVN. :(

I'll let DrEvil answer this. I recall either having to log in first, or requiring a login from DrEvil himself, before accessing the source tree.

Quote:
I'm not sure what you mean by this, sorry. Haha.

Script objects kind of encapsulate or box native objects so, for example, if you store in a gmUserObject a integer handle, shared native pointer or double dereferenced pointer, you could check if the object is valid even if it has logically or physically been deleted. It's all up to your implementation choices.

Quote:
For many things - like sound for example - I have used singletons and so it would be easy to create a free function play_sound() for example. However, for things like rendering animations, if the script called a create_animation() function or something, the animation would have to be stored in some kind of animation manager that handles animation rendering and updating for the duration of the animation. Does this sound ok?

Yes, I think that sounds ok. You will need a way to identify logical objects between C and script. In the end, you could have script code looking like any of these following lines. There are trade offs with performance, interface, implementation complexity. What is still not obvious from the following examples is what is a native bound type and what is defined entirely in script, which is usually a good thing.
Code:
cabinDoor.PlayAnimation("open");
PlayAnimation("CabinDoor17", "open");
cabinDoor.PlayAnimation( openAnim );


Quote:
So would creation of a gmThread technically implement the thread count in Windows Task Manager? I don't know much about threads, and from what you say, I should be fine to ignore them if I only use the script to respond to events (which is pretty much what I'll be doing).
gmThreads have nothing to do with OS threads. They also do not run concurrently in any way, so they are 'safe' as far as allowing access to any data at any time, since conflict is impossible.
I'm also saying using a bunch of threads is fine and good (in fact you can't avoid using them), but for example, having an active thread for every game/app object sitting in a loop with yeid() is a waste of CPU time. Just like OS threads, they are most efficient when they do nothing! Only wake or create when they are needed to perform some necessary work.
For example, calling script functions from C++ to handle an event like a user interaction or game object collision/trigger is good. A thread would be created, execute some script, then exit. If you had a latent function which blocked, you could write script like:
Code:
WalkThere();
DoThat();

or

WalkThere();
block(thereYet); // This could be required, depending on implementation.
DoThat();
which is better than
Code:
while( !thereYet )
{
  thereYet = walkForward();
  yield();
}
DoThat();


Top
 Profile  
Reply with quote  
 Post subject: Re: Few questions
PostPosted: Sat Jul 25, 2009 7:23 am 
Offline

Joined: Fri Jul 24, 2009 1:09 pm
Posts: 27
Thanks for that Greg. :)

I've decided that I'll register the host functions (that belong to singletons) with the gmMachine in their Initialise function:
Code:
void SDL_Audio_Player::Initialise(int global_volume_percent, bool muted,
unsigned short pos_sound_str, double fade_out)
{
    if(initialised)
    { // Already initialised.
        LOG("Warning: SDL_Audio_Player already intialised.");
        return;
    }

    LOG("Initialising SDL_Audio_Player...");

    // ...

    GM_REG_LIB_FUNC("play_music", play_music);
    GM_REG_LIB_FUNC("stop_music", stop_music);
    GM_REG_LIB_FUNC("fade_music_out", fade_music_out);

    initialised = true;
    LOG("SDL_Audio_Player initialised.");
}

Code:
#define GM_REG_LIB_FUNC(funcName, func) gmMachineSingleton::Get().RegisterLibraryFunction(funcName, func)


Top
 Profile  
Reply with quote  
 Post subject: Re: Few questions
PostPosted: Sun Jul 26, 2009 8:22 pm 
Offline

Joined: Thu Jan 01, 2004 4:31 pm
Posts: 307
Greg wrote:
Quote:
I can't find any files on the source forge link, nor can I find a url to checkout with SVN. :(

I'll let DrEvil answer this. I recall either having to log in first, or requiring a login from DrEvil himself, before accessing the source tree.


Just need SVN and you can pull it down from SF.net using:

svn co https://gmscriptex.svn.sourceforge.net/ ... gmscriptex gmscriptex

Not sure how intertwined gmBind2 is with gmMachineEx though, I tend to do most of my bindings manually these days (heh)


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 2 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