Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
115 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Introduction to GameMonkey Script Part 2
Embedding GameMonkey

Operator Overrides

If you have ever overridden a class operator in C++ you will know how powerful this feature is - operator overriding allows you to specify a function to control the behaviour of a type when certain script operators are used. The operators you can override for a type in GM Script are:

Dot Setv.x = 50;Setting of 'members'
Dot Geta = v.y;Getting of 'members'
Index Setv[0] = 100;Setting of indexed items
Index Geta = v[3];Getting of indexed items
Adda = v + v2;Addition of type variable with another variable
Suba = v - v2;Subtraction of type variable with another variable
Mula = v * v2;Multiplication of type variable with another variable
Diva = v / v2;Division of type variable with another variable

In this simple example I will only override the dot operators to provide access to the simulated member access method of the Vector data. Operator overriding follows the same structure for each operator so it is simple to adapt my example to use the index operators.

Operator functions all have the same signature:

void GM_CDECL operator_func(gmThread * a_thread, gmVariable * a_operands);

GetDot Operator

The operands passed to the operators vary on the type of operator. For the GetDot operator the operands are as follows:

Operand   Purpose
0The variable being operated upon and the return variable on exit (e.g.: 'v' in a = v.x; )
1The 'member' being accessed (as a gmStringObject) (e.g.: 'x' in a = v.x; )
2Data passed for assigning with the value from the object (e.g.: 'a' in a = v.x; )

The following code details the GetDot function we will be using:

void GM_CDECL OpGetDot(gmThread * a_thread, gmVariable * a_operands)
    GM_ASSERT(a_operands[0].m_type == Type);
    Vector* thisVec = static_cast<Vector*>(static_cast<gmUserObject*>(GM_OBJECT(a_operands[0].m_value.m_ref))->m_user);

    GM_ASSERT(a_operands[1].m_type == GM_STRING);
    gmStringObject* stringObj = static_cast<gmStringObject*>(GM_OBJECT(a_operands[1].m_value.m_ref));
    const char* propName = stringObj->GetString();

    // Resolve the member name
    if(::stricmp(propName, "x") == 0)
    else if(::stricmp(propName, "y") == 0)
    else if(::stricmp(propName, "z") == 0)

Example: vector_3.cpp

The process is simple; first we check that the type of the variable being operated on matches that of the newly bound Vector type. Afterwards, the string name of the member is retrieved and checked against the members we wish to export. Confusingly operand zero is also the return variable, so it must be set with the relevant value from the bound class. This is as simple as copying the value from the 'real' member in our class to the variable represented by operand zero. If there is a problem, you should nullify the return variable, which returns null to GameMonkey Script.

With the Get Dot operator function created, it's time to add its registration to the BindLib function we looked as earlier. This is as simple as calling the RegisterTypeOperator on the newly bound type, passing the relevant operator and function handler as parameters:

a_machine->RegisterTypeOperator(Type, O_GETDOT, NULL, OpGetDot);

SetDot Operator

  Basic Embedding Concepts
  Executing a String as a Script
  Executing a Script from File
  More on Script Execution
  gmVariable Object
  Calling a Scripted Function
  Creating a host-bound function
  Creating a simple type
  Constructor with Parameters
  Operator Overrides
  SetDot Operator
  Garbage Collection

  Source code
  Printable version
  Discuss this article

The Series
  Language Introduction
  Embedding GameMonkey