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.
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