Sign in to follow this  
andrew1b

Problem with handles and [] operators

Recommended Posts

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 );

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Actually I was using (Entity &in) 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 &in not?

Share this post


Link to post
Share on other sites
With &in 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.

Share this post


Link to post
Share on other sites
Sorry, now I realized that I was using const Entity&in, 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&in (non const). So I don't think it was an AngelScript bug.
Now it's working fine with Entity@.

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