Advertisement

How do I register an Angelscript function that passes an array of array of doubles?

Started by October 17, 2024 05:21 PM
1 comment, last by WitchLord 1 month, 1 week ago

Hi All,

I'm a software dev and I'm working on a project that interfaces a C++ program with Angelscript for running custom functions. As a result I need parse between Angelscript's Array of Array of Doubles and a C++ STL library vector of vector of doubles (and ints).

Angelscript:

array<array<double>> dblMat = {{ data } { data }};

C++ STL object

std::vector < std::vector < double > >dblMat = {{data } { data }};

The program uses CScriptArray to get vectors of data in and out between the two, and it successfully handles not-nested vectors for input and output, and we're able to get a matrix OUTPUT from C++ STL to AngelScript, but we haven't gotten it from STl to Angelscript.

We have a method called FillSTLVector that takes a CScriptArray and an STL vector pointer as an input and transfers the data between the two as follows:

template < class T >
void ScriptMgrSingleton::FillSTLVector( CScriptArray* in, vector < T > & out )
{
    out.resize( in->GetSize() );
    for ( int i = 0 ; i < ( int )in->GetSize() ; i++ )
    {
        out[i] = * ( T* ) ( in->At( i ) );
    }
}

And I've been trying to implement one for matrices, with the assumption that the CScriptArray has a vector of CScriptArrays inside of it:

template < class T >
void ScriptMgrSingleton::FillSTLMatrix( CScriptArray* in, vector < vector < T > > & out )
{
    out.resize( in->GetSize() );
    for ( int i = 0 ; i < ( int )in->GetSize() ; i++ )
    {
        CScriptArray* row = ( CScriptArray* ) ( in->At( i ) );


        if ( row )
        {
            FillSTLVector( row, out[i] );
        }
    }
}

When attempting to run this code, I get an error in the FillSTLVector called by FillSTLMatrix; the first attempt to get the size of its CScriptArray fails as it's somehow an incompatible type. I understand the casting to CScriptArray might be a broad assumption in FillSTLMatrix but it should work as passing the CScriptArrays I know are nested should work out.

Does anyone know what to do about this?

Thanks everyone in advance!

This works for me:

template < class T >
void FillSTLVector(CScriptArray* in, std::vector < T >& out)
{
	out.resize(in->GetSize());
	for (int i = 0; i < (int)in->GetSize(); i++)
	{
		out[i] = *(T*)(in->At(i));
	}
}

template < class T >
void FillSTLMatrix(CScriptArray* in, std::vector < std::vector < T > >& out)
{
	out.resize(in->GetSize());
	for (int i = 0; i < (int)in->GetSize(); i++)
	{
		CScriptArray* row = (CScriptArray*)(in->At(i));
		if (row)
		{
			FillSTLVector(row, out[i]);
		}
	}
}

std::vector < std::vector < double >> mtx;
void TakeArrayOfArray(CScriptArray* in)
{
	FillSTLMatrix(in, mtx);
}

bool Test()
{
	...
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);
		bout.buffer = "";

		RegisterScriptArray(engine, true);
		engine->RegisterGlobalFunction("void TakeArrayOfArray(array<array<double>> &)", asFUNCTION(TakeArrayOfArray), asCALL_CDECL);

		r = ExecuteString(engine, "array<array<double>> arr = {{1,2},{3,4}}; TakeArrayOfArray(arr);");
		if (r != asEXECUTION_FINISHED)
			TEST_FAILED;

		if (mtx[0][0] != 1 || mtx[0][1] != 2 || mtx[1][0] != 3 || mtx[1][1] != 4)
			TEST_FAILED;

		if (bout.buffer != "")
		{
			PRINTF("%s", bout.buffer.c_str());
			TEST_FAILED;
		}

		engine->ShutDownAndRelease();
	}
	...
}

I don't see any relevant difference in your code though. Check if there is a difference in the way the method was registered,

Or, perhaps you're using an old version of angelscript that may have some bugs. If you think it might be a bug in angelscript, try the latest WIP version which has the most up to date code.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement