ASBindGen (C++ To AngelScript Bindings Generator)

Hi! IMHO, AngelScript bindings writing is so boring and trivial, but I couldn’t find tool for automatic bindings generation. So I created tool for it myself. :slight_smile:

GitHub repository

https://github.com/KonstantinTomashevich/as-bind-gen

Short overview

ASBindGen is lua script (from several files). It reads project configuration from special file (example file cmake template), then parses specified headers, then writes bindings for them. It doesn’t generates AST, parsing is ruled by special command-comments.

Example header:

#pragma once
#include <Urho3D/Core/Object.h>
#include <SampleProject/SampleObject.hpp>

//@ASBindGen Class ObjectType=Ref
class SampleContainer : public Urho3D::Object
{
URHO3D_OBJECT (SampleContainer, Object)
protected:
    Urho3D::Vector <Urho3D::SharedPtr <SampleObject> > objects_;

public:
    //@ASBindGen Constructor UseUrho3DScriptContext_arg0
    SampleContainer (Urho3D::Context *context);
    virtual ~SampleContainer ();

    //@ASBindGen Function ReturnHandleArray
        Urho3D::Vector <Urho3D::SharedPtr <SampleObject> > GetObjects () const;
        //@ASBindGen Function OverrideName=get_objectsCount
        unsigned GetObjectsCount () const;
        //@ASBindGen Function AddRef_arg0
        void AddObject (SampleObject *object);
        //@ASBindGen Function AddRef_arg-1
        SampleObject *GetObjectByIndex (unsigned index) const;
        //@ASBindGen Function AddRef_arg0
        bool RemoveObject (SampleObject *object);
};

Bindings code, generated from this header:

#pragma once
#include <Urho3D/AngelScript/Script.h>
#include <Urho3D/ThirdParty/AngelScript/angelscript.h>
#include <Urho3D/AngelScript/APITemplates.h>
#include <SampleProject/SampleContainer.hpp>

namespace Bindings
{
SampleContainer * wrapper_SampleContainer_constructor ()
{
    return new SampleContainer (Urho3D::GetScriptContext ());
}

Urho3D::CScriptArray * wrapper_SampleContainer_GetObjects (SampleContainer* objectPtr)
{
    Urho3D::Vector <Urho3D::SharedPtr <SampleObject> > result = objectPtr->GetObjects ();
    return Urho3D::VectorToHandleArray <SampleObject> (result, "Array <SampleObject @>");
}

template <class T> void RegisterSampleContainer (asIScriptEngine *engine, const char *className, bool registerConstructors)
{
    Urho3D::RegisterObject <T> (engine, className);

    if (registerConstructors)
        {

            engine->RegisterObjectBehaviour (className, asBEHAVE_FACTORY, (Urho3D::String (className) + "@+ f ()").CString (), asFUNCTION (wrapper_SampleContainer_constructor), asCALL_CDECL);
        }

        engine->RegisterObjectMethod (className, "Array <SampleObject @> @ GetObjects () const", asFUNCTION (wrapper_SampleContainer_GetObjects), asCALL_CDECL_OBJFIRST);
        engine->RegisterObjectMethod (className, "uint get_objectsCount () const", asMETHOD (T, GetObjectsCount), asCALL_THISCALL);
        engine->RegisterObjectMethod (className, "void AddObject (SampleObject @+ object) ", asMETHOD (T, AddObject), asCALL_THISCALL);
        engine->RegisterObjectMethod (className, "SampleObject @+ GetObjectByIndex (uint index) const", asMETHOD (T, GetObjectByIndex), asCALL_THISCALL);
        engine->RegisterObjectMethod (className, "bool RemoveObject (SampleObject @+ object) ", asMETHOD (T, RemoveObject), asCALL_THISCALL);
}

}

Also it generates bindings hub like this:

#include <Urho3D/ThirdParty/AngelScript/angelscript.h>
#include <Urho3D/AngelScript/APITemplates.h>
#include "Bindings.hpp"
#include <SampleProject/AngelScriptBindings/SampleContainer.hpp>
#include <SampleProject/AngelScriptBindings/SampleObject.hpp>

namespace Bindings
{
void RegisterAnything (asIScriptEngine *engine)
{
    RegisterClassesForwardDeclarations (engine);
    RegisterEnums (engine);
    RegisterConstants (engine);
    RegisterFreeFunctions (engine);
    RegisterUrho3DSubsystems (engine);
    RegisterClasses (engine);
}

void RegisterClassesForwardDeclarations (asIScriptEngine *engine)
{
    engine->RegisterObjectType ("SampleContainer", 0, asOBJ_REF);
    engine->RegisterObjectType ("SampleObject", 0, asOBJ_REF);
}

void RegisterEnums (asIScriptEngine *engine)
{
}

void RegisterConstants (asIScriptEngine *engine)
{
}

void RegisterFreeFunctions (asIScriptEngine *engine)
{
}

void RegisterUrho3DSubsystems (asIScriptEngine *engine)
{
}

void RegisterClasses (asIScriptEngine *engine)
{
    RegisterSampleContainer <SampleContainer> (engine, "SampleContainer", true);
    RegisterSampleObject <SampleObject> (engine, "SampleObject", true);
}

}

Example CMake project

https://github.com/KonstantinTomashevich/as-bin-gen-sample-project

Also it perfectly works in my game:
https://github.com/KonstantinTomashevich/colonization

9 Likes

thanks for share nice asset