diff --git a/site/source/docs/api_reference/bind.h.rst b/site/source/docs/api_reference/bind.h.rst index d2bf85d43ff0a..f23bcaba693a5 100644 --- a/site/source/docs/api_reference/bind.h.rst +++ b/site/source/docs/api_reference/bind.h.rst @@ -804,11 +804,12 @@ Enums A typedef of ``EnumType`` (a typename for the class). - .. cpp:function:: enum_(const char* name) + .. cpp:function:: enum_(const char* name, enum_value_type valueType = enum_value_type::object) Constructor. :param const char* name: + :param enum_value_type valueType: The type of the enum values. This determines how the values are represented in JavaScript. If ``valueType`` is ``enum_value_type::object`` (default), the enum values are represented as an object with a ``.value`` field. If ``valueType`` is ``enum_value_type::number``, the enum values are represented as plain numbers. The default is ``enum_value_type::string``, the enum values are represented as the string names of the enum values. .. cpp:function:: enum_& value(const char* name, EnumType value) diff --git a/site/source/docs/porting/connecting_cpp_and_javascript/embind.rst b/site/source/docs/porting/connecting_cpp_and_javascript/embind.rst index b1b6e030cab38..c1a11dd4024ba 100644 --- a/site/source/docs/porting/connecting_cpp_and_javascript/embind.rst +++ b/site/source/docs/porting/connecting_cpp_and_javascript/embind.rst @@ -825,6 +825,33 @@ type. Module.OldStyle.ONE; Module.NewStyle.TWO; +You can simplify how enums are represented in JavaScript by setting the `enum_value_type` parameter when registering the enum. +The default value type is `enum_value_type::object`, which binds the enum values to objects with a `value` property. +Other options are `enum_value_type::number`, which binds the enum values to their plain integer value, and `enum_value_type::string`, which binds the enum values to the string of their name. + +.. code:: cpp + + EMSCRIPTEN_BINDINGS(my_enum_example) { + enum_("ObjectEnum", enum_value_type::object) + .value("ONE", FirstEnum::ONE) + .value("TWO", FirstEnum::TWO) + ; + enum_("NumberEnum", enum_value_type::number) + .value("ONE", SecondEnum::ONE) + .value("TWO", SecondEnum::TWO) + ; + enum_("StringEnum", enum_value_type::string) + .value("ONE", ThirdEnum::ONE) + .value("TWO", ThirdEnum::TWO) + ; + } + +.. code:: javascript + + Module.ObjectEnum.ONE.value === 1; + Module.NumberEnum.ONE === 1; + Module.StringEnum.ONE === "ONE"; + .. _embind-constants: Constants diff --git a/src/lib/libembind.js b/src/lib/libembind.js index 6d1704eacd707..3508421a1a58c 100644 --- a/src/lib/libembind.js +++ b/src/lib/libembind.js @@ -2196,24 +2196,74 @@ var LibraryEmbind = { _embind_register_enum__docs: '/** @suppress {globalThis} */', _embind_register_enum__deps: ['$exposePublicSymbol', '$enumReadValueFromPointer', - '$AsciiToString', '$registerType'], - _embind_register_enum: (rawType, name, size, isSigned) => { + '$AsciiToString', '$registerType', '$getEnumValueType'], + _embind_register_enum: (rawType, name, size, isSigned, rawValueType) => { name = AsciiToString(name); + const valueType = getEnumValueType(rawValueType); + + switch (valueType) { + case 'object': { + function ctor() {} + ctor.values = {}; + + registerType(rawType, { + name, + constructor: ctor, + valueType, + fromWireType: function(c) { + return this.constructor.values[c]; + }, + toWireType: (destructors, c) => c.value, + readValueFromPointer: enumReadValueFromPointer(name, size, isSigned), + destructorFunction: null, + }); - function ctor() {} - ctor.values = {}; + exposePublicSymbol(name, ctor); + break; + } + case 'number': { + var keysMap = {}; + + registerType(rawType, { + name: name, + policyType: 'value', + fromWireType: (c) => c, + toWireType: (destructors, c) => c, + readValueFromPointer: enumReadValueFromPointer(name, size, isSigned), + destructorFunction: null, + }); - registerType(rawType, { - name, - constructor: ctor, - fromWireType: function(c) { - return this.constructor.values[c]; - }, - toWireType: (destructors, c) => c.value, - readValueFromPointer: enumReadValueFromPointer(name, size, isSigned), - destructorFunction: null, - }); - exposePublicSymbol(name, ctor); + exposePublicSymbol(name, keysMap); + // Just exposes a simple dict. argCount is meaningless here, + delete Module[name].argCount; + break; + } + case 'string': { + var valuesMap = {}; + var reverseMap = {}; + var keysMap = {}; + + registerType(rawType, { + name: name, + valuesMap, + reverseMap, + keysMap, + valueType, + fromWireType: function(c) { + return this.reverseMap[c]; + }, + toWireType: function(destructors, c) { + return this.valuesMap[c]; + }, + readValueFromPointer: enumReadValueFromPointer(name, size, isSigned), + destructorFunction: null, + }); + + exposePublicSymbol(name, keysMap); + // Just exposes a simple dict. argCount is meaningless here, + delete Module[name].argCount; + } + } }, _embind_register_enum_value__deps: ['$createNamedFunction', '$AsciiToString', '$requireRegisteredType'], @@ -2221,14 +2271,27 @@ var LibraryEmbind = { var enumType = requireRegisteredType(rawEnumType, 'enum'); name = AsciiToString(name); - var Enum = enumType.constructor; - - var Value = Object.create(enumType.constructor.prototype, { - value: {value: enumValue}, - constructor: {value: createNamedFunction(`${enumType.name}_${name}`, function() {})}, - }); - Enum.values[enumValue] = Value; - Enum[name] = Value; + switch (enumType.valueType) { + case 'object': { + var Enum = enumType.constructor; + var Value = Object.create(enumType.constructor.prototype, { + value: {value: enumValue}, + constructor: {value: createNamedFunction(`${enumType.name}_${name}`, function() {})}, + }); + Enum.values[enumValue] = Value; + Enum[name] = Value; + break; + } + case 'number': { + enumType.keysMap[name] = enumValue; + break; + } + case 'string': { + enumType.valuesMap[name] = enumValue; + enumType.reverseMap[enumValue] = name; + enumType.keysMap[name] = name; + } + } }, _embind_register_constant__deps: ['$AsciiToString', '$whenDependentTypesAreResolved'], diff --git a/src/lib/libembind_gen.js b/src/lib/libembind_gen.js index 7651a51ada158..f91d0cf9be92b 100644 --- a/src/lib/libembind_gen.js +++ b/src/lib/libembind_gen.js @@ -279,23 +279,35 @@ var LibraryEmbind = { }, $EnumDefinition: class { hasPublicSymbol = true; - constructor(typeId, name) { + constructor(typeId, name, valueType) { this.typeId = typeId; this.name = name; this.items = []; this.destructorType = 'none'; + this.valueType = valueType; } print(nameMap, out) { - out.push(`export interface ${this.name}Value {\n`); - out.push(' value: T;\n}\n'); + if (this.valueType === 'object') { + out.push(`export interface ${this.name}Value {\n`); + out.push(' value: T;\n}\n'); + } out.push(`export type ${this.name} = `); if (this.items.length === 0) { out.push('never/* Empty Enumerator */'); } else { const outItems = []; for (const [name, value] of this.items) { - outItems.push(`${this.name}Value<${value}>`); + switch (this.valueType) { + case 'object': + outItems.push(`${this.name}Value<${value}>`); + break; + case 'string': + outItems.push(`'${name}'`); + break; + case 'number': + outItems.push(`${value}`); + } } out.push(outItems.join('|')); } @@ -306,7 +318,16 @@ var LibraryEmbind = { out.push(` ${this.name}: {`); const outItems = []; for (const [name, value] of this.items) { - outItems.push(`${name}: ${this.name}Value<${value}>`); + switch (this.valueType) { + case 'object': + outItems.push(`${name}: ${this.name}Value<${value}>`); + break; + case 'string': + outItems.push(`${name}: '${name}'`); + break; + case 'number': + outItems.push(`${name}: ${value}`); + } } out.push(outItems.join(', ')); out.push('};\n'); @@ -711,10 +732,11 @@ var LibraryEmbind = { }, // Stub function. This is called a when extending an object and not needed for TS generation. _embind_create_inheriting_constructor: (constructorName, wrapperType, properties) => {}, - _embind_register_enum__deps: ['$AsciiToString', '$EnumDefinition', '$moduleDefinitions'], - _embind_register_enum: function(rawType, name, size, isSigned) { + _embind_register_enum__deps: ['$AsciiToString', '$EnumDefinition', '$moduleDefinitions', '$getEnumValueType'], + _embind_register_enum: function(rawType, name, size, isSigned, rawValueType) { name = AsciiToString(name); - const enumDef = new EnumDefinition(rawType, name); + const valueType = getEnumValueType(rawValueType); + const enumDef = new EnumDefinition(rawType, name, valueType); registerType(rawType, enumDef); moduleDefinitions.push(enumDef); }, diff --git a/src/lib/libembind_shared.js b/src/lib/libembind_shared.js index fcc4fe1a672c4..05c117f813dba 100644 --- a/src/lib/libembind_shared.js +++ b/src/lib/libembind_shared.js @@ -183,6 +183,11 @@ var LibraryEmbindShared = { } }, + $getEnumValueType(rawValueType) { + // This must match the values of enum_value_type in wire.h + return rawValueType === 0 ? 'object' : (rawValueType === 1 ? 'number' : 'string'); + }, + $getRequiredArgCount(argTypes) { var requiredArgCount = argTypes.length - 2; for (var i = argTypes.length - 1; i >= 2; --i) { diff --git a/src/lib/libsigs.js b/src/lib/libsigs.js index 04e36d080ee3f..fc2f41623edc0 100644 --- a/src/lib/libsigs.js +++ b/src/lib/libsigs.js @@ -296,7 +296,7 @@ sigs = { _embind_register_class_property__sig: 'vpppppppppp', _embind_register_constant__sig: 'vppd', _embind_register_emval__sig: 'vp', - _embind_register_enum__sig: 'vpppi', + _embind_register_enum__sig: 'vpppii', _embind_register_enum_value__sig: 'vppi', _embind_register_float__sig: 'vppp', _embind_register_function__sig: 'vpippppii', diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 2c529071863d0..18b22ed9790d4 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -224,7 +224,8 @@ void _embind_register_enum( TYPEID enumType, const char* name, size_t size, - bool isSigned); + bool isSigned, + int policyValue); void _embind_register_smart_ptr( TYPEID pointerType, @@ -1989,13 +1990,14 @@ class enum_ { public: typedef EnumType enum_type; - enum_(const char* name) { + enum_(const char* name, enum_value_type valueType = enum_value_type::object) { using namespace internal; _embind_register_enum( internal::TypeID::get(), name, sizeof(EnumType), - std::is_signed::type>::value); + std::is_signed::type>::value, + static_cast(valueType)); } enum_& value(const char* name, EnumType value) { diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index 6bdcb6fdc117b..2093b8067bae6 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -577,6 +577,12 @@ struct reference : public allow_raw_pointers {}; } // end namespace return_value_policy +enum class enum_value_type { + object = 0, + number = 1, + string = 2 +}; + namespace internal { #if __cplusplus >= 201703L diff --git a/test/embind/embind.test.js b/test/embind/embind.test.js index 4fc2c6d0cb1cb..67ca8966a9587 100644 --- a/test/embind/embind.test.js +++ b/test/embind/embind.test.js @@ -2031,6 +2031,47 @@ module({ }); }); + BaseFixture.extend("enums with integer values", function() { + test("can compare enumeration values", function() { + assert.equal(cm.EnumNum.ONE, cm.EnumNum.ONE); + assert.equal(cm.EnumNum.ONE, 0); + assert.notEqual(cm.EnumNum.TWO, cm.EnumNum.ONE); + }); + + if (typeof INVOKED_FROM_EMSCRIPTEN_TEST_RUNNER === "undefined") { // TODO: Enable this to work in Emscripten runner as well! + test("repr includes enum value", function() { + assert.equal(0, IMVU.repr(cm.EnumNum.ONE)); + assert.equal(1, IMVU.repr(cm.EnumNum.TWO)); + }); + } + + test("can pass and return enumeration values to functions", function() { + assert.equal(cm.EnumNum.TWO, cm.emval_test_take_and_return_EnumNum(cm.EnumNum.TWO)); + assert.equal(cm.EnumNum.TWO, cm.emval_test_take_and_return_EnumNum(cm.EnumNum.TWO)); + }); + }); + + + BaseFixture.extend("enums with string values", function() { + test("can compare enumeration values", function() { + assert.equal(cm.EnumStr.ONE, cm.EnumStr.ONE); + assert.equal(cm.EnumStr.ONE, 'ONE'); + assert.notEqual(cm.EnumStr.ONE, cm.EnumStr.TWO); + }); + + if (typeof INVOKED_FROM_EMSCRIPTEN_TEST_RUNNER === "undefined") { // TODO: Enable this to work in Emscripten runner as well! + test("repr includes enum value", function() { + assert.equal('ONE', IMVU.repr(cm.EnumStr.ONE)); + assert.equal('TWO', IMVU.repr(cm.EnumStr.TWO)); + }); + } + + test("can pass and return enumeration values to functions", function() { + assert.equal(cm.EnumStr.TWO, cm.emval_test_take_and_return_EnumStr(cm.EnumStr.TWO)); + assert.equal('TWO', cm.emval_test_take_and_return_EnumStr('TWO')); + }); + }); + BaseFixture.extend("emval call tests", function() { test("can call functions from C++", function() { var called = false; diff --git a/test/embind/embind_test.cpp b/test/embind/embind_test.cpp index ace09ead6b965..7352850270d25 100644 --- a/test/embind/embind_test.cpp +++ b/test/embind/embind_test.cpp @@ -1016,6 +1016,18 @@ EnumClass emval_test_take_and_return_EnumClass(EnumClass e) { return e; } +enum class EnumNum { ONE, TWO }; + +EnumNum emval_test_take_and_return_EnumNum(EnumNum e) { + return e; +} + +enum class EnumStr { ONE, TWO }; + +EnumStr emval_test_take_and_return_EnumStr(EnumStr e) { + return e; +} + void emval_test_call_function(val v, int i, float f, TupleVector tv, StructVector sv) { v(i, f, tv, sv); } @@ -2350,6 +2362,19 @@ EMSCRIPTEN_BINDINGS(tests) { ; function("emval_test_take_and_return_EnumClass", &emval_test_take_and_return_EnumClass); + enum_("EnumNum", enum_value_type::number) + .value("ONE", EnumNum::ONE) + .value("TWO", EnumNum::TWO) + ; + function("emval_test_take_and_return_EnumNum", &emval_test_take_and_return_EnumNum); + + + enum_("EnumStr", enum_value_type::string) + .value("ONE", EnumStr::ONE) + .value("TWO", EnumStr::TWO) + ; + function("emval_test_take_and_return_EnumStr", &emval_test_take_and_return_EnumStr); + function("emval_test_call_function", &emval_test_call_function); function("emval_test_return_unique_ptr", &emval_test_return_unique_ptr); @@ -2404,7 +2429,7 @@ EMSCRIPTEN_BINDINGS(tests) { register_map("StringIntMap"); function("embind_test_get_string_int_map", embind_test_get_string_int_map); - + register_map>("IntStringMapGreater"); function("embind_test_get_int_string_greater_map", embind_test_get_int_string_greater_map); diff --git a/test/other/embind_tsgen.cpp b/test/other/embind_tsgen.cpp index d515a419e2505..3b7e93fe0e2ba 100644 --- a/test/other/embind_tsgen.cpp +++ b/test/other/embind_tsgen.cpp @@ -45,11 +45,14 @@ std::unique_ptr class_unique_ptr_returning_fn() { return std::make_unique(); } -enum Bar { kValueOne, kValueTwo, kValueThree }; - +enum FirstEnum { kValueOne, kValueTwo, kValueThree }; +enum SecondEnum { kValueA, kValueB, kValueC }; +enum ThirdEnum { kValueAlpha, kValueBeta, kValueGamma }; enum EmptyEnum {}; -Bar enum_returning_fn() { return kValueOne; } +FirstEnum enum_returning_fn() { return kValueOne; } +SecondEnum num_enum_returning_fn() { return kValueA; } +ThirdEnum str_enum_returning_fn() { return kValueAlpha; } struct ValArr { int x, y, z; @@ -58,7 +61,9 @@ struct ValArr { EMSCRIPTEN_DECLARE_VAL_TYPE(CallbackType); struct ValObj { - Bar bar; + FirstEnum firstEnum; + SecondEnum secondEnum; + ThirdEnum thirdEnum; std::string string; CallbackType callback; ValObj() : callback(val::undefined()) {} @@ -178,23 +183,33 @@ EMSCRIPTEN_BINDINGS(Test) { constant("an_int", 5); constant("a_bool", false); - constant("an_enum", Bar::kValueOne); + constant("an_enum", FirstEnum::kValueOne); constant("a_class_instance", Test()); - enum_("Bar") - .value("valueOne", Bar::kValueOne) - .value("valueTwo", Bar::kValueTwo) - .value("valueThree", Bar::kValueThree); + enum_("FirstEnum", enum_value_type::object) + .value("kValueOne", FirstEnum::kValueOne) + .value("kValueTwo", FirstEnum::kValueTwo) + .value("kValueThree", FirstEnum::kValueThree); + enum_("SecondEnum", enum_value_type::number) + .value("kValueA", SecondEnum::kValueA) + .value("kValueB", SecondEnum::kValueB) + .value("kValueC", SecondEnum::kValueC); + enum_("ThirdEnum", enum_value_type::string) + .value("kValueAlpha", ThirdEnum::kValueAlpha) + .value("kValueBeta", ThirdEnum::kValueBeta) + .value("kValueGamma", ThirdEnum::kValueGamma); enum_("EmptyEnum"); function("enum_returning_fn", &enum_returning_fn); + function("num_enum_returning_fn", &num_enum_returning_fn); + function("str_enum_returning_fn", &str_enum_returning_fn); value_array("ValArr") .element(&ValArr::x) .element(&ValArr::y) .element(&ValArr::z); - value_array>("ValArrIx") + value_array>("ValArrIx") .element(emscripten::index<0>()) .element(emscripten::index<1>()) .element(emscripten::index<2>()) @@ -202,7 +217,9 @@ EMSCRIPTEN_BINDINGS(Test) { value_object("ValObj") .field("string", &ValObj::string) - .field("bar", &ValObj::bar) + .field("firstEnum", &ValObj::firstEnum) + .field("secondEnum", &ValObj::secondEnum) + .field("thirdEnum", &ValObj::thirdEnum) .field("callback", &ValObj::callback); function("getValObj", &getValObj); function("setValObj", &setValObj); diff --git a/test/other/embind_tsgen.d.ts b/test/other/embind_tsgen.d.ts index 44f4b1b4c5653..df036128ea74f 100644 --- a/test/other/embind_tsgen.d.ts +++ b/test/other/embind_tsgen.d.ts @@ -31,17 +31,21 @@ export interface Test extends ClassHandle { export interface Obj extends ClassHandle { } -export interface BarValue { +export interface FirstEnumValue { value: T; } -export type Bar = BarValue<0>|BarValue<1>|BarValue<2>; +export type FirstEnum = FirstEnumValue<0>|FirstEnumValue<1>|FirstEnumValue<2>; + +export type SecondEnum = 0|1|2; + +export type ThirdEnum = 'kValueAlpha'|'kValueBeta'|'kValueGamma'; export interface EmptyEnumValue { value: T; } export type EmptyEnum = never/* Empty Enumerator */; -export type ValArrIx = [ Bar, Bar, Bar, Bar ]; +export type ValArrIx = [ FirstEnum, FirstEnum, FirstEnum, FirstEnum ]; export interface IntVec extends ClassHandle { push_back(_0: number): void; @@ -93,7 +97,9 @@ export type ValArr = [ number, number, number ]; export type ValObj = { string: EmbindString, - bar: Bar, + firstEnum: FirstEnum, + secondEnum: SecondEnum, + thirdEnum: ThirdEnum, callback: (message: string) => void }; @@ -111,10 +117,14 @@ interface EmbindModule { getPointer(_0: Obj | null): Obj | null; getNonnullPointer(): Obj; a_class_instance: Test; - an_enum: Bar; - Bar: {valueOne: BarValue<0>, valueTwo: BarValue<1>, valueThree: BarValue<2>}; + an_enum: FirstEnum; + FirstEnum: {kValueOne: FirstEnumValue<0>, kValueTwo: FirstEnumValue<1>, kValueThree: FirstEnumValue<2>}; + SecondEnum: {kValueA: 0, kValueB: 1, kValueC: 2}; + ThirdEnum: {kValueAlpha: 'kValueAlpha', kValueBeta: 'kValueBeta', kValueGamma: 'kValueGamma'}; EmptyEnum: {}; - enum_returning_fn(): Bar; + enum_returning_fn(): FirstEnum; + num_enum_returning_fn(): SecondEnum; + str_enum_returning_fn(): ThirdEnum; IntVec: { new(): IntVec; }; diff --git a/test/other/embind_tsgen_ignore_1.d.ts b/test/other/embind_tsgen_ignore_1.d.ts index fc3f5a1f10c4c..616014d7df95e 100644 --- a/test/other/embind_tsgen_ignore_1.d.ts +++ b/test/other/embind_tsgen_ignore_1.d.ts @@ -42,17 +42,21 @@ export interface Test extends ClassHandle { export interface Obj extends ClassHandle { } -export interface BarValue { +export interface FirstEnumValue { value: T; } -export type Bar = BarValue<0>|BarValue<1>|BarValue<2>; +export type FirstEnum = FirstEnumValue<0>|FirstEnumValue<1>|FirstEnumValue<2>; + +export type SecondEnum = 0|1|2; + +export type ThirdEnum = 'kValueAlpha'|'kValueBeta'|'kValueGamma'; export interface EmptyEnumValue { value: T; } export type EmptyEnum = never/* Empty Enumerator */; -export type ValArrIx = [ Bar, Bar, Bar, Bar ]; +export type ValArrIx = [ FirstEnum, FirstEnum, FirstEnum, FirstEnum ]; export interface IntVec extends ClassHandle { push_back(_0: number): void; @@ -104,7 +108,9 @@ export type ValArr = [ number, number, number ]; export type ValObj = { string: EmbindString, - bar: Bar, + firstEnum: FirstEnum, + secondEnum: SecondEnum, + thirdEnum: ThirdEnum, callback: (message: string) => void }; @@ -122,10 +128,14 @@ interface EmbindModule { getPointer(_0: Obj | null): Obj | null; getNonnullPointer(): Obj; a_class_instance: Test; - an_enum: Bar; - Bar: {valueOne: BarValue<0>, valueTwo: BarValue<1>, valueThree: BarValue<2>}; + an_enum: FirstEnum; + FirstEnum: {kValueOne: FirstEnumValue<0>, kValueTwo: FirstEnumValue<1>, kValueThree: FirstEnumValue<2>}; + SecondEnum: {kValueA: 0, kValueB: 1, kValueC: 2}; + ThirdEnum: {kValueAlpha: 'kValueAlpha', kValueBeta: 'kValueBeta', kValueGamma: 'kValueGamma'}; EmptyEnum: {}; - enum_returning_fn(): Bar; + enum_returning_fn(): FirstEnum; + num_enum_returning_fn(): SecondEnum; + str_enum_returning_fn(): ThirdEnum; IntVec: { new(): IntVec; }; diff --git a/test/other/embind_tsgen_ignore_2.d.ts b/test/other/embind_tsgen_ignore_2.d.ts index f37c34ab820d0..7e616f7534218 100644 --- a/test/other/embind_tsgen_ignore_2.d.ts +++ b/test/other/embind_tsgen_ignore_2.d.ts @@ -30,17 +30,21 @@ export interface Test extends ClassHandle { export interface Obj extends ClassHandle { } -export interface BarValue { +export interface FirstEnumValue { value: T; } -export type Bar = BarValue<0>|BarValue<1>|BarValue<2>; +export type FirstEnum = FirstEnumValue<0>|FirstEnumValue<1>|FirstEnumValue<2>; + +export type SecondEnum = 0|1|2; + +export type ThirdEnum = 'kValueAlpha'|'kValueBeta'|'kValueGamma'; export interface EmptyEnumValue { value: T; } export type EmptyEnum = never/* Empty Enumerator */; -export type ValArrIx = [ Bar, Bar, Bar, Bar ]; +export type ValArrIx = [ FirstEnum, FirstEnum, FirstEnum, FirstEnum ]; export interface IntVec extends ClassHandle { push_back(_0: number): void; @@ -92,7 +96,9 @@ export type ValArr = [ number, number, number ]; export type ValObj = { string: EmbindString, - bar: Bar, + firstEnum: FirstEnum, + secondEnum: SecondEnum, + thirdEnum: ThirdEnum, callback: (message: string) => void }; @@ -110,10 +116,14 @@ interface EmbindModule { getPointer(_0: Obj | null): Obj | null; getNonnullPointer(): Obj; a_class_instance: Test; - an_enum: Bar; - Bar: {valueOne: BarValue<0>, valueTwo: BarValue<1>, valueThree: BarValue<2>}; + an_enum: FirstEnum; + FirstEnum: {kValueOne: FirstEnumValue<0>, kValueTwo: FirstEnumValue<1>, kValueThree: FirstEnumValue<2>}; + SecondEnum: {kValueA: 0, kValueB: 1, kValueC: 2}; + ThirdEnum: {kValueAlpha: 'kValueAlpha', kValueBeta: 'kValueBeta', kValueGamma: 'kValueGamma'}; EmptyEnum: {}; - enum_returning_fn(): Bar; + enum_returning_fn(): FirstEnum; + num_enum_returning_fn(): SecondEnum; + str_enum_returning_fn(): ThirdEnum; IntVec: { new(): IntVec; }; diff --git a/test/other/embind_tsgen_ignore_3.d.ts b/test/other/embind_tsgen_ignore_3.d.ts index 44f4b1b4c5653..df036128ea74f 100644 --- a/test/other/embind_tsgen_ignore_3.d.ts +++ b/test/other/embind_tsgen_ignore_3.d.ts @@ -31,17 +31,21 @@ export interface Test extends ClassHandle { export interface Obj extends ClassHandle { } -export interface BarValue { +export interface FirstEnumValue { value: T; } -export type Bar = BarValue<0>|BarValue<1>|BarValue<2>; +export type FirstEnum = FirstEnumValue<0>|FirstEnumValue<1>|FirstEnumValue<2>; + +export type SecondEnum = 0|1|2; + +export type ThirdEnum = 'kValueAlpha'|'kValueBeta'|'kValueGamma'; export interface EmptyEnumValue { value: T; } export type EmptyEnum = never/* Empty Enumerator */; -export type ValArrIx = [ Bar, Bar, Bar, Bar ]; +export type ValArrIx = [ FirstEnum, FirstEnum, FirstEnum, FirstEnum ]; export interface IntVec extends ClassHandle { push_back(_0: number): void; @@ -93,7 +97,9 @@ export type ValArr = [ number, number, number ]; export type ValObj = { string: EmbindString, - bar: Bar, + firstEnum: FirstEnum, + secondEnum: SecondEnum, + thirdEnum: ThirdEnum, callback: (message: string) => void }; @@ -111,10 +117,14 @@ interface EmbindModule { getPointer(_0: Obj | null): Obj | null; getNonnullPointer(): Obj; a_class_instance: Test; - an_enum: Bar; - Bar: {valueOne: BarValue<0>, valueTwo: BarValue<1>, valueThree: BarValue<2>}; + an_enum: FirstEnum; + FirstEnum: {kValueOne: FirstEnumValue<0>, kValueTwo: FirstEnumValue<1>, kValueThree: FirstEnumValue<2>}; + SecondEnum: {kValueA: 0, kValueB: 1, kValueC: 2}; + ThirdEnum: {kValueAlpha: 'kValueAlpha', kValueBeta: 'kValueBeta', kValueGamma: 'kValueGamma'}; EmptyEnum: {}; - enum_returning_fn(): Bar; + enum_returning_fn(): FirstEnum; + num_enum_returning_fn(): SecondEnum; + str_enum_returning_fn(): ThirdEnum; IntVec: { new(): IntVec; }; diff --git a/test/other/embind_tsgen_main.ts b/test/other/embind_tsgen_main.ts index 8b4588e85643c..3efa548dcdb4d 100644 --- a/test/other/embind_tsgen_main.ts +++ b/test/other/embind_tsgen_main.ts @@ -15,12 +15,14 @@ import moduleFactory from './embind_tsgen.js'; // Test a few variations of passing value_objects with strings. module.setValObj({ bar: module.Bar.valueOne, + baz: module.Baz.valueA, string: "ABCD", callback: () => {} }); module.setValObj({ bar: module.Bar.valueOne, + baz: "valueA", string: new Int8Array([65, 66, 67, 68]), callback: () => {} }); diff --git a/test/other/embind_tsgen_module.d.ts b/test/other/embind_tsgen_module.d.ts index 40b3b804a649d..200395f4f14f1 100644 --- a/test/other/embind_tsgen_module.d.ts +++ b/test/other/embind_tsgen_module.d.ts @@ -31,17 +31,21 @@ export interface Test extends ClassHandle { export interface Obj extends ClassHandle { } -export interface BarValue { +export interface FirstEnumValue { value: T; } -export type Bar = BarValue<0>|BarValue<1>|BarValue<2>; +export type FirstEnum = FirstEnumValue<0>|FirstEnumValue<1>|FirstEnumValue<2>; + +export type SecondEnum = 0|1|2; + +export type ThirdEnum = 'kValueAlpha'|'kValueBeta'|'kValueGamma'; export interface EmptyEnumValue { value: T; } export type EmptyEnum = never/* Empty Enumerator */; -export type ValArrIx = [ Bar, Bar, Bar, Bar ]; +export type ValArrIx = [ FirstEnum, FirstEnum, FirstEnum, FirstEnum ]; export interface IntVec extends ClassHandle { push_back(_0: number): void; @@ -93,7 +97,9 @@ export type ValArr = [ number, number, number ]; export type ValObj = { string: EmbindString, - bar: Bar, + firstEnum: FirstEnum, + secondEnum: SecondEnum, + thirdEnum: ThirdEnum, callback: (message: string) => void }; @@ -111,10 +117,14 @@ interface EmbindModule { getPointer(_0: Obj | null): Obj | null; getNonnullPointer(): Obj; a_class_instance: Test; - an_enum: Bar; - Bar: {valueOne: BarValue<0>, valueTwo: BarValue<1>, valueThree: BarValue<2>}; + an_enum: FirstEnum; + FirstEnum: {kValueOne: FirstEnumValue<0>, kValueTwo: FirstEnumValue<1>, kValueThree: FirstEnumValue<2>}; + SecondEnum: {kValueA: 0, kValueB: 1, kValueC: 2}; + ThirdEnum: {kValueAlpha: 'kValueAlpha', kValueBeta: 'kValueBeta', kValueGamma: 'kValueGamma'}; EmptyEnum: {}; - enum_returning_fn(): Bar; + enum_returning_fn(): FirstEnum; + num_enum_returning_fn(): SecondEnum; + str_enum_returning_fn(): ThirdEnum; IntVec: { new(): IntVec; }; diff --git a/test/test_other.py b/test/test_other.py index 716da4e8ef081..688930e80cf0d 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -15159,6 +15159,7 @@ def test_no_input_files(self): def test_embind_negative_enum_values(self): # Test if negative enum values are printed correctly and not overflown to # large values when CAN_ADDRESS_2GB is true. + # Test both default enums and enums as string src = r''' #include #include