Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem with handles and [] operators

Started by andrew1b Mar 4, 2010 at 10:09 AM 4 replies 1.6k views
Original Post
andrew1b
andrew1b
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 );

...
WitchLord
WitchLord
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 - <a href="http://www.angelcode.com/tower" rel
WitchLord
WitchLord
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 - <a href="http://www.angelcode.com/tower" rel
andrew1b
andrew1b
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?
...
WitchLord
WitchLord
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 - <a href="http://www.angelcode.com/tower" rel
andrew1b
andrew1b
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@.
...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.