Jump to content
  • Advertisement
Sign in to follow this  
behc

enum issues

This topic is 2689 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi

I've found some potential bugs regarding enum's when enabling asEP_REQUIRE_ENUM_SCOPE:

Declaring enum with value that has same name as other script declared enum value results in: "Name conflict "xxx" is a global property.", using c++ registered enum value name is ok.

initializing global variable of script declared enum don't need scope (::) operator, and gives error instead: "'TYPE::VALUE' is not declared." Local variables and c++ registered enums are ok.

RegisterEnumValue accepts everything as 'name', even things like "@#$%".
It is also possible to register same enum value name with different enum types without asEP_REQUIRE_ENUM_SCOPE, but this results with error when using enum value without scope, so that might not be a bug.

[source lang="cpp"]

//paste at the end of TestEnum()
{
COutStream out;
engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
r = engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, 1); assert(r >= 0);

r = engine->RegisterEnum("RENUM_1"); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "R_GLOBAL", 0); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "RE1_1", 1); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "RE1_2", 2); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "@#$%", 777);
if(r < 0)
TEST_FAILED;

r = engine->RegisterEnum("RENUM_2"); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_2", "R_GLOBAL", 13); // that always works (regardless asEP_REQUIRE_ENUM_SCOPE state)
if(r < 0)
TEST_FAILED;
r = engine->RegisterEnumValue("RENUM_2", "RE2_1", 1); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_2", "RE2_2", 2); assert(r >= 0);

r = engine->RegisterGlobalFunction("void output(int val1)", asFUNCTION(scriptOutput), asCALL_CDECL); assert(r >= 0);

asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
mod->AddScriptSection("script", "enum ENUM_1 \n"
"{ \n"
" TEST_GLOBAL = 0, \n"
" E1_VAL1, \n"
" E1_VAL2, \n"
" RE1_2 \n"
"} \n"
"enum ENUM_2 \n"
"{ \n"
//error: name conflict " TEST_GLOBAL = 0, \n"
" E2_VAL1, \n"
" E2_VAL2 \n"
"} \n"
//that doesn't work -> "ENUM_1 g_e1 = ENUM_1::E1_VAL1; \n"
"ENUM_1 g_e1 = E1_VAL1; \n" // <- that shouldn't (?)
"RENUM_1 rg_e1 = RENUM_1::RE1_2; \n" // <- that's ok
" \n"
"void main() \n"
"{ \n"
" ENUM_1 l_e1 = ENUM_1::E1_VAL1; \n"
" g_e1 = ENUM_1::E1_VAL1; \n"
" rg_e1 = RENUM_1::R_GLOBAL; \n"
" RENUM_2 rl_e2 = RENUM_2::R_GLOBAL; \n"
" output(rg_e1); \n"
" output(rl_e2); \n"
"} \n"
);

r = mod->Build();
if( r < 0 )
TEST_FAILED;

buffer = "";
r = ExecuteString(engine, "main();", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
if( buffer != "0\n13\n" )
TEST_FAILED;

engine->Release();
}
[/source]

Share this post


Link to post
Share on other sites
Advertisement
I've fixed the problems you reported in revision 854. Thanks for preparing the test case that made it so easy to find and fix the bugs.

Share this post


Link to post
Share on other sites
[font=arial, verdana, tahoma, sans-serif][size=2]Thanks for quick fix.

I also found that TestExecute fails in release mode (it is unrelated to enums). ctx->SetUserData is never called as assert are discarded in release mode, and without user data, cleanContext is not called, reporting everything as failure (while this is expected behavior). You may want to rewrite this like:[/font]
[source lang="cpp"]

void* prevUserData;
asIScriptContext *ctx = engine->CreateContext();
prevUserData = ctx->SetUserData((void*)(size_t)0xDEADF00D); assert(prevUserData == 0);
prevUserData = ctx->GetUserData(); assert(prevUserData == (void*)(size_t)0xDEADF00D);
prevUserData = ctx->SetUserData(0); assert(prevUserData == (void*)(size_t)0xDEADF00D);
prevUserData = ctx->SetUserData((void*)(size_t)0xDEADF00D); assert(prevUserData == 0);
engine->SetContextUserDataCleanupCallback(cleanContext);
called = false;
ctx->Release();
if( !called )
TEST_FAILED;
[/source]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!