From 37e28d98ea1ef178e32be6acc0c5911a616ba021 Mon Sep 17 00:00:00 2001 From: Shuhei Tanuma Date: Fri, 6 Nov 2015 07:47:39 +0900 Subject: [PATCH] C# Unity can't cast integer represented enum value. ``` namespace MyGame; enum CommandType : byte { None = 0, } table Command { id:int; type:CommandType; } ``` then generate c# files. it'll output compile error like these. ``` Assets/MyGame/Command.cs(18,39): error CS1041: Identifier expected Assets/MyGame/Command.cs(18,39): error CS1737: Optional parameter cannot precede required parameters 16: public static Offset CreateCommand(FlatBufferBuilder builder, 17: int id = 0, 18: CommandType type = (CommandType)0) { ``` --- src/idl_gen_general.cpp | 27 ++++++++++++++++--- .../MyGame/Example/TestSimpleTableWithEnum.cs | 2 +- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index fdb6df795..99bd9ca72 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -409,6 +409,24 @@ static std::string GenDefaultValue(const LanguageParameters &lang, const Value & : value.constant; } +static std::string GenEnumDefaultValue(const FieldDef &field) { + auto enum_def = field.value.type.enum_def; + auto vec = enum_def->vals.vec; + auto default_value = StringToInt(field.value.constant.c_str()); + + auto result = field.value.constant; + for (auto it = vec.begin(); it != vec.end(); ++it) { + auto enum_val = **it; + if (enum_val.value == default_value) { + result = enum_def->name + "." + enum_val.name; + break; + } + } + + return result; +} + + static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def, std::string *code_ptr) { std::string &code = *code_ptr; @@ -873,14 +891,15 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, // supply all arguments, and thus won't compile when fields are added. if (lang.language != GeneratorOptions::kJava) { code += " = "; - // in C#, enum values have their own type, so we need to cast the - // numeric value to the proper type + // in C#, enum values have their own type, but Unity (specifically .Net 3.5) can't + // cast enum type from numeric value. if (lang.language == GeneratorOptions::kCSharp && field.value.type.enum_def != nullptr && field.value.type.base_type != BASE_TYPE_UNION) { - code += "(" + field.value.type.enum_def->name + ")"; + code += GenEnumDefaultValue(field); + } else { + code += GenDefaultValue(lang, field.value, false); } - code += GenDefaultValue(lang, field.value, false); } } code += ") {\n builder."; diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.cs b/tests/MyGame/Example/TestSimpleTableWithEnum.cs index 9b436ffdc..245d33001 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.cs +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.cs @@ -14,7 +14,7 @@ public sealed class TestSimpleTableWithEnum : Table { public bool MutateColor(Color color) { int o = __offset(4); if (o != 0) { bb.PutSbyte(o + bb_pos, (sbyte)color); return true; } else { return false; } } public static Offset CreateTestSimpleTableWithEnum(FlatBufferBuilder builder, - Color color = (Color)2) { + Color color = Color.Green) { builder.StartObject(1); TestSimpleTableWithEnum.AddColor(builder, color); return TestSimpleTableWithEnum.EndTestSimpleTableWithEnum(builder);