Hi all, Recently I've began to integrate AngelScript into my application, but have hit a snag. I want to access some fields of an object handled by the application and returned by a function. To that, I've created a simple wrapper in C++ for that object, and registered both the wrapper and the function. All compiles and runs, but the values returned are not the correct ones. Maybe you can show me where? The wrapper class:
class GUIWidgetWrapReference
{
public:
GUIWidgetWrapReference() : objWrapped(0), refCount(1) { std::cout << "GUIWidgetWrapReference()\n"; }
GUIWidgetWrapReference(gcn::Widget& obj) : objWrapped(&obj), refCount(1) { std::cout << "GUIWidgetWrapReference(&)\n"; }
~GUIWidgetWrapReference() { std::cout << "~GUIWidgetWrapReference()\n"; }
// script specific stuff
void AddRef() { std::cout << "AddRef\n"; refCount++; } // Increase the reference counter
void Release() { std::cout << "Release\n"; if( --refCount == 0 ) delete this; } // Decrease ref count and delete if it reaches 0
//
int getX() { return objWrapped->getX(); }
int getY() { return objWrapped->getY(); }
int getWidth() { return objWrapped->getWidth(); }
int getHeight() { return objWrapped->getHeight(); }
Vector2 getPosition() { return Vector2(objWrapped->getX(), objWrapped->getY()); }
Vector2 getDimensions() { return Vector2(objWrapped->getWidth(), objWrapped->getHeight()); }
public:
gcn::Widget* objWrapped;
private:
int refCount;
};
The registration for the wrapper (factory methods were purposely commented for the engine is not responsible for creating or managing objects of the type):
static void registerGUIWidgetAS(asIScriptEngine* engine)
{
int result;
// register as reference
// http://www.angelcode.com/angelscript/sdk/docs/manual/doc_reg_basicref.html
result = engine->RegisterObjectType("GUIWidget", 0, asOBJ_REF); assert( result >= 0 );
// Registering the factory behaviour
//result = engine->RegisterObjectBehaviour("GUIWidget", asBEHAVE_FACTORY, "GUIWidget@ f()", asFUNCTION(GUIWidgetDefaultFactory), asCALL_CDECL); assert( result >= 0 );
////result = engine->RegisterObjectBehaviour("GUIWidget", asBEHAVE_FACTORY, "GUIWidget@ f(const GUIWidget& in)", asFUNCTION(GUIWidgetCopyFactory), asCALL_CDECL); assert( result >= 0 );
//result = engine->RegisterObjectBehaviour("GUIWidget", asBEHAVE_FACTORY, "GUIWidget@ f(GUIWidget@)", asFUNCTION(GUIWidgetCopyFactory), asCALL_CDECL); assert( result >= 0 );
// Registering the addref/release behaviours
result = engine->RegisterObjectBehaviour("GUIWidget", asBEHAVE_ADDREF, "void f()", asMETHOD(GUIWidgetWrapReference,AddRef), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectBehaviour("GUIWidget", asBEHAVE_RELEASE, "void f()", asMETHOD(GUIWidgetWrapReference,Release), asCALL_THISCALL); assert( result >= 0 );
// register operators
result = engine->RegisterObjectMethod("GUIWidget", "Vector2 getPosition()", asMETHOD(GUIWidgetWrapReference, getPosition), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectMethod("GUIWidget", "Vector2 getDimensions()", asMETHOD(GUIWidgetWrapReference, getDimensions), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectMethod("GUIWidget", "int getX()", asMETHOD(GUIWidgetWrapReference, getX), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectMethod("GUIWidget", "int getY()", asMETHOD(GUIWidgetWrapReference, getY), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectMethod("GUIWidget", "int getWidth()", asMETHOD(GUIWidgetWrapReference, getWidth), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectMethod("GUIWidget", "int getHeight()", asMETHOD(GUIWidgetWrapReference, getHeight), asCALL_THISCALL); assert( result >= 0 );
result = engine->RegisterObjectMethod("GUIWidget", "GUIWidget& opAssign(const GUIWidget& in)", asMETHODPR(GUIWidgetWrapReference, operator=, (const GUIWidgetWrapReference&), GUIWidgetWrapReference&), asCALL_THISCALL); assert( result >= 0 );
}
The registration for the function I want to call (registered in another class, after this one has been registered):
result = engine->RegisterObjectMethod("GraphicalUserInterface", "GUIWidget& addLabel(string& in, string& in, Vector2& in, Vector2& in)", asMETHOD(GraphicalUserInterface,addLabel), asCALL_THISCALL); assert( result >= 0 );
The function to call (just the header):
gcn::Widget* addLabel(std::string id, std::string caption, Vector2 position, Vector2 dimensions);
Usage in the script:
uint guideHorizontalBeginning = 10;
GUIWidget@ label = gui.addLabel("labelTop", "Choose Action", Vector2(guideHorizontalBeginning, 5), Vector2(-1,-1));
print("label.getX() "+ label.getX() +"\n");
print("label.getWidth() "+ label.getWidth() +"\n");
After running the code, in the output console, only the "AddRef" and "Release" for the "GUIWidgetWrapReference" print, neither of the constructors do (so they are not called - I suspect this is the problem...), and the "label" values have absurd values (whereas in the function, after object creation, the values are correct). Thanks in advance.