Sign in to follow this  
sorressean

binding functions that take/return std::list/std::vector

Recommended Posts

sorressean    103

hello all:

I'm setting up scripting, which I will use to add content to my mud. I am running into an issue however: how does one bind a function that either takes or receives std::list or std::vector? Any information here would be really appreciated. I have a method that looks something like:

std::list<Entity*>* Entity::GetContents() { ... }

and am trying to bind it.

Thanks,

Share this post


Link to post
Share on other sites
WitchLord    4677

To register these methods directly with AngelScript you would first have to register the std::list/vector with the engine for the type you'll return/receive.

 

stdvector.h from the svn shows the basics of registering the std::vector type with AngelScript.

 

 

However, I do not recommend that you register the std::list/vector directly with AngelScript. They are not well suited for the automatic memory management, and you would likely end up with performance bottlenecks due to the memory in the containers being copied whenever the container is being passed around in the script.

 

Instead I recommend you write a wrapper around your application functions that take/receive std::list/vectors to transform the container into a type that is better suited for automatic memory management (i.e. with refcounting). In most cases the CScriptArray add-on type is good enough, and is the recommended starting point.

 

 

Regards,

Andreas

Share this post


Link to post
Share on other sites
iraxef    451

Here's a helper function I use to get a script array from an application-registered type which returns an std::vector:

engine->RegisterObjectMethod("MyScene", "array<MySprite@>@ FindSprites(const string& in) const", asFUNCTION(FindSprites), asCALL_CDECL_OBJLAST);

CScriptArray* FindSprites(const std::string& name, MyScene* scene)
{
    std::vector<MySprite*> sprites = scene->FindSprites(name);

    asIObjectType* objectType = MyWrapper_GetEngineObjectTypeFromDecl("array<MySprite@>");

    CScriptArray* scriptArray = CScriptArray::Create(objectType, sprites.size());

    for (uint i = 0; i < sprites.size(); ++i)
    {
        void* ptr = sprites[i];
        scriptArray->SetValue(i, &ptr);
    }

    return scriptArray; // don't delete array because script will now have a refcount of 1 to it, and will take care of the memory from here
}

And here's one which lets you give a script array, yet pass that to an application-registered type which expects a vector:

engine->RegisterObjectMethod("MySprite", "void SetOffsets(const array<MyVec2> &in)",  asFUNCTION(SetOffsets), asCALL_CDECL_OBJLAST);

void SetOffsets(CScriptArray& offsets, MySprite* sprite)
{
    const uint arraySize = offsets.GetSize();

    std::vector<MyVec2> offsets(arraySize);

    for (uint arrayIdx = 0; arrayIdx < arraySize; ++arrayIdx)
    {
        const MyVec2* pos = static_cast<const MyVec2*>(offsets.At(arrayIdx));

        offsets[arrayIdx].Set( *pos );
    }

    sprite->SetOffsets(offsets);
}

Edited by iraxef

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this