Advertisement

Problem with handles and [] operators

Started by March 04, 2010 10:09 AM
4 comments, last by andrew1b 14 years, 8 months ago
Why doesn't it work on AngelScript:

EntityArray array;
// ... filling the array etc.
@array[n] = DeleteEntity(array[n]);

But this one does:

EntityArray array; // an array of Entity handles
// ... filling the array etc.
Entity @temp = array[n];
@array[n] = DeleteEntity(temp);

I get these error messages:
AngelScript ERROR (line: 76):
No default constructor for object of type 'Entity'.

AngelScript ERROR (line: 76):
There is no copy operator for this type available.
Entity is a reference counted reference object and everything works fine when I create a temporary handle. EntityArray is a std::vector wrapper with overloaded index operators. The only time the array doesn't work is when I pass any element as a function parameter.

r = pASEngine->RegisterObjectBehaviour("EntityArray",
asBEHAVE_INDEX, "Entity@ &f(const uint)",
asMETHODPR(EntityArray, operator[], (const unsigned int), Entity* &),
asCALL_THISCALL); assert( r >= 0 );

r = pASEngine->RegisterObjectBehaviour("EntityArray",
asBEHAVE_INDEX, "const Entity@ &f(const uint) const",
asMETHODPR(EntityArray, operator[], (const unsigned int) const, const Entity* &),
asCALL_THISCALL); assert( r >= 0 );

...
The AngelScript compiler is attempting to make a copy of the Entity object, which fails because the Entity object doesn't have a default factory.

This looks like a bug, as the compiler shouldn't have to make this copy, because the object is reference counted. I will look into this.

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

Advertisement
I can't reproduce this.

How is the DeleteEntity function registered? Is it Entity @DeleteEntity(Entity @)?

Also, could you give revision 566 a try? It may be that recent changes have fixed this problem.

Here's the code I wrote to try to reproduce the problem:

		asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);		engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);		bout.buffer = "";		engine->RegisterObjectType("Entity", 0, asOBJ_REF);		engine->RegisterObjectBehaviour("Entity", asBEHAVE_ADDREF, "void f()", asFUNCTION(0), asCALL_GENERIC);		engine->RegisterObjectBehaviour("Entity", asBEHAVE_RELEASE, "void f()", asFUNCTION(0), asCALL_GENERIC);				engine->RegisterObjectType("EntityArray", 0, asOBJ_REF);		engine->RegisterObjectBehaviour("EntityArray", asBEHAVE_FACTORY, "EntityArray @f()", asFUNCTION(0), asCALL_GENERIC);		engine->RegisterObjectBehaviour("EntityArray", asBEHAVE_ADDREF, "void f()", asFUNCTION(0), asCALL_GENERIC);		engine->RegisterObjectBehaviour("EntityArray", asBEHAVE_RELEASE, "void f()", asFUNCTION(0), asCALL_GENERIC);		engine->RegisterObjectBehaviour("EntityArray", asBEHAVE_INDEX, "Entity@ &f(const uint)", asFUNCTION(0), asCALL_GENERIC);		engine->RegisterGlobalFunction("Entity @DeleteEntity(Entity @)", asFUNCTION(0), asCALL_GENERIC);		const char *script = 			"void func() { \n"			"EntityArray array; \n"			"@array[0] = DeleteEntity(array[0]); \n"			"}; \n";		asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);		mod->AddScriptSection("script", script);		r = mod->Build();		if( r < 0 )			fail = true;		if( bout.buffer != "" )		{			printf(bout.buffer.c_str());			fail = true;		}		if( r != asEXECUTION_FINISHED )			fail = true;		engine->Release();


Observe, that as I'm not going to execute the script all functions are registered as null pointers.

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

Actually I was using (Entity ∈) for that. Now that I changed it to (Entity @) it works fine.
Just for curiosity, is there any difference between them when it comes to ADDREF? I mean, does Entity@ automatically calls the ADDREF function and Entity ∈ not?
...
With ∈ angelscript must make a local copy of the object to make sure the original object isn't modified by the called function. It doesn't call addref since the object will already be in local variable, which makes it safe.

However, this changes things a bit. I understand now that the bug is actually that angelscript didn't try to copy the object when the handle was first assigned to a local variable. Both of the original scripts should have failed.

I'll investigate this some more.

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

Sorry, now I realized that I was using const Entity∈, which is quite wrong, since the entity was supposed to be deleted, I shouldn't do that... it was probably a lack of attention. It didn't work with Entity∈ (non const). So I don't think it was an AngelScript bug.
Now it's working fine with Entity@.
...

This topic is closed to new replies.

Advertisement