Introduction to GameMonkey Script Part 2
Embedding GameMonkey
SetDot OperatorIf you experiment with some scripts on the new Vector type, you will notice that you can read data from it but not alter the data in any way outside of actual construction of the variable. We will now provide a SetDot operator override to handle the setting of the member data. The operands are similar to that of GetDot:
A function to handle the Set Dot operator for our vector class is as follows: void GM_CDECL OpSetDot(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[2].m_type == GM_STRING); gmStringObject* stringObj = static_cast<gmStringObject*>(GM_OBJECT(a_operands[2].m_value.m_ref)); const char* propname = stringObj->GetString(); // Create a variable to hold the data to assign // handle both ints and floats float newFloat = 0.0f; if(a_operands[1].m_type == GM_FLOAT) { newFloat = a_operands[1].m_value.m_float; } else if(a_operands[1].m_type == GM_INT) { newFloat = (float)a_operands[1].m_value.m_int; } // Assign the data if(::stricmp( propname, "x") == 0) { thisVec->x = newFloat; } else if(::stricmp( propname, "y") == 0) { thisVec->y = newFloat; } else if(::stricmp( propname, "z") == 0) { thisVec->z = newFloat; } }
As you can see, it follows a similar progression from the previous example, except this time we need to retrieve the value passed to the function by the script (operand #1). As before, the member is compared to the exported members and the assignment made accordingly. Adding the following line to the BindLib function will complete the simple type. a_machine->RegisterTypeOperator(Type, O_SETDOT, NULL, OpSetDot); I mentioned previously that GameMonkey Script user variables are reference types; this becomes evident now that you have working dot operators. For example, if one were to write a script such as: a = Vector( 20, 20, 30 ); b = a; b.x = 10; print(a.x); print(b.x); You would see that updating the value of b.x would also update the value of a.x as they both reference the same data. The solution to this would be to implement a copy constructor for the Vector type (or add a Copy function to the type) which would be used as such: a = Vector( 20, 20, 30 ); b = Vector( a ); b.x = 10; print(a.x); print(b.x); In this case you would notice that the data is copied and the two variables retain their own data. And there we have it; an almost complete simple vector type for you to use in your scripts. It is almost complete because we have not yet touched on the subject of Garbage Collection, which plays an important role in any bound type you create. |