c++classscriptinginstance

Register a C++ class in AngelScript and pass a class instance


I am having trouble following the AngelScript manual on the proper way to register class objects and pass a particular instance of the class to a script. Say I have a C++ class Circle that I would like to make aware to AngelScript.

class Circle
{
public:
    int getArea();

    int radius;
};

From here, I would like to create an instance of the Circle class, register the getArea() method to the AngelScript engine (or register all of the methods in the class automatically if that is possible), and pass the class instance itself to the AngelScript environment.

Circle circleInstance;
circleInstance.radius = 10;

// Initialize AngelScript engine

asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

engine->RegisterObjectMethod("Circle", "int getArea()",
    asMETHOD(Circle, getArea), asCALL_THISCALL);

In AngelScript, I would like to be able to call the method from the instance variable and return the result of the C++ function.

circleInstance.getArea();

However, in the above code I am clearly not passing the instance circleInstance to the AngelScript engine in any way, so the scripting environment has no idea of its existence. I assume I am overlooking something and that the answer is only about one or two lines of C++. Should I register the Circle class through a method like RegisterObjectType or RegisterInterface, and would I need to let Circle inherit asIScriptObject for this to work? Any insight is appreciated!


Solution

  • First you register Circle object.

    engine->RegisterObjectType("Circle",0, asOBJ_REF); // asOBJ_REF because you wanted a reference call
    engine->RegisterObjectBehaviour("Circle", asBEHAVE_ADDREF, "void f()", asMETHOD(Circle, AddRef), asCALL_THISCALL);
    engine->RegisterObjectBehaviour("Circle", asBEHAVE_RELEASE, "void f()", asMETHOD(Circle, ReleaseRef), asCALL_THISCALL);
    

    note the AddRef and ReleaseRef functions. these are mandatory functions to allow Angelscript to release them from memory when need. you dont need to actually implement them as in your example you want to use only a reference. just declare like this

    class Circle
    {
    public:
    
         void AddRef() { /* do nothing */ }
         void ReleaseRef() { /* do nothing */ }
    }
    

    now register object method. (your getArea() function)

    engine->RegisterObjectMethod("Circle", "int getArea()", asMETHOD(Circle, getArea), asCALL_THISCALL); // asCALL_THISCALL means we will call function using myCircle.getArea()
    

    then register global property. this is the instance you want to use in angelscript.

    engine->RegisterGlobalProperty("Circle myCircle", &CircleInstance);
    

    now in your angelscript file

     int value = myCircle.getArea(); // remember you registered myCircle as Circle reference
    
     int radius = myCircle.radius; // error. you need to register each member.
    

    i advise you to read documentation start to finish. Object handles, reference counting etc... are very important concepts you need to grasp.

    angelscript is very easy to embed, documentation helps a lot. But certainly doesn't hold your hand.

    this is a late answer, as i found this through Google. i didn't want the question to be left unanswered. some one might find my answer useful.

    img