Advertisement

[BUG] Problem with dictionary addon/implicit casts

Started by January 26, 2014 10:44 PM
13 comments, last by WitchLord 10 years, 10 months ago

The ?&in is always the last option. It's the one listed as 'variable argument type';

If you want to keep the implicit casts in the string class, your other option is to implement a get/set pair in the dictionary that takes the string type as value (similar to the existing overloads for int64 and double).

There is no reason for the the argument not being 'const ?&in', it's just something that was missed. :)

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

The ?&in is always the last option. It's the one listed as 'variable argument type';

If you want to keep the implicit casts in the string class, your other option is to implement a get/set pair in the dictionary that takes the string type as value (similar to the existing overloads for int64 and double).

There is no reason for the the argument not being 'const ?&in', it's just something that was missed. smile.png

Iiirc I did try implementing a get/set pair for the dictionary class but that didn't help.. AS still opted for the implicit cast overload (const string & vs const string &@ perhaps?).

Advertisement

Using your patch as a base I've now added a test case like this:

{
  engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
  engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
 
  RegisterScriptString(engine);
  RegisterScriptArray(engine, false);
  RegisterScriptDictionary(engine);
  r = engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); assert( r >= 0 );
 
  // Register additional behaviour to the CScriptString to allow it to be implicitly converted to/from double
  struct helper
  {
    static CScriptString *objectString_FactoryFromDouble(double v) 
    { 
      CScriptString *str = new CScriptString(); 
      stringstream s; 
      s << v; 
      str->buffer = s.str(); 
      return str; 
    }
    static double objectString_CastToDouble(CScriptString *str) 
    { 
      stringstream s(str->buffer); 
      double v; 
      s >> v; 
      return v; 
    }
  };
  r = engine->RegisterObjectBehaviour( "string", asBEHAVE_FACTORY, "string @f(double)", asFUNCTION( helper::objectString_FactoryFromDouble ), asCALL_CDECL ); assert( r >= 0 );
  r = engine->RegisterObjectBehaviour( "string", asBEHAVE_IMPLICIT_VALUE_CAST, "double f() const", asFUNCTION( helper::objectString_CastToDouble ), asCALL_CDECL_OBJLAST ); assert( r >= 0 );
 
  const char *str = 
    "string gs;                      \n"
    "void Test()                     \n"
    "{                               \n"
    "  dictionary dict;              \n"
    "  dict.set('a', '3.14');        \n" // calls dict.set(string, double &in) since the string has an implicit cast to double
    "  string c;                     \n"
    "  dict.get('a', c);             \n" // calls dict.get(string, double &out) since the string has implicit factory from double
    "  assert(c == double('3.14'));  \n"
    "  dict.get('a', gs);            \n" // calls dict.get(string, double &out) since the string has implicit factory from double
    "  assert(gs == double('3.14')); \n"
    "}                               \n";
 
  mod = engine->GetModule("test", asGM_ALWAYS_CREATE);
  mod->AddScriptSection("test", str);
  r = mod->Build();
  if( r < 0 )
    TEST_FAILED;
 
  r = ExecuteString(engine, "Test()", mod);
  if( r != asEXECUTION_FINISHED )
    TEST_FAILED;
 
  engine->Release();
}

This reproduces the situation you're facing, and has allowed me to confirm that the compiler is working as it should in this case.

I've also confirmed that by registering the new get/set overloads as follows will work. The compiler will correctly chose these new overloads before the others.

r = engine->RegisterObjectMethod("dictionary", "void set(const string &in, const string &in)", asMETHODPR(...), asCALL_THISCALL);
r = engine->RegisterObjectMethod("dictionary", "void get(const string &in, string &out)", asMETHODPR(...), asCALL_THISCALL);

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

Hm, ok, sorry for wasting your time on this then :) At least you got some new test cases out of this :) Thanks!

No problem at all. After all, you could hardly have known that this wasn't a bug since it had always worked like what you had seen before. :)

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