🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

TypeId inconsistency with variable parameter type

Started by
0 comments, last by WitchLord 9 years, 7 months ago

If I register a global function with a variable parameter type:


string classname(const ?&in)

When my C++ function gets called,


std::string MyClassname(void *ref, int typeId)
{
    asIScriptContext* ctx = asGetActiveContext();
    if ( ctx )
        return ctx->GetEngine()->GetTypeDeclaration(typeId, true);

    return "";
}

the typeId appears to have asTYPEID_OBJHANDLE already stripped. That is, even though the documentation says, "if the expression is an object handle then the reference will refer to the handle, not the actual object" the typeId appears to be for the object, not the handle.

An example:


class Foo {}
Foo foo;
Foo@ h = @foo;

void main()
{
    print(classname(h)); // prints Foo
}

When I extended MyClassname to work with dictionary values (so that it prints the underlying type instead of "dictionaryValue", I got a different behavior:


std::string ClassnameGetString(void *ref, int typeId)
{
    asIScriptContext* ctx = asGetActiveContext();
    if ( ctx )
    {
        const int dictionaryValueTypeId = ctx->GetEngine()->GetTypeIdByDecl("dictionaryValue");
        if ( dictionaryValueTypeId != asINVALID_TYPE && dictionaryValueTypeId == typeId )
        {
            CScriptDictValue* pScriptDictValue = reinterpret_cast<CScriptDictValue*>(ref);
            return ctx->GetEngine()->GetTypeDeclaration(pScriptDictValue->GetTypeId(), true);
        }
        else
            return ctx->GetEngine()->GetTypeDeclaration(typeId, true);
    }

    return "";
}

dictionary d;
@d['h'] = h;
print(classname(d['h'])); // prints Foo@

I had to manually strip the objhandle bit(s) in order for the standalone h and the h stored in the dictionary to be 'equal':


std::string ClassnameGetString(void *ref, int typeId)
{
    asIScriptContext* ctx = asGetActiveContext();
    if ( ctx )
    {
        const int dictionaryValueTypeId = ctx->GetEngine()->GetTypeIdByDecl("dictionaryValue");
        if ( dictionaryValueTypeId != asINVALID_TYPE && dictionaryValueTypeId == typeId )
        {
            CScriptDictValue* pScriptDictValue = reinterpret_cast<CScriptDictValue*>(ref);

            int dictValueActualTypeId = pScriptDictValue->GetTypeId();
            dictValueActualTypeId &= ~asTYPEID_OBJHANDLE;

            return ctx->GetEngine()->GetTypeDeclaration(dictValueActualTypeId, true);
        }
        else
            return ctx->GetEngine()->GetTypeDeclaration(typeId, true);
    }

    return "";
}

Is this expected behavior? Thank you.

Advertisement

It is expected. In your sample, you didn't call the function with handle, instead you called with a reference to the object. To get the handle in this case you need to explicitly prefix the expression with @

class Foo {}
Foo foo;
Foo@ h = @foo;

void main()
{
  print(classname(@h)); // will give the type id of the handle to Foo
}

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

This topic is closed to new replies.

Advertisement