Advertisement

[SOLVED] Casting between const handles broken?

Started by October 23, 2015 11:21 AM
1 comment, last by Prinsessa 9 years, 1 month ago
Hello!

I updated to the latest version of AS for my project (thank you soooo much for the lambdas — they made my day!). It's been some time. But almost everything still worked. One thing I needed to change was how base types and child types are casted between each other, because the syntax for registering that was changed a little. But the new example could be found at the same place in the doc as the old one, and the difference wasn't big, so it was done in a jiffy.
BUT.
Now I can't cast const handles. cast<Emitter @>(getSomeVarOfTypeComponent()) works fine, but cast<const Emitter @>(getSomeConstVarOfTypeComponent()) does not, giving me the following error:
No conversion from 'const Component@&' to 'const Emitter@' available.
The & sign is because the component is being returned from a function, and that's exactly how I'm retrieving the non-const one as well, and either way both worked before I updated AS.
I was thinking maybe now I need to register const conversion individually, but AS actually has an assert telling me I can't register more than one cast for the same type, const or not, and in the comment above the assert, there's a todo saying that maybe more should be allowed in the future to allow different behaviour for const conversion than for non-const conversion.
But surely that must mean that const conversion is automatically covered by the non-const cast I registered, and not that the latest version of AS suddenly cannot cast between const handles at all, like some sort of todo? That would be a step backwards from something that actually worked before and would break existing AS code.
So why is this happening? sad.png Could it actually be a bug?

Both types, parent Component and child Emitter, are C++ classes that have been registered in AS as asOBJ_REF | asOBJ_NOCOUNT. I've registered Emitter @opCast() in the parent class and Component @opImplCast() in the child class, using a direct copy of the refCast() function from the docs (sans the ->addref() of course).

I have changed absolutely nothing from before I updated, neither in AS code or C++ code, besides the registration of casting, and the AS code that performs this cast did, again, work before the update with the old registration of casting, and does still, again, work if the handles are not const.

As ref cast behaviours are now treated (almost) as ordinary class methods it is necessary to register both the non-const and the const overload of the opCast method, like this:

// Register the non-const opCast version
r = engine->RegisterObjectMethod("A", "B@ opCast()", asFUNCTION((refCast<A,B>)), asCALL_CDECL_OBJLAST); assert( r >= 0 );
 
// Register the const opCast version
r = engine->RegisterObjectMethod("A", "const B@ opCast() const", asFUNCTION((refCast<A,B>)), asCALL_CDECL_OBJLAST); assert( r >= 0 );

Let me know if that still doesn't work for you. If so I'll need to investigate it to look for possible bugs.

I'll make a clarification in the manual about this.

Regards,

Andreas

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

Well, now I'm embarrassed. I tried exactly that, with a const handle returned, but I forgot to mark the method itself as const. And I'm an avid producer of const-correct code!

Sheesh. Thanks a lot! Works like a charm now.

But yeah, probably good to mention in the docs since that's different from when you used to do RegisterObjectBehaviour().

This topic is closed to new replies.

Advertisement