Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions site/source/docs/porting/connecting_cpp_and_javascript/embind.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,13 @@ produce `val` types. To give better type information, custom `val` types can be
registered using :cpp:func:`EMSCRIPTEN_DECLARE_VAL_TYPE` in combination with
:cpp:class:`emscripten::register_type`. An example below:

Two registration forms are supported:

* Single parameter: ``register_type<T>(definition)`` — the provided string is inlined
everywhere the type appears.
* Two parameters: ``register_type<T>(name, definition)`` — creates a named TypeScript
type alias (``type name = definition;``) and uses ``name`` at call sites.

.. code:: cpp

EMSCRIPTEN_DECLARE_VAL_TYPE(CallbackType);
Expand All @@ -1226,6 +1233,9 @@ registered using :cpp:func:`EMSCRIPTEN_DECLARE_VAL_TYPE` in combination with
EMSCRIPTEN_BINDINGS(custom_val) {
function("function_with_callback_param", &function_with_callback_param);
register_type<CallbackType>("(message: string) => void");

// Named alias form (emits: type Callback = (message: string) => void;)
// register_type<CallbackType>("Callback", "(message: string) => void");
}


Expand Down
5 changes: 5 additions & 0 deletions src/lib/libembind.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,11 @@ var LibraryEmbind = {
__embind_register_emval(rawType);
},

_embind_register_user_type_definition__deps: ['_embind_register_emval'],
_embind_register_user_type_definition: (rawType, name, definition) => {
__embind_register_emval(rawType);
},

_embind_register_optional__deps: ['$registerType', '$EmValOptionalType'],
_embind_register_optional: (rawOptionalType, rawType) => {
registerType(rawOptionalType, EmValOptionalType);
Expand Down
20 changes: 20 additions & 0 deletions src/lib/libembind_gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ var LibraryEmbind = {
this.destructorType = 'none'; // Same as emval.
}
},
$UserTypeDefinition: class {
constructor(typeId, name, definition) {
this.typeId = typeId;
this.name = name;
this.definition = definition;
this.destructorType = 'none'; // Same as emval.
}

print(nameMap, out) {
out.push(`type ${this.name} = ${this.definition};\n\n`);
}
},
$OptionalType: class {
constructor(type) {
this.type = type;
Expand Down Expand Up @@ -563,6 +575,14 @@ var LibraryEmbind = {
name = AsciiToString(name);
registerType(rawType, new UserType(rawType, name));
},
_embind_register_user_type_definition__deps: ['$registerType', '$AsciiToString', '$UserTypeDefinition'],
_embind_register_user_type_definition: (rawType, name, definition) => {
name = AsciiToString(name);
definition = AsciiToString(definition);
const userTypeDef = new UserTypeDefinition(rawType, name, definition);
registerType(rawType, userTypeDef);
moduleDefinitions.push(userTypeDef);
},
_embind_register_optional__deps: ['$OptionalType'],
_embind_register_optional: (rawOptionalType, rawType) => {
whenDependentTypesAreResolved([rawOptionalType], [rawType], function(type) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/libsigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ sigs = {
_embind_register_std_string__sig: 'vpp',
_embind_register_std_wstring__sig: 'vppp',
_embind_register_user_type__sig: 'vpp',
_embind_register_user_type_definition__sig: 'vppp',
_embind_register_value_array__sig: 'vpppppp',
_embind_register_value_array_element__sig: 'vppppppppp',
_embind_register_value_object__sig: 'vpppppp',
Expand Down
11 changes: 11 additions & 0 deletions system/include/emscripten/bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ void _embind_register_user_type(
TYPEID type,
const char* typeName);

void _embind_register_user_type_definition(
TYPEID type,
const char* typeName,
const char* typeDefinition);

// Register an InitFunc in the global linked list of init functions.
void _embind_register_bindings(struct InitFunc* f);

Expand Down Expand Up @@ -2223,6 +2228,12 @@ inline void register_type(const char* name) {
_embind_register_user_type(TypeID<T>::get(), name);
}

template <typename T>
inline void register_type(const char* name, const char* definition) {
using namespace internal;
_embind_register_user_type_definition(TypeID<T>::get(), name, definition);
}

// EMSCRIPTEN_BINDINGS creates a static struct to initialize the binding which
// will get included in the program if the translation unit in which it is
// defined gets linked into the program. Using a C++ constructor here ensures it
Expand Down
10 changes: 10 additions & 0 deletions test/other/embind_tsgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ struct ValObj {
ValObj() : callback(val::undefined()) {}
};

EMSCRIPTEN_DECLARE_VAL_TYPE(AliasedVal);


ValObj getValObj() {
ValObj o;
return o;
Expand Down Expand Up @@ -104,6 +107,9 @@ int function_with_callback_param(CallbackType ct) {
return 0;
}

void function_consuming_aliased_val(AliasedVal) {
}

int global_fn(int, int) { return 0; }

std::string string_test(std::string arg) {
Expand Down Expand Up @@ -240,7 +246,11 @@ EMSCRIPTEN_BINDINGS(Test) {
function("function_with_callback_param",
&function_with_callback_param);

function("function_consuming_aliased_val",
&function_consuming_aliased_val);

register_type<CallbackType>("(message: string) => void");
register_type<AliasedVal>("AliasedVal", "number");

class_<BaseClass>("BaseClass").function("fn", &BaseClass::fn);

Expand Down
3 changes: 3 additions & 0 deletions test/other/embind_tsgen.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

type AliasedVal = number;

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand Down Expand Up @@ -139,6 +141,7 @@ interface EmbindModule {
extend(_0: EmbindString, _1: any): any;
};
InterfaceWrapper: {};
function_consuming_aliased_val(_0: AliasedVal): void;
a_bool: boolean;
an_int: number;
optional_test(_0?: Foo): number | undefined;
Expand Down
3 changes: 3 additions & 0 deletions test/other/embind_tsgen_ignore_1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

type AliasedVal = number;

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand Down Expand Up @@ -150,6 +152,7 @@ interface EmbindModule {
extend(_0: EmbindString, _1: any): any;
};
InterfaceWrapper: {};
function_consuming_aliased_val(_0: AliasedVal): void;
a_bool: boolean;
an_int: number;
optional_test(_0?: Foo): number | undefined;
Expand Down
3 changes: 3 additions & 0 deletions test/other/embind_tsgen_ignore_2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

type AliasedVal = number;

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand Down Expand Up @@ -138,6 +140,7 @@ interface EmbindModule {
extend(_0: EmbindString, _1: any): any;
};
InterfaceWrapper: {};
function_consuming_aliased_val(_0: AliasedVal): void;
a_bool: boolean;
an_int: number;
optional_test(_0?: Foo): number | undefined;
Expand Down
3 changes: 3 additions & 0 deletions test/other/embind_tsgen_ignore_3.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

type AliasedVal = number;

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand Down Expand Up @@ -139,6 +141,7 @@ interface EmbindModule {
extend(_0: EmbindString, _1: any): any;
};
InterfaceWrapper: {};
function_consuming_aliased_val(_0: AliasedVal): void;
a_bool: boolean;
an_int: number;
optional_test(_0?: Foo): number | undefined;
Expand Down
3 changes: 3 additions & 0 deletions test/other/embind_tsgen_module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

type AliasedVal = number;

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand Down Expand Up @@ -139,6 +141,7 @@ interface EmbindModule {
extend(_0: EmbindString, _1: any): any;
};
InterfaceWrapper: {};
function_consuming_aliased_val(_0: AliasedVal): void;
a_bool: boolean;
an_int: number;
optional_test(_0?: Foo): number | undefined;
Expand Down