From 5fd1b290008695a6384f18c55d839caca48ccd6b Mon Sep 17 00:00:00 2001 From: Philipp Frericks <54364015+frericp@users.noreply.github.com> Date: Fri, 14 May 2021 11:12:10 +0200 Subject: [PATCH] JS Bindings: Enhance binding macros to support different kinds of functions (#1198) --- .../JsMaterialXCore/JsDocument.cpp | 22 +- source/JsMaterialX/helpers.h | 410 +++++++++++------- 2 files changed, 257 insertions(+), 175 deletions(-) diff --git a/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp b/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp index b1dac9ac83..8ef7c5dd8c 100644 --- a/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp +++ b/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp @@ -25,29 +25,29 @@ extern "C" int size = referenced.size(); return arrayToVec((std::string *)&referenced, size); })) - BIND_FUNC("addNodeGraph", mx::Document, addNodeGraph, 0, 1, stRef) + BIND_MEMBER_FUNC("addNodeGraph", mx::Document, addNodeGraph, 0, 1, stRef) .function("getNodeGraph", &mx::Document::getNodeGraph) .function("getNodeGraphs", &mx::Document::getNodeGraphs) .function("removeNodeGraph", &mx::Document::removeNodeGraph) .function("getMatchingPorts", &mx::Document::getMatchingPorts) - BIND_FUNC("addGeomInfo", mx::Document, addGeomInfo, 0, 2, stRef, stRef) + BIND_MEMBER_FUNC("addGeomInfo", mx::Document, addGeomInfo, 0, 2, stRef, stRef) .function("getGeomInfo", &mx::Document::getGeomInfo) .function("getGeomInfos", &mx::Document::getGeomInfos) .function("removeGeomInfo", &mx::Document::removeGeomInfo) - BIND_FUNC("getGeomPropValue", mx::Document, getGeomPropValue, 1, 2, stRef, stRef) + BIND_MEMBER_FUNC("getGeomPropValue", mx::Document, getGeomPropValue, 1, 2, stRef, stRef) .function("addGeomPropDef", &mx::Document::addGeomPropDef) .function("getGeomPropDef", &mx::Document::getGeomPropDef) .function("getGeomPropDefs", &mx::Document::getGeomPropDefs) .function("removeGeomPropDef", &mx::Document::removeGeomPropDef) - BIND_FUNC("addLook", mx::Document, addLook, 0, 1, stRef) + BIND_MEMBER_FUNC("addLook", mx::Document, addLook, 0, 1, stRef) .function("getLook", &mx::Document::getLook) .function("getLooks", &mx::Document::getLooks) .function("removeLook", &mx::Document::removeLook) - BIND_FUNC("addLookGroup", mx::Document, addLookGroup, 0, 1, stRef) + BIND_MEMBER_FUNC("addLookGroup", mx::Document, addLookGroup, 0, 1, stRef) .function("getLookGroup", &mx::Document::getLookGroup) .function("getLookGroups", &mx::Document::getLookGroups) .function("removeLookGroup", &mx::Document::removeLookGroup) - BIND_FUNC("addCollection", mx::Document, addCollection, 0, 1, stRef) + BIND_MEMBER_FUNC("addCollection", mx::Document, addCollection, 0, 1, stRef) .function("getCollection", &mx::Document::getCollection) .function("getCollections", &mx::Document::getCollections) .function("removeCollection", &mx::Document::removeCollection) @@ -55,23 +55,23 @@ extern "C" .function("getTypeDef", &mx::Document::getTypeDef) .function("getTypeDefs", &mx::Document::getTypeDefs) .function("removeTypeDef", &mx::Document::removeTypeDef) - BIND_FUNC("addNodeDef", mx::Document, addNodeDef, 0, 3, stRef, stRef, stRef) - BIND_FUNC("addNodeDefFromGraph", mx::Document, addNodeDefFromGraph, 7, 8, const mx::NodeGraphPtr, + BIND_MEMBER_FUNC("addNodeDef", mx::Document, addNodeDef, 0, 3, stRef, stRef, stRef) + BIND_MEMBER_FUNC("addNodeDefFromGraph", mx::Document, addNodeDefFromGraph, 7, 8, const mx::NodeGraphPtr, stRef, stRef, stRef, bool, stRef, std::string, stRef) .function("getNodeDef", &mx::Document::getNodeDef) .function("getNodeDefs", &mx::Document::getNodeDefs) .function("removeNodeDef", &mx::Document::removeNodeDef) .function("getMatchingNodeDefs", &mx::Document::getMatchingNodeDefs) .function("getMatchingImplementations", &mx::Document::getMatchingImplementations) - BIND_FUNC("addPropertySet", mx::Document, addPropertySet, 0, 1, stRef) + BIND_MEMBER_FUNC("addPropertySet", mx::Document, addPropertySet, 0, 1, stRef) .function("getPropertySet", &mx::Document::getPropertySet) .function("getPropertySets", &mx::Document::getPropertySets) .function("removePropertySet", &mx::Document::removePropertySet) - BIND_FUNC("addVariantSet", mx::Document, addVariantSet, 0, 1, stRef) + BIND_MEMBER_FUNC("addVariantSet", mx::Document, addVariantSet, 0, 1, stRef) .function("getVariantSet", &mx::Document::getVariantSet) .function("getVariantSets", &mx::Document::getVariantSets) .function("removeVariantSet", &mx::Document::removeVariantSet) - BIND_FUNC("addImplementation", mx::Document, addImplementation, 0, 1, stRef) + BIND_MEMBER_FUNC("addImplementation", mx::Document, addImplementation, 0, 1, stRef) .function("getImplementation", &mx::Document::getImplementation) .function("getImplementations", &mx::Document::getImplementations) .function("removeImplementation", &mx::Document::removeImplementation) diff --git a/source/JsMaterialX/helpers.h b/source/JsMaterialX/helpers.h index 276b5b0282..d7f56709b1 100644 --- a/source/JsMaterialX/helpers.h +++ b/source/JsMaterialX/helpers.h @@ -13,8 +13,42 @@ std::vector arrayToVec(myClass *arr, int size) // Binding helpers +#define UNPACK(...) __VA_ARGS__ + /** * Use this macro to conveniently create bindings for class member functions with optional parameters. + * If this is the last member on a class binding, finalize the invocation with a semicolon, e.g. BIND_MEMBER_FUNC(...); + * NOTE: The macro expects the MaterialX scope to be available as 'mx', and the emscripten scope as 'ems'! + * @param JSNAME The name of the function in JavaScript, as a double-quoted string (e.g. "addNodeGraph"). + * @param CLASSNAME The name (and scope) of the class that the member functions belongs to (e.g. mx::Document). + * @param FUNCNAME The name of the function to bind (e.g. addNodeGraph). + * @param MINARGS The minimal number of parameters that need to provided when calling the function (a.k.a # of required parameters). + * @param MAXARGS The total number of parameters that the function takes, including optional ones. + * @param ... The types of all parameters, as a comma-separated list (e.g. const std::string&, float, bool) + */ +#define BIND_MEMBER_FUNC(JSNAME, CLASSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ +BIND_ ##MINARGS ## _ ##MAXARGS(.function, JSNAME, CLASSNAME &self, (,), self., FUNCNAME, ( ), , __VA_ARGS__) + +/** + * Use this macro to conveniently create bindings for class member functions with optional parameters, + * where some of the parameters are raw pointers. + * If this is the last member on a class binding, finalize the invocation with a semicolon, e.g. BIND_MEMBER_FUNC_RAW_PTR(...); + * NOTE: The macro expects the MaterialX scope to be available as 'mx', and the emscripten scope as 'ems'! + * @param JSNAME The name of the function in JavaScript, as a double-quoted string (e.g. "addNodeGraph"). + * @param CLASSNAME The name (and scope) of the class that the member functions belongs to (e.g. mx::Document). + * @param FUNCNAME The name of the function to bind (e.g. addNodeGraph). + * @param MINARGS The minimal number of parameters that need to provided when calling the function (a.k.a # of required parameters). + * @param MAXARGS The total number of parameters that the function takes, including optional ones. + * @param ... The types of all parameters, as a comma-separated list (e.g. const std::string&, float, bool) + */ +#define BIND_MEMBER_FUNC_RAW_PTR(JSNAME, CLASSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ +BIND_ ##MINARGS ## _ ##MAXARGS(.function, JSNAME, CLASSNAME &self, (,), self., FUNCNAME, (, ems::allow_raw_pointers()), , __VA_ARGS__) + + +/** + * Use this macro to conveniently create bindings for static class functions with optional parameters. + * If this is the last member on a class binding, finalize the invocation with a semicolon, e.g. BIND_CLASS_FUNC(...); + * NOTE: The macro expects the MaterialX scope to be available as 'mx', and the emscripten scope as 'ems'! * @param JSNAME The name of the function in JavaScript, as a double-quoted string (e.g. "addNodeGraph"). * @param CLASSNAME The name (and scope) of the class that the member functions belongs to (e.g. mx::Document). * @param FUNCNAME The name of the function to bind (e.g. addNodeGraph). @@ -22,247 +56,295 @@ std::vector arrayToVec(myClass *arr, int size) * @param MAXARGS The total number of parameters that the function takes, including optional ones. * @param ... The types of all parameters, as a comma-separated list (e.g. const std::string&, float, bool) */ -#define BIND_FUNC(JSNAME, CLASSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ -BIND_FUNC_ ##MINARGS ## _ ##MAXARGS(JSNAME, CLASSNAME, FUNCNAME, __VA_ARGS__) +#define BIND_CLASS_FUNC(JSNAME, CLASSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ +BIND_ ##MINARGS ## _ ##MAXARGS(.class_function, JSNAME, , ( ), CLASSNAME ::, FUNCNAME, ( ), , __VA_ARGS__) + +/** + * Use this macro to conveniently create bindings for static class functions with optional parameters, + * where some of the parameters are raw pointers. + * If this is the last member on a class binding, finalize the invocation with a semicolon, e.g. BIND_CLASS_FUNC_RAW_PTR(...); + * NOTE: The macro expects the MaterialX scope to be available as 'mx', and the emscripten scope as 'ems'! + * @param JSNAME The name of the function in JavaScript, as a double-quoted string (e.g. "addNodeGraph"). + * @param CLASSNAME The name (and scope) of the class that the member functions belongs to (e.g. mx::Document). + * @param FUNCNAME The name of the function to bind (e.g. addNodeGraph). + * @param MINARGS The minimal number of parameters that need to provided when calling the function (a.k.a # of required parameters). + * @param MAXARGS The total number of parameters that the function takes, including optional ones. + * @param ... The types of all parameters, as a comma-separated list (e.g. const std::string&, float, bool) + */ +#define BIND_CLASS_FUNC_RAW_PTR(JSNAME, CLASSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ +BIND_ ##MINARGS ## _ ##MAXARGS(.class_function, JSNAME, , ( ), CLASSNAME ::, FUNCNAME, (, ems::allow_raw_pointers()), , __VA_ARGS__) + + +/** + * Use this macro to conveniently create bindings for global (utility) functions with optional parameters. + * Do not finalize the invocation with a semicolon, e.g. simply use it as BIND_FUNC(...) + * NOTE: The macro expects the MaterialX scope to be available as 'mx', and the emscripten scope as 'ems'! + * @param JSNAME The name of the function in JavaScript, as a double-quoted string (e.g. "createDocument"). + * @param FUNCNAME The name of the function to bind (e.g. createDocument). + * @param MINARGS The minimal number of parameters that need to provided when calling the function (a.k.a # of required parameters). + * @param MAXARGS The total number of parameters that the function takes, including optional ones. + * @param ... The types of all parameters, as a comma-separated list (e.g. const std::string&, float, bool) + */ +#define BIND_FUNC(JSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ +BIND_ ##MINARGS ## _ ##MAXARGS(ems::function, JSNAME, , ( ), mx::, FUNCNAME, ( ), ;, __VA_ARGS__) + +/** + * Use this macro to conveniently create bindings for global (utility) functions with optional parameters, + * where some of the parameters are raw pointers. + * Do not finalize the invocation with a semicolon, e.g. simply use it as BIND_FUNC_RAW_PTR(...). + * NOTE: The macro expects the MaterialX scope to be available as 'mx', and the emscripten scope as 'ems'! + * @param JSNAME The name of the function in JavaScript, as a double-quoted string (e.g. "createDocument"). + * @param FUNCNAME The name of the function to bind (e.g. createDocument). + * @param MINARGS The minimal number of parameters that need to provided when calling the function (a.k.a # of required parameters). + * @param MAXARGS The total number of parameters that the function takes, including optional ones. + * @param ... The types of all parameters, as a comma-separated list (e.g. const std::string&, float, bool) + */ +#define BIND_FUNC_RAW_PTR(JSNAME, FUNCNAME, MINARGS, MAXARGS, ...) \ +BIND_ ##MINARGS ## _ ##MAXARGS(ems::function, JSNAME, , ( ), mx::, FUNCNAME, (, ems::allow_raw_pointers()), ;, __VA_ARGS__) + -#define BIND_FUNC_8(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, TYPE6, TYPE7, TYPE8, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_8(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, \ + TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, TYPE6, TYPE7, TYPE8, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2, TYPE3 p3, TYPE4 p4, TYPE5 p5, TYPE6 p6, TYPE7 p7, TYPE8 p8) { \ - return self.FUNCNAME(p1, p2, p3, p4, p5, p6, p7, p8); \ -})) + return SCOPE FUNCNAME(p1, p2, p3, p4, p5, p6, p7, p8); \ +})UNPACK OPTIONS)SEMICOLON // 9 Macros for MAXARGS = 8 -#define BIND_FUNC_8_8(...) \ -BIND_FUNC_8(__VA_ARGS__) +#define BIND_8_8(...) \ +BIND_8(__VA_ARGS__) -#define BIND_FUNC_7_8(...) \ -BIND_FUNC_8_8(__VA_ARGS__) \ -BIND_FUNC_7(__VA_ARGS__) +#define BIND_7_8(...) \ +BIND_8_8(__VA_ARGS__) \ +BIND_7(__VA_ARGS__) -#define BIND_FUNC_6_8(...) \ -BIND_FUNC_7_8(__VA_ARGS__) \ -BIND_FUNC_6(__VA_ARGS__) +#define BIND_6_8(...) \ +BIND_7_8(__VA_ARGS__) \ +BIND_6(__VA_ARGS__) -#define BIND_FUNC_5_8(...) \ -BIND_FUNC_6_8(__VA_ARGS__) \ -BIND_FUNC_5(__VA_ARGS__) +#define BIND_5_8(...) \ +BIND_6_8(__VA_ARGS__) \ +BIND_5(__VA_ARGS__) -#define BIND_FUNC_4_8(...) \ -BIND_FUNC_5_8(__VA_ARGS__) \ -BIND_FUNC_4(__VA_ARGS__) +#define BIND_4_8(...) \ +BIND_5_8(__VA_ARGS__) \ +BIND_4(__VA_ARGS__) -#define BIND_FUNC_3_8(...) \ -BIND_FUNC_4_8(__VA_ARGS__) \ -BIND_FUNC_3(__VA_ARGS__) +#define BIND_3_8(...) \ +BIND_4_8(__VA_ARGS__) \ +BIND_3(__VA_ARGS__) -#define BIND_FUNC_2_8(...) \ -BIND_FUNC_3_8(__VA_ARGS__) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_8(...) \ +BIND_3_8(__VA_ARGS__) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_8(...) \ -BIND_FUNC_2_8(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_8(...) \ +BIND_2_8(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_8(...) \ -BIND_FUNC_1_8(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_8(...) \ +BIND_1_8(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_7(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, TYPE6, TYPE7, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_7(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, \ + TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, TYPE6, TYPE7, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2, TYPE3 p3, TYPE4 p4, TYPE5 p5, TYPE6 p6, TYPE7 p7) { \ - return self.FUNCNAME(p1, p2, p3, p4, p5, p6, p7); \ -})) + return SCOPE FUNCNAME(p1, p2, p3, p4, p5, p6, p7); \ +}) UNPACK OPTIONS)SEMICOLON // 8 Macros for MAXARGS = 7 -#define BIND_FUNC_7_7(...) \ -BIND_FUNC_7(__VA_ARGS__) +#define BIND_7_7(...) \ +BIND_7(__VA_ARGS__) -#define BIND_FUNC_6_7(...) \ -BIND_FUNC_7_7(__VA_ARGS__) \ -BIND_FUNC_6(__VA_ARGS__) +#define BIND_6_7(...) \ +BIND_7_7(__VA_ARGS__) \ +BIND_6(__VA_ARGS__) -#define BIND_FUNC_5_7(...) \ -BIND_FUNC_6_7(__VA_ARGS__) \ -BIND_FUNC_5(__VA_ARGS__) +#define BIND_5_7(...) \ +BIND_6_7(__VA_ARGS__) \ +BIND_5(__VA_ARGS__) -#define BIND_FUNC_4_7(...) \ -BIND_FUNC_5_7(__VA_ARGS__) \ -BIND_FUNC_4(__VA_ARGS__) +#define BIND_4_7(...) \ +BIND_5_7(__VA_ARGS__) \ +BIND_4(__VA_ARGS__) -#define BIND_FUNC_3_7(...) \ -BIND_FUNC_4_7(__VA_ARGS__) \ -BIND_FUNC_3(__VA_ARGS__) +#define BIND_3_7(...) \ +BIND_4_7(__VA_ARGS__) \ +BIND_3(__VA_ARGS__) -#define BIND_FUNC_2_7(...) \ -BIND_FUNC_3_7(__VA_ARGS__) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_7(...) \ +BIND_3_7(__VA_ARGS__) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_7(...) \ -BIND_FUNC_2_7(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_7(...) \ +BIND_2_7(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_7(...) \ -BIND_FUNC_1_7(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_7(...) \ +BIND_1_7(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_6(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, TYPE6, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_6(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, \ + TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, TYPE6, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2, TYPE3 p3, TYPE4 p4, TYPE5 p5, TYPE6 p6) { \ - return self.FUNCNAME(p1, p2, p3, p4, p5, p6); \ -})) + return SCOPE FUNCNAME(p1, p2, p3, p4, p5, p6); \ +}) UNPACK OPTIONS)SEMICOLON // 7 Macros for MAXARGS = 6 -#define BIND_FUNC_6_6(...) \ -BIND_FUNC_6(__VA_ARGS__) +#define BIND_6_6(...) \ +BIND_6(__VA_ARGS__) -#define BIND_FUNC_5_6(...) \ -BIND_FUNC_6_6(__VA_ARGS__) \ -BIND_FUNC_5(__VA_ARGS__) +#define BIND_5_6(...) \ +BIND_6_6(__VA_ARGS__) \ +BIND_5(__VA_ARGS__) -#define BIND_FUNC_4_6(...) \ -BIND_FUNC_5_6(__VA_ARGS__) \ -BIND_FUNC_4(__VA_ARGS__) +#define BIND_4_6(...) \ +BIND_5_6(__VA_ARGS__) \ +BIND_4(__VA_ARGS__) -#define BIND_FUNC_3_6(...) \ -BIND_FUNC_4_6(__VA_ARGS__) \ -BIND_FUNC_3(__VA_ARGS__) +#define BIND_3_6(...) \ +BIND_4_6(__VA_ARGS__) \ +BIND_3(__VA_ARGS__) -#define BIND_FUNC_2_6(...) \ -BIND_FUNC_3_6(__VA_ARGS__) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_6(...) \ +BIND_3_6(__VA_ARGS__) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_6(...) \ -BIND_FUNC_2_6(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_6(...) \ +BIND_2_6(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_6(...) \ -BIND_FUNC_1_6(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_6(...) \ +BIND_1_6(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_5(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_5(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, TYPE1, TYPE2, TYPE3, TYPE4, TYPE5, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2, TYPE3 p3, TYPE4 p4, TYPE5 p5) { \ - return self.FUNCNAME(p1, p2, p3, p4, p5); \ -})) + return SCOPE FUNCNAME(p1, p2, p3, p4, p5); \ +}) UNPACK OPTIONS)SEMICOLON // 6 Macros for MAXARGS = 5 -#define BIND_FUNC_5_5(...) \ -BIND_FUNC_5(__VA_ARGS__) +#define BIND_5_5(...) \ +BIND_5(__VA_ARGS__) -#define BIND_FUNC_4_5(...) \ -BIND_FUNC_5_5(__VA_ARGS__) \ -BIND_FUNC_4(__VA_ARGS__) +#define BIND_4_5(...) \ +BIND_5_5(__VA_ARGS__) \ +BIND_4(__VA_ARGS__) -#define BIND_FUNC_3_5(...) \ -BIND_FUNC_4_5(__VA_ARGS__) \ -BIND_FUNC_3(__VA_ARGS__) +#define BIND_3_5(...) \ +BIND_4_5(__VA_ARGS__) \ +BIND_3(__VA_ARGS__) -#define BIND_FUNC_2_5(...) \ -BIND_FUNC_3_5(__VA_ARGS__) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_5(...) \ +BIND_3_5(__VA_ARGS__) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_5(...) \ -BIND_FUNC_2_5(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_5(...) \ +BIND_2_5(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_5(...) \ -BIND_FUNC_1_5(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_5(...) \ +BIND_1_5(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_4(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, TYPE3, TYPE4, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_4(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, TYPE1, TYPE2, TYPE3, TYPE4, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2, TYPE3 p3, TYPE4 p4) { \ - return self.FUNCNAME(p1, p2, p3, p4); \ -})) + return SCOPE FUNCNAME(p1, p2, p3, p4); \ +}) UNPACK OPTIONS)SEMICOLON // 5 Macros for MAXARGS = 4 -#define BIND_FUNC_4_4(...) \ -BIND_FUNC_4(__VA_ARGS__) +#define BIND_4_4(...) \ +BIND_4(__VA_ARGS__) -#define BIND_FUNC_3_4(...) \ -BIND_FUNC_4_4(__VA_ARGS__) \ -BIND_FUNC_3(__VA_ARGS__) +#define BIND_3_4(...) \ +BIND_4_4(__VA_ARGS__) \ +BIND_3(__VA_ARGS__) -#define BIND_FUNC_2_4(...) \ -BIND_FUNC_3_4(__VA_ARGS__) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_4(...) \ +BIND_3_4(__VA_ARGS__) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_4(...) \ -BIND_FUNC_2_4(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_4(...) \ +BIND_2_4(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_4(...) \ -BIND_FUNC_1_4(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_4(...) \ +BIND_1_4(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_3(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, TYPE3, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_3(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, TYPE1, TYPE2, TYPE3, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2, TYPE3 p3) { \ - return self.FUNCNAME(p1, p2, p3); \ -})) + return SCOPE FUNCNAME(p1, p2, p3); \ +}) UNPACK OPTIONS)SEMICOLON // 4 Macros for MAXARGS = 3 -#define BIND_FUNC_3_3(...) \ -BIND_FUNC_3(__VA_ARGS__) +#define BIND_3_3(...) \ +BIND_3(__VA_ARGS__) -#define BIND_FUNC_2_3(...) \ -BIND_FUNC_3_3(__VA_ARGS__) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_3(...) \ +BIND_3_3(__VA_ARGS__) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_3(...) \ -BIND_FUNC_2_3(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_3(...) \ +BIND_2_3(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_3(...) \ -BIND_FUNC_1_3(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_3(...) \ +BIND_1_3(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_2(JSNAME, CLASSNAME, FUNCNAME, TYPE1, TYPE2, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, \ +#define BIND_2(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, TYPE1, TYPE2, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ TYPE1 p1, TYPE2 p2) { \ - return self.FUNCNAME(p1, p2); \ -})) + return SCOPE FUNCNAME(p1, p2); \ +}) UNPACK OPTIONS)SEMICOLON // 3 Macros for MAXARGS = 2 -#define BIND_FUNC_2_2(...) \ -BIND_FUNC_2(__VA_ARGS__) +#define BIND_2_2(...) \ +BIND_2(__VA_ARGS__) -#define BIND_FUNC_1_2(...) \ -BIND_FUNC_2_2(__VA_ARGS__) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_2(...) \ +BIND_2_2(__VA_ARGS__) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_2(...) \ -BIND_FUNC_1_2(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_2(...) \ +BIND_1_2(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_1(JSNAME, CLASSNAME, FUNCNAME, TYPE1, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self, TYPE1 p1) { \ - return self.FUNCNAME(p1); \ -})) +#define BIND_1(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, TYPE1, ...) \ +API(JSNAME, ems::optional_override([](SELF UNPACK SEP \ + TYPE1 p1) { \ + return SCOPE FUNCNAME(p1); \ +}) UNPACK OPTIONS)SEMICOLON // 2 Macros for MAXARGS = 1 -#define BIND_FUNC_1_1(...) \ -BIND_FUNC_1(__VA_ARGS__) +#define BIND_1_1(...) \ +BIND_1(__VA_ARGS__) -#define BIND_FUNC_0_1(...) \ -BIND_FUNC_1_1(__VA_ARGS__) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_1(...) \ +BIND_1_1(__VA_ARGS__) \ +BIND_0(__VA_ARGS__) -#define BIND_FUNC_0(JSNAME, CLASSNAME, FUNCNAME, ...) \ -.function(JSNAME, ems::optional_override([](CLASSNAME &self) { \ - return self.FUNCNAME(); \ -})) +#define BIND_0(API, JSNAME, SELF, SEP, SCOPE, FUNCNAME, OPTIONS, SEMICOLON, ...) \ +API(JSNAME, ems::optional_override([](SELF) { \ + return SCOPE FUNCNAME(); \ +}) UNPACK OPTIONS)SEMICOLON // 1 Macros for MAXARGS = 0 -#define BIND_FUNC_0_0(...) \ -BIND_FUNC_0(__VA_ARGS__) +#define BIND_0_0(...) \ +BIND_0(__VA_ARGS__) #endif // JSMATERIALX_HELPERS_H \ No newline at end of file