#include #include #include #include #include using namespace emscripten; class Test { public: int function_one(char x, int y) { return 42; } int function_two(unsigned char x, int y) { return 43; } int function_three(const std::string&) { return 1; } int function_four(bool x) { return 2; } long long_fn(unsigned long a) { return 3; } int const_fn() const { return 0; } int getX() const { return x; } void setX(int x_) { x = x_; } int getY() const { return y; } std::string string_property; static int static_function(int x) { return 1; } static int static_property; static std::string static_string_property; private: int x; int y; }; class Foo { public: void process(const Test& input) {} }; class IterableClass { public: IterableClass() : data{1, 2, 3} {} unsigned int count() const { return 3; } int at(unsigned int index) const { return data[index]; } private: int data[3]; }; Test class_returning_fn() { return Test(); } std::unique_ptr class_unique_ptr_returning_fn() { return std::make_unique(); } enum FirstEnum { kValueOne, kValueTwo, kValueThree }; enum SecondEnum { kValueA, kValueB, kValueC }; enum ThirdEnum { kValueAlpha, kValueBeta, kValueGamma }; enum EmptyEnum {}; 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; }; EMSCRIPTEN_DECLARE_VAL_TYPE(CallbackType); struct ValObj { FirstEnum firstEnum; SecondEnum secondEnum; ThirdEnum thirdEnum; std::string string; CallbackType callback; std::optional optionalInt; ValObj() : callback(val::undefined()) {} }; EMSCRIPTEN_DECLARE_VAL_TYPE(AliasedVal); ValObj getValObj() { ValObj o; return o; } void setValObj(ValObj v) {} class ClassWithConstructor { public: ClassWithConstructor(int, const ValArr&) {} int fn(int x) { return 0; } }; class ClassWithTwoConstructors { public: ClassWithTwoConstructors() {} ClassWithTwoConstructors(int) {} }; class ClassWithSmartPtrConstructor { public: ClassWithSmartPtrConstructor(int, const ValArr&) {} int fn(int x) { return 0; } }; int smart_ptr_function(std::shared_ptr) { return 0; } struct Obj {}; Obj* get_pointer(Obj* ptr) { return ptr; } Obj* get_nonnull_pointer() { return new Obj(); } int function_with_callback_param(CallbackType ct) { ct(val("hello")); return 0; } void function_consuming_aliased_val(AliasedVal) { } int global_fn(int, int) { return 0; } std::string string_test(std::string arg) { return "hi"; } std::wstring wstring_test(std::wstring arg) { return L"hi"; } std::optional optional_string_test(std::string arg) { return "hi"; } std::optional optional_test(std::optional arg) { return {}; } std::optional optional_and_nonoptional_test(std::optional arg1, int arg2) { return {}; } class BaseClass { public: virtual ~BaseClass() = default; virtual int fn(int x) { return 0; } }; class DerivedClass : public BaseClass { public: int fn(int x) override { return 1; } int fn2(int x) { return 2; } }; struct Interface { virtual void invoke(const std::string& str) = 0; virtual ~Interface() {} }; struct InterfaceWrapper : public wrapper { EMSCRIPTEN_WRAPPER(InterfaceWrapper); void invoke(const std::string& str) { return call("invoke", str); } }; EMSCRIPTEN_BINDINGS(Test) { class_("Test") .function("functionOne", &Test::function_one) .function("functionTwo", &Test::function_two) .function("functionThree", &Test::function_three) .function("functionFour", &Test::function_four) .function("functionFive(x, y)", &Test::function_one) .function("functionSix(str)", &Test::function_three) .function("longFn", &Test::long_fn) .function("constFn", &Test::const_fn) .property("x", &Test::getX, &Test::setX) .property("y", &Test::getY) .property("stringProperty", &Test::string_property) .class_function("staticFunction", &Test::static_function) .class_function("staticFunctionWithParam(x)", &Test::static_function) .class_property("staticProperty", &Test::static_property) .class_property("staticStringProperty", &Test::static_string_property) ; function("class_returning_fn", &class_returning_fn); function("class_unique_ptr_returning_fn", &class_unique_ptr_returning_fn); class_("Obj"); function("getPointer", &get_pointer, allow_raw_pointers()); function("getNonnullPointer", &get_nonnull_pointer, allow_raw_pointers(), nonnull()); constant("an_int", 5); constant("a_bool", false); constant("an_enum", FirstEnum::kValueOne); constant("a_class_instance", Test()); 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") .element(emscripten::index<0>()) .element(emscripten::index<1>()) .element(emscripten::index<2>()) .element(emscripten::index<3>()); value_object("ValObj") .field("string", &ValObj::string) .field("firstEnum", &ValObj::firstEnum) .field("secondEnum", &ValObj::secondEnum) .field("thirdEnum", &ValObj::thirdEnum) .field("optionalInt", &ValObj::optionalInt) .field("callback", &ValObj::callback); function("getValObj", &getValObj); function("setValObj", &setValObj); register_vector("IntVec"); class_("IterableClass") .constructor<>() .function("count", &IterableClass::count) .function("at", &IterableClass::at) .iterable("count", "at"); register_map("MapIntInt"); class_("Foo").function("process", &Foo::process); function("global_fn", &global_fn); register_optional(); register_optional(); register_optional(); function("optional_test", &optional_test); function("optional_and_nonoptional_test", &optional_and_nonoptional_test); function("string_test", &string_test); function("wstring_test", &wstring_test); function("optional_string_test", &optional_string_test); class_("ClassWithConstructor") .constructor() .function("fn", &ClassWithConstructor::fn); // The last defined constructor should be used in the definition. class_("ClassWithTwoConstructors") .constructor<>() .constructor(); class_("ClassWithSmartPtrConstructor") .smart_ptr_constructor( "ClassWithSmartPtrConstructor", &std::make_shared) .function("fn", &ClassWithSmartPtrConstructor::fn); function("smart_ptr_function", &smart_ptr_function); function("smart_ptr_function_with_params(foo)", &smart_ptr_function); function("function_with_callback_param", &function_with_callback_param); function("function_consuming_aliased_val", &function_consuming_aliased_val); register_type("(message: string) => void"); register_type("AliasedVal", "number"); class_("BaseClass").function("fn", &BaseClass::fn); class_>("DerivedClass") .function("fn2", &DerivedClass::fn2); class_("Interface") .function("invoke", &Interface::invoke, pure_virtual()) .allow_subclass("InterfaceWrapper") ; } int Test::static_property = 42; std::string Test::static_string_property = ""; int main() { // Main should not be run during TypeScript generation, but should run when // the program is run normally. printf("main ran\n"); return 0; }