Hello,
I recently started thinking about scripting in our game engine and I looked what different scripting solutions have to offer. I found Angel Script cause it was mentioned on Wolfire's blog and I must say I really love it. I'm a Python guy so I thought LUA would be good, but after comparing those two I'm amazed how cool AS is. And how easy it was to implement basic functionality with it for a noob like me. I already have a GameEntity scripting proxy that allows me to control and extend in-game objects by AS scripts. I'm now adding some basic types like Vec3 for some math operations. Here where I got into some troubles.
I used Vector3 addon as reference on how to implement our own Vec3 class. We have that class as a template (VEC3<float>, VEC3<double> etc.) but I wanted to just register VEC3<float> version for now, as a non-template in AS, so I can use it as a basic "vec3" type. All went well with basic registration, property access, constructors but when I got to operators I couldn't make it work with addon sample code.
In Vector3 you do something like this:
r = engine->RegisterObjectMethod("vector3", "vector3 opAdd(const vector3 &in) const", asFUNCTIONPR(operator+, (const Vector3&,
const Vector3&), Vector3), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
When I tried similar way for our VEC3:
r = engine->RegisterObjectMethod("vec3", "vec3 opAdd(const vec3 &in) const", asFUNCTIONPR(operator+, (const Vec3f&, const Vec3f&),
Vec3f), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
I started getting compiler error: .\src\Managers\ScriptManager.cpp(54) : error C2065: '+' : undeclared identifier
This is part of my VEC3's operator overloading:
VEC3 operator + (const VEC3 &v) const;
VEC3<T> VEC3<T>::operator + (const VEC3<T> &v) const
{
return VEC3(x + v.x, y + v.y, z + v.z);
}
I noticed that second parameter to asFUNCTIONPR has 2 values in Vector3 sample, and I also used 2 but it seems like I should only use 1 looking at how our operator+ is overloaded. So I changed it, but it didn't fix the error:
r = engine->RegisterObjectMethod("vec3", "vec3 opAdd(const vec3 &in) const", asFUNCTIONPR(operator+, (const Vec3f&),
Vec3f), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
This still continued to give undeclared identifier '+' error on compile. What is the reason for this? I tried to see what that asFUNCTIONPTR does but this:
#define asFUNCTIONPR(f,p,r) asFunctionPtr((void (*)())(static_cast<r (*)p>(f)))
looks to me like a BrainF.. language, I know nothing about function pointers in so advanced form. Could anyone please point me what may be the problem?
EDIT:
I think I found the reason, I was using asFUNCTIONPR when it was a class operator I was refering too. I looked at Vector3 addon code and found that it defines some of the operations (*, /, +, - etc.) as functions that are friended? (if I'm correct) by a Vector3 struct.
Vector3 operator*(const Vector3 &v, float s)
{
// Return a new object as a script handle
Vector3 res(v.x * s, v.y * s, v.z * s);
return res;
}
I changed the code to:
engine->RegisterObjectMethod("vec3", "vec3 opAdd(const vec3 &in) const", asMETHODPR(Vec3f, operator+, (const Vec3f &) const, Vec3f), asCALL_THISCALL); assert( r >= 0 );
and now it compiles and seem to work (add etc.) for now Can someone explain in simple words why Vector3 sample does that thing with defining function outside of struct for some of the operators, instead of doing it as other operators (with methods)? Even though it works for me, I like to understand why things were done one or other way. Thanks!