From aa91280bf2914df90d2fda67052fd3a22d81df29 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 20 Nov 2017 15:55:19 +0100 Subject: [PATCH 01/83] Create new cli project with CMakeLists.txt --- source/tools/CMakeLists.txt | 2 + source/tools/glkernel-cli/CMakeLists.txt | 133 +++++++++++++++++++++++ source/tools/glkernel-cli/main.cpp | 5 + 3 files changed, 140 insertions(+) create mode 100644 source/tools/glkernel-cli/CMakeLists.txt create mode 100644 source/tools/glkernel-cli/main.cpp diff --git a/source/tools/CMakeLists.txt b/source/tools/CMakeLists.txt index 980b177..c0cfb70 100644 --- a/source/tools/CMakeLists.txt +++ b/source/tools/CMakeLists.txt @@ -6,3 +6,5 @@ endif() # Example applications add_subdirectory(glkernel-cmd) + +add_subdirectory(glkernel-cli) diff --git a/source/tools/glkernel-cli/CMakeLists.txt b/source/tools/glkernel-cli/CMakeLists.txt new file mode 100644 index 0000000..4c8c56d --- /dev/null +++ b/source/tools/glkernel-cli/CMakeLists.txt @@ -0,0 +1,133 @@ + +# +# External dependencies +# + +find_package(cppassist REQUIRED) + +# +# Executable name and options +# + +# Target name +set(target glkernel-cli) + + +# +# Sources +# + +set(headers + ) + +set(sources + main.cpp + ) + +set(header_group "Header Files (API)") +set(source_group "Source Files") +source_group_by_path(${CMAKE_CURRENT_SOURCE_DIR} "\\\\.h$" + ${header_group} ${headers}) +source_group_by_path(${CMAKE_CURRENT_SOURCE_DIR} "\\\\.cpp$" + ${source_group} ${sources}) + + +# +# Create executable +# + +# Build executable +add_executable(${target} + ${sources} + ${headers} + ) + + +# Create namespaced alias +add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) + + +# +# Project options +# + +set_target_properties(${target} + PROPERTIES + ${DEFAULT_PROJECT_OPTIONS} + FOLDER "${IDE_FOLDER}" + ) + + +# +# Include directories +# + +target_include_directories(${target} + PRIVATE + ${DEFAULT_INCLUDE_DIRECTORIES} + ${CMAKE_CURRENT_BINARY_DIR} + ${PROJECT_BINARY_DIR}/source/include + ) + + +# +# Libraries +# + +target_link_libraries(${target} + PRIVATE + ${DEFAULT_LIBRARIES} + cppassist::cppassist + ${META_PROJECT_NAME}::glkernel + ) + + +# +# Compile definitions +# + +target_compile_definitions(${target} + PRIVATE + GLM_FORCE_RADIANS + ${DEFAULT_COMPILE_DEFINITIONS} + ) + + +# +# Compile options +# + +target_compile_options(${target} + PRIVATE + ${DEFAULT_COMPILE_OPTIONS} + ) + + +# +# Linker options +# + +target_link_libraries(${target} + PRIVATE + ${DEFAULT_LINKER_OPTIONS} + ) + +# +# Target Health +# + +perform_health_checks( + ${target} + ${sources} +) + + +# +# Deployment +# + +# Executable +install(TARGETS ${target} + RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT tools + BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT tools + ) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp new file mode 100644 index 0000000..aafca78 --- /dev/null +++ b/source/tools/glkernel-cli/main.cpp @@ -0,0 +1,5 @@ + +int main(int argc, char* argv[]) +{ + +} \ No newline at end of file From e3b339141e1a171fd49d4f7e9c54b6db97a17034 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 20 Nov 2017 17:19:18 +0100 Subject: [PATCH 02/83] Add basic command line flag handling using cppassist/cmdline --- source/tools/glkernel-cli/main.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index aafca78..b506b80 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -1,5 +1,28 @@ +#include +#include + +#include + int main(int argc, char* argv[]) { + cppassist::ArgumentParser argParser; + argParser.parse(argc, argv); + + auto inFileName = argParser.value("--input"); + auto outFileName = argParser.value("--output"); + + auto outFileType = outFileName.substr(outFileName.find_last_of('.') + 1); + + auto fromGeneratedKernel = argParser.isSet("-k"); + + if (fromGeneratedKernel) + { + std::cout << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName << "\" (type: " << outFileType << ")" < Date: Mon, 27 Nov 2017 16:57:57 +0100 Subject: [PATCH 03/83] Fix indentation in main.cpp --- source/tools/glkernel-cli/main.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index b506b80..21f467b 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -6,23 +6,23 @@ int main(int argc, char* argv[]) { - cppassist::ArgumentParser argParser; - argParser.parse(argc, argv); + cppassist::ArgumentParser argParser; + argParser.parse(argc, argv); - auto inFileName = argParser.value("--input"); - auto outFileName = argParser.value("--output"); + auto inFileName = argParser.value("--input"); + auto outFileName = argParser.value("--output"); - auto outFileType = outFileName.substr(outFileName.find_last_of('.') + 1); + auto outFileType = outFileName.substr(outFileName.find_last_of('.') + 1); - auto fromGeneratedKernel = argParser.isSet("-k"); + auto fromGeneratedKernel = argParser.isSet("-k"); - if (fromGeneratedKernel) - { - std::cout << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName << "\" (type: " << outFileType << ")" < Date: Mon, 27 Nov 2017 17:06:19 +0100 Subject: [PATCH 04/83] Require cppexpose dependency --- source/tools/glkernel-cli/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/tools/glkernel-cli/CMakeLists.txt b/source/tools/glkernel-cli/CMakeLists.txt index 4c8c56d..542fea2 100644 --- a/source/tools/glkernel-cli/CMakeLists.txt +++ b/source/tools/glkernel-cli/CMakeLists.txt @@ -4,6 +4,7 @@ # find_package(cppassist REQUIRED) +find_package(cppexpose REQUIRED) # # Executable name and options @@ -78,6 +79,7 @@ target_link_libraries(${target} PRIVATE ${DEFAULT_LIBRARIES} cppassist::cppassist + cppexpose::cppexpose ${META_PROJECT_NAME}::glkernel ) From 5eed0a2151fb0707ae4391ca07a5ae275f567b72 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 4 Dec 2017 14:31:21 +0100 Subject: [PATCH 05/83] Rewrite CLI using cppassist::CommandLineProgram --- source/tools/glkernel-cli/main.cpp | 99 ++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 12 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index 21f467b..ba0425d 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -1,28 +1,103 @@ #include #include +#include + #include +#include +#include +#include +#include +#include +#include int main(int argc, char* argv[]) { - cppassist::ArgumentParser argParser; - argParser.parse(argc, argv); + auto program = cppassist::CommandLineProgram{ + "glkernel-cli", + "glkernel-cli", // TODO version, license? + "A command line interface for generating and converting kernels."}; + + + auto actionGenerate = cppassist::CommandLineAction{"generate", "Generate a kernel from a kernel description"}; + auto actionConvert = cppassist::CommandLineAction{"convert", "Convert an existing kernel into another representation"}; + + auto commandGenerate = cppassist::CommandLineCommand{"generate"}; + auto commandConvert = cppassist::CommandLineCommand{"convert"}; + + auto optInputFile = cppassist::CommandLineOption{"--input", "-i", "inFileName", + "Kernel description or generated kernel", cppassist::CommandLineOption::NonOptional}; + auto optOutputFile = cppassist::CommandLineOption{"--output", "-o", "outFileName", + "File that the generated / converted kernel will be written to", cppassist::CommandLineOption::NonOptional}; + auto optOutputFormat = cppassist::CommandLineOption{"--format", "-f", "outFileFormat", + "File format for the generated / converted kernel (e.g. json, png)", cppassist::CommandLineOption::Optional}; + + actionGenerate.add(&commandGenerate); + actionGenerate.add(&optInputFile); + actionGenerate.add(&optOutputFile); + actionGenerate.add(&optOutputFormat); - auto inFileName = argParser.value("--input"); - auto outFileName = argParser.value("--output"); + actionConvert.add(&commandConvert); + actionConvert.add(&optInputFile); + actionConvert.add(&optOutputFile); + actionConvert.add(&optOutputFormat); - auto outFileType = outFileName.substr(outFileName.find_last_of('.') + 1); + program.add(&actionGenerate); + program.add(&actionConvert); - auto fromGeneratedKernel = argParser.isSet("-k"); + program.parse(argc, argv); - if (fromGeneratedKernel) - { - std::cout << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName << "\" (type: " << outFileType << ")" <errors()[0]; + program.print("Error: " + error); + + return 1; + } } + return 0; } \ No newline at end of file From b56cc35c77488e4f34dccbf8bf073212318aceed Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 4 Dec 2017 14:45:14 +0100 Subject: [PATCH 06/83] Remove unused import, add version --- source/tools/glkernel-cli/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index ba0425d..386e1ed 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -3,20 +3,20 @@ #include +#include + #include #include #include #include #include -#include -#include int main(int argc, char* argv[]) { auto program = cppassist::CommandLineProgram{ "glkernel-cli", - "glkernel-cli", // TODO version, license? + "glkernel-cli " GLKERNEL_VERSION, "A command line interface for generating and converting kernels."}; From 0905f9faacc460b6539e65d699a61d5d603a3381 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 4 Dec 2017 15:18:20 +0100 Subject: [PATCH 07/83] Use switch instead of different actions --- source/tools/glkernel-cli/main.cpp | 97 +++++++++++++++--------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index 386e1ed..0d7dc64 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include int main(int argc, char* argv[]) @@ -20,69 +20,72 @@ int main(int argc, char* argv[]) "A command line interface for generating and converting kernels."}; - auto actionGenerate = cppassist::CommandLineAction{"generate", "Generate a kernel from a kernel description"}; - auto actionConvert = cppassist::CommandLineAction{"convert", "Convert an existing kernel into another representation"}; + auto actionRun = cppassist::CommandLineAction{"run", + "Generate a kernel from a kernel description or convert an existing kernel into another representation"}; - auto commandGenerate = cppassist::CommandLineCommand{"generate"}; - auto commandConvert = cppassist::CommandLineCommand{"convert"}; + auto optInputFile = cppassist::CommandLineOption{ + "--input", + "-i", + "inFileName", + "Kernel description or generated kernel", + cppassist::CommandLineOption::NonOptional}; - auto optInputFile = cppassist::CommandLineOption{"--input", "-i", "inFileName", - "Kernel description or generated kernel", cppassist::CommandLineOption::NonOptional}; - auto optOutputFile = cppassist::CommandLineOption{"--output", "-o", "outFileName", - "File that the generated / converted kernel will be written to", cppassist::CommandLineOption::NonOptional}; - auto optOutputFormat = cppassist::CommandLineOption{"--format", "-f", "outFileFormat", - "File format for the generated / converted kernel (e.g. json, png)", cppassist::CommandLineOption::Optional}; + auto optOutputFile = cppassist::CommandLineOption{ + "--output", + "-o", + "outFileName", + "File that the generated / converted kernel will be written to", + cppassist::CommandLineOption::NonOptional}; - actionGenerate.add(&commandGenerate); - actionGenerate.add(&optInputFile); - actionGenerate.add(&optOutputFile); - actionGenerate.add(&optOutputFormat); + auto optOutputFormat = cppassist::CommandLineOption{ + "--format", + "-f", + "outFileFormat", + "File format for the generated / converted kernel (e.g. json, png)", + cppassist::CommandLineOption::Optional}; - actionConvert.add(&commandConvert); - actionConvert.add(&optInputFile); - actionConvert.add(&optOutputFile); - actionConvert.add(&optOutputFormat); + auto swConvert = cppassist::CommandLineSwitch{ + "--convert", + "-c", + "Convert an existing kernel into another representation instead of generating a new one", + cppassist::CommandLineSwitch::Optional}; - program.add(&actionGenerate); - program.add(&actionConvert); + + actionRun.add(&optInputFile); + actionRun.add(&optOutputFile); + actionRun.add(&optOutputFormat); + actionRun.add(&swConvert); + + program.add(&actionRun); program.parse(argc, argv); if (program.selectedAction() && !program.hasErrors()) { // Generate kernel from description - if (program.selectedAction() == &actionGenerate) { - const auto& inFileName = optInputFile.value(); - const auto& outFileName = optOutputFile.value(); - auto outFileFormat = optOutputFormat.value(); - if (outFileFormat.empty()) { - if (outFileName.find('.') == std::string::npos) { - outFileFormat = "json"; - } else { - outFileFormat = outFileName.substr(outFileName.find_last_of('.') + 1); - } + const auto &inFileName = optInputFile.value(); + const auto &outFileName = optOutputFile.value(); + auto outFileFormat = optOutputFormat.value(); + if (outFileFormat.empty()) { + if (outFileName.find('.') == std::string::npos) { + outFileFormat = "json"; + } else { + outFileFormat = outFileName.substr(outFileName.find_last_of('.') + 1); } - cppassist::info() << "Using kernel description \"" << inFileName << "\" to generate kernel \"" << outFileName << "\" (format: " << outFileFormat << ")"; } - // Convert kernel to other representation - else if (program.selectedAction() == &actionConvert) { - const auto& inFileName = optInputFile.value(); - const auto& outFileName = optOutputFile.value(); - auto outFileFormat = optOutputFormat.value(); - if (outFileFormat.empty()) { - outFileFormat = outFileName.substr(outFileName.find_last_of('.') + 1); - if (outFileName.find('.') == std::string::npos) { - outFileFormat = "json"; - } else { - outFileFormat = outFileName.substr(outFileName.find_last_of('.') + 1); - } - } - cppassist::info() << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName << "\" (format: " << outFileFormat << ")"; + if (swConvert.activated()) { + // Convert kernel to other representation + cppassist::info() << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName + << "\" (format: " << outFileFormat << ")"; + } else { + // Generate kernel from description + cppassist::info() << "Using kernel description \"" << inFileName << "\" to generate kernel \"" + << outFileName << "\" (format: " << outFileFormat << ")"; } - // Success return 0; + // Success } else { From e26abe528c9123f9fd8a44b68d19cb789e479843 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Mon, 4 Dec 2017 15:29:58 +0100 Subject: [PATCH 08/83] Start basic scripting --- source/tools/glkernel-cli/CMakeLists.txt | 4 ++ source/tools/glkernel-cli/main.cpp | 6 ++- source/tools/glkernel-cli/scripting.cpp | 53 ++++++++++++++++++++++++ source/tools/glkernel-cli/scripting.h | 18 ++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 source/tools/glkernel-cli/scripting.cpp create mode 100644 source/tools/glkernel-cli/scripting.h diff --git a/source/tools/glkernel-cli/CMakeLists.txt b/source/tools/glkernel-cli/CMakeLists.txt index 4c8c56d..206c42f 100644 --- a/source/tools/glkernel-cli/CMakeLists.txt +++ b/source/tools/glkernel-cli/CMakeLists.txt @@ -4,6 +4,7 @@ # find_package(cppassist REQUIRED) +find_package(cppexpose REQUIRED) # # Executable name and options @@ -18,10 +19,12 @@ set(target glkernel-cli) # set(headers + scripting.h ) set(sources main.cpp + scripting.cpp ) set(header_group "Header Files (API)") @@ -78,6 +81,7 @@ target_link_libraries(${target} PRIVATE ${DEFAULT_LIBRARIES} cppassist::cppassist + cppexpose::cppexpose ${META_PROJECT_NAME}::glkernel ) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index b506b80..41e07a5 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -1,8 +1,9 @@ #include #include -#include +#include "scripting.h" +#include int main(int argc, char* argv[]) { @@ -25,4 +26,5 @@ int main(int argc, char* argv[]) std::cout << "Using kernel description \"" << inFileName << "\" to generate kernel \"" << outFileName << "\" (type: " << outFileType << ")" << std::endl; } -} \ No newline at end of file + doScripting(); +} diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp new file mode 100644 index 0000000..0c6f627 --- /dev/null +++ b/source/tools/glkernel-cli/scripting.cpp @@ -0,0 +1,53 @@ +#include "scripting.h" + +#include + +#include + +#include +#include + +void printKernel(const std::array& kernel) { + for (int i = 0; i < 10; ++i) + { + std::cout << kernel[i] << std::endl; + } +} + +//void printKernel2(const cppexpose::Variant& variant) { +// const auto& map = *variant.asMap(); +// const auto& kernelVariant = map.at("kernel"); +// const auto kernel = kernelVariant.value(); + +// std::cout << kernel.size() << std::endl; +//} + +void doScripting() +{ + ScriptingObject obj; + + cppexpose::ScriptContext scriptContext; + scriptContext.addGlobalObject(&obj); + + auto variant = scriptContext.evaluate("kernel.uniform(0.0, 1.0); kernel.print();"); +} + +ScriptingObject::ScriptingObject() +: Object("kernel") +{ + m_kernel = glkernel::kernel1(10, 1, 1); + + addFunction("uniform", this, &ScriptingObject::uniform); + addFunction("print", this, &ScriptingObject::print); +} + +void ScriptingObject::uniform(float range_min, float range_max) +{ + glkernel::sequence::uniform(m_kernel, range_min, range_max); +} + +void ScriptingObject::print() +{ + for (const auto& val : m_kernel) + std::cout << val << std::endl; +} diff --git a/source/tools/glkernel-cli/scripting.h b/source/tools/glkernel-cli/scripting.h new file mode 100644 index 0000000..563903e --- /dev/null +++ b/source/tools/glkernel-cli/scripting.h @@ -0,0 +1,18 @@ + +#include + +#include + +class ScriptingObject : public cppexpose::Object +{ +public: + ScriptingObject(); + + void uniform(float range_min, float range_max); + void print(); + +protected: + glkernel::kernel1 m_kernel; +}; + +void doScripting(); From 0fd5e2f9c6ddecdbc561bf54f2b8729f9ff2d3fa Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Mon, 4 Dec 2017 15:58:27 +0100 Subject: [PATCH 09/83] Remove old code --- source/tools/glkernel-cli/scripting.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index 0c6f627..0513b36 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -14,14 +14,6 @@ void printKernel(const std::array& kernel) { } } -//void printKernel2(const cppexpose::Variant& variant) { -// const auto& map = *variant.asMap(); -// const auto& kernelVariant = map.at("kernel"); -// const auto kernel = kernelVariant.value(); - -// std::cout << kernel.size() << std::endl; -//} - void doScripting() { ScriptingObject obj; From b8f51a741ddc217dcbae9535d3d789f58a22d463 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Mon, 4 Dec 2017 17:28:49 +0100 Subject: [PATCH 10/83] Implement conversion between kernel and variant to enable javascript to access kernel --- source/tools/glkernel-cli/scripting.cpp | 60 +++++++++++++++++++++---- source/tools/glkernel-cli/scripting.h | 3 ++ 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index 0513b36..f5dc47b 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -3,25 +3,33 @@ #include #include +#include #include #include -void printKernel(const std::array& kernel) { - for (int i = 0; i < 10; ++i) - { - std::cout << kernel[i] << std::endl; - } -} - void doScripting() { ScriptingObject obj; cppexpose::ScriptContext scriptContext; scriptContext.addGlobalObject(&obj); + scriptContext.scriptException.connect([](const std::string & msg) { + std::cerr << msg << std::endl; + }); - auto variant = scriptContext.evaluate("kernel.uniform(0.0, 1.0); kernel.print();"); + auto script = R"( + kernel.uniform(0.0, 1.0); + var t = kernel.toArray(); + t = t.map(function(v) { return Math.log(v + 0.1); }); + kernel.fromArray(t); + kernel.shuffle_random(); + var s = kernel.toArray(); + s + )"; + + auto variant = scriptContext.evaluate(script); + std::cout << variant.toString(); } ScriptingObject::ScriptingObject() @@ -30,7 +38,10 @@ ScriptingObject::ScriptingObject() m_kernel = glkernel::kernel1(10, 1, 1); addFunction("uniform", this, &ScriptingObject::uniform); + addFunction("shuffle_random", this, &ScriptingObject::shuffle_random); addFunction("print", this, &ScriptingObject::print); + addFunction("toArray", this, &ScriptingObject::toArray); + addFunction("fromArray", this, &ScriptingObject::fromArray); } void ScriptingObject::uniform(float range_min, float range_max) @@ -38,8 +49,41 @@ void ScriptingObject::uniform(float range_min, float range_max) glkernel::sequence::uniform(m_kernel, range_min, range_max); } +void ScriptingObject::shuffle_random() +{ + glkernel::shuffle::random(m_kernel); +} + void ScriptingObject::print() { for (const auto& val : m_kernel) + { std::cout << val << std::endl; + } +} + +cppexpose::Variant ScriptingObject::toArray() +{ + cppexpose::Variant result = cppexpose::Variant::array(); + auto resultArray = result.asArray(); + + for (const auto& val : m_kernel) + { + resultArray->push_back(val); + } + + return result; +} + +void ScriptingObject::fromArray(const cppexpose::Variant& array) +{ + auto values = array.asArray(); + + int i = 0; + + for (const auto& variant : *values) + { + m_kernel[i] = variant.value(); + i += 1; + } } diff --git a/source/tools/glkernel-cli/scripting.h b/source/tools/glkernel-cli/scripting.h index 563903e..a907545 100644 --- a/source/tools/glkernel-cli/scripting.h +++ b/source/tools/glkernel-cli/scripting.h @@ -9,7 +9,10 @@ class ScriptingObject : public cppexpose::Object ScriptingObject(); void uniform(float range_min, float range_max); + void shuffle_random(); void print(); + cppexpose::Variant toArray(); + void fromArray(const cppexpose::Variant& array); protected: glkernel::kernel1 m_kernel; From 45bfa237da3a716939fe8f481338404122af0f41 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 11 Dec 2017 17:35:58 +0100 Subject: [PATCH 11/83] Incorporate change ideas from #1 --- source/tools/glkernel-cli/main.cpp | 102 ++++++++++++++++++----------- 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index 0d7dc64..d51d4e4 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include int main(int argc, char* argv[]) @@ -17,68 +17,95 @@ int main(int argc, char* argv[]) auto program = cppassist::CommandLineProgram{ "glkernel-cli", "glkernel-cli " GLKERNEL_VERSION, - "A command line interface for generating and converting kernels."}; + "A command line interface for generating and converting kernels." + }; + auto actionRun = cppassist::CommandLineAction{ + "run", + "Generate a kernel from a kernel description (.js file), or convert an existing kernel (.json file) into another representation" + }; - auto actionRun = cppassist::CommandLineAction{"run", - "Generate a kernel from a kernel description or convert an existing kernel into another representation"}; - - auto optInputFile = cppassist::CommandLineOption{ - "--input", - "-i", - "inFileName", - "Kernel description or generated kernel", - cppassist::CommandLineOption::NonOptional}; + auto paramInputFile = cppassist::CommandLineParameter{ + "inputFileName", + cppassist::CommandLineParameter::NonOptional + }; auto optOutputFile = cppassist::CommandLineOption{ "--output", "-o", - "outFileName", - "File that the generated / converted kernel will be written to", - cppassist::CommandLineOption::NonOptional}; + "outputFileName", + "File that the generated / converted kernel will be written to (defaults: .json for generation, .png for conversion)", + cppassist::CommandLineOption::Optional + }; auto optOutputFormat = cppassist::CommandLineOption{ "--format", "-f", - "outFileFormat", - "File format for the generated / converted kernel (e.g. json, png)", - cppassist::CommandLineOption::Optional}; - - auto swConvert = cppassist::CommandLineSwitch{ - "--convert", - "-c", - "Convert an existing kernel into another representation instead of generating a new one", - cppassist::CommandLineSwitch::Optional}; - + "outputFileFormat", + "File format for the generated / converted kernel (e.g. .json, .png, .h)", + cppassist::CommandLineOption::Optional + }; - actionRun.add(&optInputFile); + actionRun.add(¶mInputFile); actionRun.add(&optOutputFile); actionRun.add(&optOutputFormat); - actionRun.add(&swConvert); program.add(&actionRun); program.parse(argc, argv); - if (program.selectedAction() && !program.hasErrors()) { + if (program.selectedAction() && !program.hasErrors()) + { + const auto &inFileName = paramInputFile.value(); + + if (inFileName.find('.') == std::string::npos) + { + cppassist::error() << "Input file must have .js or .json file format"; + return 1; + } + const auto inFileFormat = inFileName.substr(inFileName.find_last_of('.') + 1); + if (inFileFormat != "js" && inFileFormat != "json") + { + cppassist::error() << "Input file must have .js or .json file format"; + return 1; + } + const auto shouldConvert = inFileFormat == "json"; - // Generate kernel from description - const auto &inFileName = optInputFile.value(); - const auto &outFileName = optOutputFile.value(); auto outFileFormat = optOutputFormat.value(); - if (outFileFormat.empty()) { - if (outFileName.find('.') == std::string::npos) { - outFileFormat = "json"; - } else { + auto outFileName = optOutputFile.value(); + + if (outFileFormat.empty()) + { + if (outFileName.find('.') == std::string::npos) + { + if (shouldConvert) + { + outFileFormat = "png"; + } + else + { + outFileFormat = "json"; + } + } + else + { outFileFormat = outFileName.substr(outFileName.find_last_of('.') + 1); } } - if (swConvert.activated()) { + if (outFileName.empty()) + { + outFileName = inFileName.substr(0, inFileName.find_last_of('.')) + "." + outFileFormat; + } + + if (shouldConvert) + { // Convert kernel to other representation cppassist::info() << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName << "\" (format: " << outFileFormat << ")"; - } else { + } + else + { // Generate kernel from description cppassist::info() << "Using kernel description \"" << inFileName << "\" to generate kernel \"" << outFileName << "\" (format: " << outFileFormat << ")"; @@ -88,7 +115,8 @@ int main(int argc, char* argv[]) // Success } - else { + else + { // Print help program.print(program.help(program.selectedAction())); From bcd44d305beacd3f3ff2d82666e51025f1824035 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 11 Dec 2017 17:47:14 +0100 Subject: [PATCH 12/83] Extract methods for readability --- source/tools/glkernel-cli/main.cpp | 84 ++++++++++++++++++------------ 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index d51d4e4..b34fd3e 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -12,6 +12,42 @@ #include +std::string extractInputFormat(const std::string & inFileName) { + if (inFileName.find('.') == std::string::npos) + { + return ""; + } + const auto inFileFormat = inFileName.substr(inFileName.find_last_of('.') + 1); + if (inFileFormat != "js" && inFileFormat != "json") + { + return ""; + } + return inFileFormat; +} + +std::string extractOutputFormat(const std::string & outFileName, const bool shouldConvert) { + if (outFileName.find('.') == std::string::npos) + { + if (shouldConvert) + { + return "png"; + } + else + { + return "json"; + } + } + else + { + return outFileName.substr(outFileName.find_last_of('.') + 1); + } +} + +std::string extractOutputFile(const std::string & inputFile, const std::string & outputFileFormat) { + const auto &inputFileName = inputFile.substr(0, inputFile.find_last_of('.')); + return inputFileName + "." + outputFileFormat; +} + int main(int argc, char* argv[]) { auto program = cppassist::CommandLineProgram{ @@ -56,59 +92,39 @@ int main(int argc, char* argv[]) if (program.selectedAction() && !program.hasErrors()) { - const auto &inFileName = paramInputFile.value(); - - if (inFileName.find('.') == std::string::npos) - { - cppassist::error() << "Input file must have .js or .json file format"; - return 1; - } - const auto inFileFormat = inFileName.substr(inFileName.find_last_of('.') + 1); - if (inFileFormat != "js" && inFileFormat != "json") + const auto & inputFile = paramInputFile.value(); + const auto & inputFormat = extractInputFormat(inputFile); + if (inputFormat.empty()) { cppassist::error() << "Input file must have .js or .json file format"; return 1; } - const auto shouldConvert = inFileFormat == "json"; + const auto shouldConvert = inputFormat == "json"; - auto outFileFormat = optOutputFormat.value(); - auto outFileName = optOutputFile.value(); + auto outputFormat = optOutputFormat.value(); + auto outputFile = optOutputFile.value(); - if (outFileFormat.empty()) + if (outputFormat.empty()) { - if (outFileName.find('.') == std::string::npos) - { - if (shouldConvert) - { - outFileFormat = "png"; - } - else - { - outFileFormat = "json"; - } - } - else - { - outFileFormat = outFileName.substr(outFileName.find_last_of('.') + 1); - } + outputFormat = extractOutputFormat(outputFile, shouldConvert); } - if (outFileName.empty()) + if (outputFile.empty()) { - outFileName = inFileName.substr(0, inFileName.find_last_of('.')) + "." + outFileFormat; + outputFile = extractOutputFile(inputFile, outputFormat); } if (shouldConvert) { // Convert kernel to other representation - cppassist::info() << "Converting kernel \"" << inFileName << "\" to output file \"" << outFileName - << "\" (format: " << outFileFormat << ")"; + cppassist::info() << "Converting kernel \"" << inputFile << "\" to output file \"" << outputFile + << "\" (format: " << outputFormat << ")"; } else { // Generate kernel from description - cppassist::info() << "Using kernel description \"" << inFileName << "\" to generate kernel \"" - << outFileName << "\" (format: " << outFileFormat << ")"; + cppassist::info() << "Using kernel description \"" << inputFile << "\" to generate kernel \"" + << outputFile << "\" (format: " << outputFormat << ")"; } return 0; From c4120937fe35741753c326f5909e35b3e540b2e7 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Tue, 12 Dec 2017 16:04:10 +0100 Subject: [PATCH 13/83] WIP new scripting interface --- source/tools/glkernel-cli/scripting.cpp | 72 +++++++++++++++---------- source/tools/glkernel-cli/scripting.h | 10 ++++ 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index f5dc47b..366606f 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -19,13 +19,20 @@ void doScripting() }); auto script = R"( - kernel.uniform(0.0, 1.0); - var t = kernel.toArray(); - t = t.map(function(v) { return Math.log(v + 0.1); }); - kernel.fromArray(t); - kernel.shuffle_random(); - var s = kernel.toArray(); - s + var Kernel = function(x, y, z) { + this.kernel = _glkernel.createKernel1(x, y, z); + //this.kernel.print(); + }; + + // inherit from Array + //Kernel.prototype = new Array; + + var kernel = new Kernel(10, 1, 1); +// kernel.push(1.0); +// kernel.push(2.0); +// kernel.push(3.0); + +// kernel )"; auto variant = scriptContext.evaluate(script); @@ -33,36 +40,40 @@ void doScripting() } ScriptingObject::ScriptingObject() -: Object("kernel") +: Object("_glkernel") { - m_kernel = glkernel::kernel1(10, 1, 1); - - addFunction("uniform", this, &ScriptingObject::uniform); - addFunction("shuffle_random", this, &ScriptingObject::shuffle_random); - addFunction("print", this, &ScriptingObject::print); - addFunction("toArray", this, &ScriptingObject::toArray); - addFunction("fromArray", this, &ScriptingObject::fromArray); +// addFunction("uniform", this, &ScriptingObject::uniform); +// addFunction("shuffle_random", this, &ScriptingObject::shuffle_random); + addFunction("createKernel1", this, &ScriptingObject::createKernel1); + //addFunction("toArray", this, &ScriptingObject::toArray); + //addFunction("fromArray", this, &ScriptingObject::fromArray); } -void ScriptingObject::uniform(float range_min, float range_max) +cppexpose::Object* ScriptingObject::createKernel1(int width, int height, int depth) { - glkernel::sequence::uniform(m_kernel, range_min, range_max); + std::cout << width << " " << height << " " << depth << std::endl; + return new KernelObject(); } -void ScriptingObject::shuffle_random() -{ - glkernel::shuffle::random(m_kernel); -} +//void ScriptingObject::uniform(float range_min, float range_max) +//{ +// glkernel::sequence::uniform(m_kernel, range_min, range_max); +//} + +//void ScriptingObject::shuffle_random() +//{ +// glkernel::shuffle::random(m_kernel); +//} -void ScriptingObject::print() +KernelObject::KernelObject() +: Object() { - for (const auto& val : m_kernel) - { - std::cout << val << std::endl; - } + m_kernel = glkernel::kernel1(10, 1, 1); + + addFunction("print", this, &KernelObject::print); } -cppexpose::Variant ScriptingObject::toArray() +cppexpose::Variant KernelObject::toArray() { cppexpose::Variant result = cppexpose::Variant::array(); auto resultArray = result.asArray(); @@ -75,7 +86,7 @@ cppexpose::Variant ScriptingObject::toArray() return result; } -void ScriptingObject::fromArray(const cppexpose::Variant& array) +void KernelObject::fromArray(const cppexpose::Variant& array) { auto values = array.asArray(); @@ -87,3 +98,8 @@ void ScriptingObject::fromArray(const cppexpose::Variant& array) i += 1; } } + +void KernelObject::print() +{ + std::cout << "I'm a kernel." << std::endl; +} diff --git a/source/tools/glkernel-cli/scripting.h b/source/tools/glkernel-cli/scripting.h index a907545..66d0d62 100644 --- a/source/tools/glkernel-cli/scripting.h +++ b/source/tools/glkernel-cli/scripting.h @@ -3,6 +3,8 @@ #include +class KernelObject; + class ScriptingObject : public cppexpose::Object { public: @@ -10,6 +12,14 @@ class ScriptingObject : public cppexpose::Object void uniform(float range_min, float range_max); void shuffle_random(); + cppexpose::Object* createKernel1(int width, int height, int depth); +}; + +class KernelObject : public cppexpose::Object +{ +public: + KernelObject(); + void print(); cppexpose::Variant toArray(); void fromArray(const cppexpose::Variant& array); From 720aaa6b2b8150248be5b9d063d10243f05c81f0 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 8 Jan 2018 16:20:14 +0100 Subject: [PATCH 14/83] Add KernelGenerator and KernelExporter for kernel generation from javascript, and kernel export to JSON --- source/tools/glkernel-cli/CMakeLists.txt | 5 +++ source/tools/glkernel-cli/KernelGenerator.cpp | 22 +++++++++++ source/tools/glkernel-cli/KernelGenerator.hpp | 10 +++++ .../glkernel-cli/export/KernelExporter.hpp | 16 ++++++++ .../export/KernelJsonExporter.cpp | 38 +++++++++++++++++++ .../export/KernelJsonExporter.hpp | 15 ++++++++ source/tools/glkernel-cli/main.cpp | 9 +++++ 7 files changed, 115 insertions(+) create mode 100644 source/tools/glkernel-cli/KernelGenerator.cpp create mode 100644 source/tools/glkernel-cli/KernelGenerator.hpp create mode 100644 source/tools/glkernel-cli/export/KernelExporter.hpp create mode 100644 source/tools/glkernel-cli/export/KernelJsonExporter.cpp create mode 100644 source/tools/glkernel-cli/export/KernelJsonExporter.hpp diff --git a/source/tools/glkernel-cli/CMakeLists.txt b/source/tools/glkernel-cli/CMakeLists.txt index 542fea2..79fbad2 100644 --- a/source/tools/glkernel-cli/CMakeLists.txt +++ b/source/tools/glkernel-cli/CMakeLists.txt @@ -19,10 +19,15 @@ set(target glkernel-cli) # set(headers + export/KernelExporter.hpp + export/KernelJsonExporter.hpp + KernelGenerator.hpp ) set(sources main.cpp + export/KernelJsonExporter.cpp + KernelGenerator.cpp ) set(header_group "Header Files (API)") diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp new file mode 100644 index 0000000..c158823 --- /dev/null +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -0,0 +1,22 @@ +#include "KernelGenerator.hpp" + +#include + +#include +#include +#include + +KernelGenerator::KernelGenerator(const std::string& inputFileName) +{ + auto inputStream = std::ifstream{inputFileName}; + auto inputStringStream = std::stringstream{}; + inputStringStream << inputStream.rdbuf(); + m_scriptCode = inputStringStream.str(); +} + +cppexpose::Variant KernelGenerator::generateKernelFromJavascript() +{ + auto generatedKernel = glkernel::kernel4{}; // TODO generate from js scriptCode + + return cppexpose::Variant::fromValue(generatedKernel); +} diff --git a/source/tools/glkernel-cli/KernelGenerator.hpp b/source/tools/glkernel-cli/KernelGenerator.hpp new file mode 100644 index 0000000..02dc737 --- /dev/null +++ b/source/tools/glkernel-cli/KernelGenerator.hpp @@ -0,0 +1,10 @@ +#include + +class KernelGenerator +{ +public: + explicit KernelGenerator(const std::string & inputFileName); + cppexpose::Variant generateKernelFromJavascript(); +protected: + std::string m_scriptCode; +}; \ No newline at end of file diff --git a/source/tools/glkernel-cli/export/KernelExporter.hpp b/source/tools/glkernel-cli/export/KernelExporter.hpp new file mode 100644 index 0000000..ccb9e31 --- /dev/null +++ b/source/tools/glkernel-cli/export/KernelExporter.hpp @@ -0,0 +1,16 @@ +#include +#include + +#include + +class KernelExporter { +public: + KernelExporter(const cppexpose::Variant & kernelVariant, const std::string & outFileName, bool force) : + m_kernel{kernelVariant}, m_outFileName{outFileName}, m_force{force} {} + + virtual void export() = 0; +protected: + cppexpose::Variant m_kernel; + std::string m_outFileName; + bool m_force; +}; \ No newline at end of file diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp new file mode 100644 index 0000000..7434386 --- /dev/null +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp @@ -0,0 +1,38 @@ +#include "KernelJsonExporter.hpp" + +#include +#include + +void KernelJsonExporter::export() { + const auto jsonArray = toJsonArray(m_kernel); + + writeToFile(jsonArray); +} + +cppexpose::Variant KernelJsonExporter::toJsonArray(const cppexpose::Variant & kernel) { + + /* TODO convert kernel to json-stringifyable variant array + * check kernel.hasType, and build corresponding appendComponentToVariantArray lambda + */ + + return cppexpose::Variant::fromValue(glkernel::kernel4{ }); +} + + +void KernelJsonExporter::writeToFile(const cppexpose::Variant & jsonArray) { + // TODO: check if file exists + // if (!force && fileExists(outFileName)) { std::cerr << "... / throw? + std::ofstream outStream(m_outFileName); + + if (!outStream.is_open()) + { + // TODO exception instead? + std::cerr << "ERROR: Output file could not be created. Aborting..." << std::endl; + } + + outStream << stringify(jsonArray) << std::endl; +} + +std::string KernelJsonExporter::stringify(const cppexpose::Variant &array) { + return cppexpose::JSON::stringify(array, cppexpose::JSON::OutputMode::Beautify); +} diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp new file mode 100644 index 0000000..f0c3f70 --- /dev/null +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp @@ -0,0 +1,15 @@ +#include "KernelExporter.hpp" + +class KernelJsonExporter : public KernelExporter { +protected: +public: + KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName, bool force) : + KernelExporter{kernel, outFileName, force} {} + + void export() override; + +protected: + cppexpose::Variant toJsonArray(const cppexpose::Variant & kernel); + void writeToFile(const cppexpose::Variant & jsonArray); + std::string stringify(const cppexpose::Variant & jsonArray); +}; diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index b34fd3e..636d0ed 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -11,6 +11,10 @@ #include #include +#include "KernelGenerator.hpp" +#include "export/KernelExporter.hpp +#include "export/KernelJsonExporter.hpp + std::string extractInputFormat(const std::string & inFileName) { if (inFileName.find('.') == std::string::npos) @@ -125,6 +129,11 @@ int main(int argc, char* argv[]) // Generate kernel from description cppassist::info() << "Using kernel description \"" << inputFile << "\" to generate kernel \"" << outputFile << "\" (format: " << outputFormat << ")"; + + auto kernelGenerator = KernelGenerator{inputFile}; + auto kernelVariant = kernelGenerator.generateKernelFromJavascript(); + auto kernelExporter = KernelJsonExporter{kernelVariant, outputFile, false}; // TODO change when --force flag is added + kernelExporter.export(); } return 0; From 4cd117171dc17971d754b87de2749fa03b652049 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 8 Jan 2018 16:49:49 +0100 Subject: [PATCH 15/83] Add --force switch and abort if output file exists and --force is not given --- source/tools/glkernel-cli/main.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index b34fd3e..929b247 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -10,6 +11,7 @@ #include #include #include +#include std::string extractInputFormat(const std::string & inFileName) { @@ -82,9 +84,17 @@ int main(int argc, char* argv[]) cppassist::CommandLineOption::Optional }; + auto swForce = cppassist::CommandLineSwitch{ + "--force", + "", + "Override the output file, if it exists", + cppassist::CommandLineSwitch::Optional + }; + actionRun.add(¶mInputFile); actionRun.add(&optOutputFile); actionRun.add(&optOutputFormat); + actionRun.add(&swForce); program.add(&actionRun); @@ -114,6 +124,17 @@ int main(int argc, char* argv[]) outputFile = extractOutputFile(inputFile, outputFormat); } + const auto shouldOverride = swForce.activated(); + auto outputFileExists= std::ifstream{outputFile}; + if (outputFileExists) + { + if (!shouldOverride) + { + cppassist::error() << "Output file \"" << outputFile << "\" exists! Use --force to override."; + return 1; + } + } + if (shouldConvert) { // Convert kernel to other representation From 168a5373cc5d1f6c0046e27b7c4fb337081c25c4 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 8 Jan 2018 16:56:58 +0100 Subject: [PATCH 16/83] Add comment explaining empty short name --- source/tools/glkernel-cli/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index 929b247..ac1bdcb 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -86,7 +86,7 @@ int main(int argc, char* argv[]) auto swForce = cppassist::CommandLineSwitch{ "--force", - "", + "", // no short name, force should be explicit to avoid accidental overrides "Override the output file, if it exists", cppassist::CommandLineSwitch::Optional }; From 29dfae82d80362ea8030d278b6e69a7917d30391 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 8 Jan 2018 17:00:49 +0100 Subject: [PATCH 17/83] Incorporate review feedback --- source/tools/glkernel-cli/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index ac1bdcb..ce31a1a 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -125,8 +125,8 @@ int main(int argc, char* argv[]) } const auto shouldOverride = swForce.activated(); - auto outputFileExists= std::ifstream{outputFile}; - if (outputFileExists) + auto outputExistsStream = std::ifstream{outputFile}; + if (outputExistsStream) { if (!shouldOverride) { From 003c9095407bb1fe99df4ad11dee5a974eee9744 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 8 Jan 2018 17:06:52 +0100 Subject: [PATCH 18/83] Remove force parameter from exporter - is handled before now --- source/tools/glkernel-cli/export/KernelExporter.hpp | 5 ++--- source/tools/glkernel-cli/export/KernelJsonExporter.hpp | 4 ++-- source/tools/glkernel-cli/main.cpp | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/tools/glkernel-cli/export/KernelExporter.hpp b/source/tools/glkernel-cli/export/KernelExporter.hpp index ccb9e31..7204b21 100644 --- a/source/tools/glkernel-cli/export/KernelExporter.hpp +++ b/source/tools/glkernel-cli/export/KernelExporter.hpp @@ -5,12 +5,11 @@ class KernelExporter { public: - KernelExporter(const cppexpose::Variant & kernelVariant, const std::string & outFileName, bool force) : - m_kernel{kernelVariant}, m_outFileName{outFileName}, m_force{force} {} + KernelExporter(const cppexpose::Variant & kernelVariant, const std::string & outFileName) : + m_kernel{kernelVariant}, m_outFileName{outFileName} {} virtual void export() = 0; protected: cppexpose::Variant m_kernel; std::string m_outFileName; - bool m_force; }; \ No newline at end of file diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp index f0c3f70..b90c170 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp @@ -3,8 +3,8 @@ class KernelJsonExporter : public KernelExporter { protected: public: - KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName, bool force) : - KernelExporter{kernel, outFileName, force} {} + KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName) : + KernelExporter{kernel, outFileName} {} void export() override; diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index 2bc3505..0349238 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -153,7 +153,7 @@ int main(int argc, char* argv[]) auto kernelGenerator = KernelGenerator{inputFile}; auto kernelVariant = kernelGenerator.generateKernelFromJavascript(); - auto kernelExporter = KernelJsonExporter{kernelVariant, outputFile, false}; // TODO change when --force flag is added + auto kernelExporter = KernelJsonExporter{kernelVariant, outputFile}; kernelExporter.export(); } From 12ce279c9a5cb842eb6faaca70e0d073b6cbb564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6schke?= Date: Mon, 8 Jan 2018 17:37:34 +0100 Subject: [PATCH 19/83] WIP: Expose glkernel operations to JavaScript Working: - Creating kernels from JS (currently only kernel) - Calling e.g. kernel.sequence.uniform() Missing: - Expose more functions --- source/tools/glkernel-cli/scripting.cpp | 176 ++++++++++++++---- source/tools/glkernel-cli/scripting.h | 50 ++++- .../tools/glkernel-cmd/KernelGeneration.cpp | 2 + 3 files changed, 178 insertions(+), 50 deletions(-) diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index 366606f..de55174 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -18,22 +18,46 @@ void doScripting() std::cerr << msg << std::endl; }); - auto script = R"( - var Kernel = function(x, y, z) { - this.kernel = _glkernel.createKernel1(x, y, z); - //this.kernel.print(); + auto script = R"javascript( + var _Kernel = function(x,y,z) { + + this._initialize = function(x,y,z) { + var that = this; + + this.kernel = this.generateKernel(x,y,z); + + this.sequence = { + uniform: function(min, max) { + _glkernel.uniform(that.kernel, min, max); + } + }; + this.shuffle = { + random: function() { + _glkernel.shuffle_random(that.kernel); + } + }; + }; }; + var Kernel1 = function(x,y,z) { + this.generateKernel = function(x,y,z) { + return _glkernel.createKernel1(x,y,z); + } + this._initialize(x,y,z); + } + // inherit from Array - //Kernel.prototype = new Array; + Kernel1.prototype = new _Kernel; - var kernel = new Kernel(10, 1, 1); + var kernel = new Kernel1(10, 1, 1); + kernel.sequence.uniform(0.0, 1.0); + kernel.shuffle.random(); // kernel.push(1.0); // kernel.push(2.0); // kernel.push(3.0); // kernel - )"; + )javascript"; auto variant = scriptContext.evaluate(script); std::cout << variant.toString(); @@ -42,64 +66,136 @@ void doScripting() ScriptingObject::ScriptingObject() : Object("_glkernel") { -// addFunction("uniform", this, &ScriptingObject::uniform); -// addFunction("shuffle_random", this, &ScriptingObject::shuffle_random); + addFunction("uniform", this, &ScriptingObject::uniform); + addFunction("shuffle_random", this, &ScriptingObject::shuffle_random); addFunction("createKernel1", this, &ScriptingObject::createKernel1); - //addFunction("toArray", this, &ScriptingObject::toArray); - //addFunction("fromArray", this, &ScriptingObject::fromArray); + addFunction("print", this, &ScriptingObject::print); } -cppexpose::Object* ScriptingObject::createKernel1(int width, int height, int depth) +void ScriptingObject::print(std::string s) { - std::cout << width << " " << height << " " << depth << std::endl; - return new KernelObject(); + std::cout << s << std::endl; } -//void ScriptingObject::uniform(float range_min, float range_max) -//{ -// glkernel::sequence::uniform(m_kernel, range_min, range_max); -//} +cppexpose::Object* ScriptingObject::createKernel1(int width, int height, int depth) +{ + return new Kernel1Object(width, height, depth); +} -//void ScriptingObject::shuffle_random() -//{ -// glkernel::shuffle::random(m_kernel); -//} +cppexpose::Object* ScriptingObject::createKernel2(int width, int height, int depth) +{ + return new Kernel2Object(width, height, depth); +} -KernelObject::KernelObject() -: Object() +cppexpose::Object* ScriptingObject::createKernel3(int width, int height, int depth) { - m_kernel = glkernel::kernel1(10, 1, 1); + return new Kernel3Object(width, height, depth); +} - addFunction("print", this, &KernelObject::print); +cppexpose::Object* ScriptingObject::createKernel4(int width, int height, int depth) +{ + return new Kernel4Object(width, height, depth); } -cppexpose::Variant KernelObject::toArray() +void ScriptingObject::uniform(cppexpose::Object* obj, float range_min, float range_max) { - cppexpose::Variant result = cppexpose::Variant::array(); - auto resultArray = result.asArray(); + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::sequence::uniform(kernelObj->kernel(), range_min, range_max); + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::sequence::uniform(kernelObj->kernel(), range_min, range_max); + return; + } - for (const auto& val : m_kernel) + if (auto kernelObj = dynamic_cast(obj)) { - resultArray->push_back(val); + glkernel::sequence::uniform(kernelObj->kernel(), range_min, range_max); + return; } - return result; + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::sequence::uniform(kernelObj->kernel(), range_min, range_max); + return; + } + + std::cerr << "Invalid kernel object in uniform()" << std::endl; } -void KernelObject::fromArray(const cppexpose::Variant& array) +void ScriptingObject::shuffle_random(cppexpose::Object* obj) { - auto values = array.asArray(); + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::shuffle::random(kernelObj->kernel()); + return; + } - int i = 0; + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::shuffle::random(kernelObj->kernel()); + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::shuffle::random(kernelObj->kernel()); + return; + } - for (const auto& variant : *values) + if (auto kernelObj = dynamic_cast(obj)) { - m_kernel[i] = variant.value(); - i += 1; + glkernel::shuffle::random(kernelObj->kernel()); + return; } + + std::cerr << "Invalid kernel object in shuffle_random()" << std::endl; } -void KernelObject::print() +Kernel1Object::Kernel1Object(int width, int height, int depth) +: Object() +, m_kernel(width, height, depth) +{ +} + +glkernel::kernel1& Kernel1Object::kernel() +{ + return m_kernel; +} + +Kernel2Object::Kernel2Object(int width, int height, int depth) +: Object() +, m_kernel(width, height, depth) +{ +} + +glkernel::kernel2& Kernel2Object::kernel() +{ + return m_kernel; +} + +Kernel3Object::Kernel3Object(int width, int height, int depth) +: Object() +, m_kernel(width, height, depth) { - std::cout << "I'm a kernel." << std::endl; } + +glkernel::kernel3& Kernel3Object::kernel() +{ + return m_kernel; +} + +Kernel4Object::Kernel4Object(int width, int height, int depth) +: Object() +, m_kernel(width, height, depth) +{ +} + +glkernel::kernel4& Kernel4Object::kernel() +{ + return m_kernel; +} + diff --git a/source/tools/glkernel-cli/scripting.h b/source/tools/glkernel-cli/scripting.h index 66d0d62..f5c91cf 100644 --- a/source/tools/glkernel-cli/scripting.h +++ b/source/tools/glkernel-cli/scripting.h @@ -3,29 +3,59 @@ #include -class KernelObject; - class ScriptingObject : public cppexpose::Object { public: ScriptingObject(); - void uniform(float range_min, float range_max); - void shuffle_random(); + void uniform(cppexpose::Object* kernelObj, float range_min, float range_max); + void shuffle_random(cppexpose::Object* kernelObj); cppexpose::Object* createKernel1(int width, int height, int depth); + cppexpose::Object* createKernel2(int width, int height, int depth); + cppexpose::Object* createKernel3(int width, int height, int depth); + cppexpose::Object* createKernel4(int width, int height, int depth); + + void print(std::string s); }; -class KernelObject : public cppexpose::Object +class Kernel1Object : public cppexpose::Object { public: - KernelObject(); - - void print(); - cppexpose::Variant toArray(); - void fromArray(const cppexpose::Variant& array); + Kernel1Object(int width, int height, int depth); + glkernel::kernel1& kernel(); protected: glkernel::kernel1 m_kernel; }; +class Kernel2Object : public cppexpose::Object +{ +public: + Kernel2Object(int width, int height, int depth); + glkernel::kernel2& kernel(); + +protected: + glkernel::kernel2 m_kernel; +}; + +class Kernel3Object : public cppexpose::Object +{ +public: + Kernel3Object(int width, int height, int depth); + glkernel::kernel3& kernel(); + +protected: + glkernel::kernel3 m_kernel; +}; + +class Kernel4Object : public cppexpose::Object +{ +public: + Kernel4Object(int width, int height, int depth); + glkernel::kernel4& kernel(); + +protected: + glkernel::kernel4 m_kernel; +}; + void doScripting(); diff --git a/source/tools/glkernel-cmd/KernelGeneration.cpp b/source/tools/glkernel-cmd/KernelGeneration.cpp index baa872a..058972e 100644 --- a/source/tools/glkernel-cmd/KernelGeneration.cpp +++ b/source/tools/glkernel-cmd/KernelGeneration.cpp @@ -14,6 +14,8 @@ namespace { + using uint = unsigned int; + template void processPoissonSquare(glkernel::tkernel & kernel, unsigned int num_probes) { From 0cfba92d9b8a0c64104d569a2049687ca5281174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6schke?= Date: Tue, 9 Jan 2018 10:07:22 +0100 Subject: [PATCH 20/83] Further WIP on exposure - Added scale::range and sort::distance - Figured out JS default parameters (see sort.distance) - Started JS-sided detection of parameter type --- source/tools/glkernel-cli/scripting.cpp | 122 ++++++++++++++++++++++-- source/tools/glkernel-cli/scripting.h | 3 + 2 files changed, 119 insertions(+), 6 deletions(-) diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index de55174..232964d 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include @@ -20,7 +22,6 @@ void doScripting() auto script = R"javascript( var _Kernel = function(x,y,z) { - this._initialize = function(x,y,z) { var that = this; @@ -36,6 +37,20 @@ void doScripting() _glkernel.shuffle_random(that.kernel); } }; + this.scale = { + range: function(toMin, toMax, fromMin, fromMax) { + // Defining default values for some parameters + fromMin = (typeof fromMin !== 'undefined') ? fromMin : 0.0; + fromMax = (typeof fromMax !== 'undefined') ? fromMax : 1.0; + + _glkernel.scale_range(that.kernel, toMin, toMax, fromMin, fromMax); + } + }; + this.sort = { + distance: function(origin) { + _glkernel.sort_distance(that.kernel, origin); + } + }; }; }; @@ -46,17 +61,51 @@ void doScripting() this._initialize(x,y,z); } - // inherit from Array Kernel1.prototype = new _Kernel; + // Done with preparation + var kernel = new Kernel1(10, 1, 1); + kernel.sequence.uniform(0.0, 1.0); kernel.shuffle.random(); -// kernel.push(1.0); -// kernel.push(2.0); -// kernel.push(3.0); + kernel.scale.range(-1,1); + kernel.sort.distance(0); + + f = function(arg) { + if (typeof arg === "number") + return "float"; + + if (typeof arg === "object") { + var keys = Object.keys(arg); + if ("0" in keys && typeof arg[0] === "number") { + if ("1" in keys && typeof arg[1] === "number") { + if ("2" in keys && typeof arg[2] === "number") { + if ("3" in keys && typeof arg[3] === "number") + return "vec4"; + else + return "vec3"; + } + else + return "vec2"; + } + else + return "vec1"; + } + } + + return "unknown"; + } + + _glkernel.print(f(1)); // float + _glkernel.print(f([1])); // vec1 + _glkernel.print(f([1,2])); // vec2 + _glkernel.print(f([1,2,3])); // vec3 + _glkernel.print(f([1,2,3,4])); // vec4 + _glkernel.print(f(["wrong"])); // unknown + _glkernel.print(f([1,2,"wrong later"])); // vec2 + _glkernel.print(f("completely wrong")); // unknown -// kernel )javascript"; auto variant = scriptContext.evaluate(script); @@ -68,6 +117,9 @@ ScriptingObject::ScriptingObject() { addFunction("uniform", this, &ScriptingObject::uniform); addFunction("shuffle_random", this, &ScriptingObject::shuffle_random); + addFunction("scale_range", this, &ScriptingObject::scale_range); + addFunction("sort_distance", this, &ScriptingObject::sort_distance); + addFunction("createKernel1", this, &ScriptingObject::createKernel1); addFunction("print", this, &ScriptingObject::print); } @@ -155,6 +207,64 @@ void ScriptingObject::shuffle_random(cppexpose::Object* obj) std::cerr << "Invalid kernel object in shuffle_random()" << std::endl; } +void ScriptingObject::scale_range(cppexpose::Object* obj, float toMin, float toMax, float fromMin, float fromMax) +{ + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::scale::range(kernelObj->kernel(), toMin, toMax, fromMin, fromMax); + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::scale::range(kernelObj->kernel(), toMin, toMax, fromMin, fromMax); + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::scale::range(kernelObj->kernel(), toMin, toMax, fromMin, fromMax); + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::scale::range(kernelObj->kernel(), toMin, toMax, fromMin, fromMax); + return; + } + + std::cerr << "Invalid kernel object in scale_range()" << std::endl; +} + +void ScriptingObject::sort_distance(cppexpose::Object* obj, float origin) +{ + if (auto kernelObj = dynamic_cast(obj)) + { + glkernel::sort::distance(kernelObj->kernel(), origin); + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + std::cerr << "Invalid origin in sort_distance(): float instead of vec2" << std::endl; + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + std::cerr << "Invalid origin in sort_distance(): float instead of vec3" << std::endl; + return; + } + + if (auto kernelObj = dynamic_cast(obj)) + { + std::cerr << "Invalid origin in sort_distance(): float instead of vec4" << std::endl; + return; + } + + std::cerr << "Invalid kernel object in scale_range()" << std::endl; +} + Kernel1Object::Kernel1Object(int width, int height, int depth) : Object() , m_kernel(width, height, depth) diff --git a/source/tools/glkernel-cli/scripting.h b/source/tools/glkernel-cli/scripting.h index f5c91cf..dc87d13 100644 --- a/source/tools/glkernel-cli/scripting.h +++ b/source/tools/glkernel-cli/scripting.h @@ -10,6 +10,9 @@ class ScriptingObject : public cppexpose::Object void uniform(cppexpose::Object* kernelObj, float range_min, float range_max); void shuffle_random(cppexpose::Object* kernelObj); + void scale_range(cppexpose::Object* kernelObj, float toMin, float toMax, float fromMin = 0.0f, float fromMax = 1.0f); + void sort_distance(cppexpose::Object* kernelObj, float origin); + cppexpose::Object* createKernel1(int width, int height, int depth); cppexpose::Object* createKernel2(int width, int height, int depth); cppexpose::Object* createKernel3(int width, int height, int depth); From bf0602092128f491b944b1269e4cfbdb12c8566a Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Wed, 10 Jan 2018 15:04:31 +0100 Subject: [PATCH 21/83] Rewrite kernel json export - unwrap kernel variant, and append values to array --- source/glkernel/CMakeLists.txt | 4 +- source/tools/glkernel-cli/KernelGenerator.cpp | 8 ++- .../glkernel-cli/export/KernelExporter.hpp | 7 +- .../export/KernelJsonExporter.cpp | 69 ++++++++++++++++--- .../export/KernelJsonExporter.hpp | 7 +- source/tools/glkernel-cli/main.cpp | 6 +- 6 files changed, 82 insertions(+), 19 deletions(-) diff --git a/source/glkernel/CMakeLists.txt b/source/glkernel/CMakeLists.txt index 3db89cb..80c7f05 100644 --- a/source/glkernel/CMakeLists.txt +++ b/source/glkernel/CMakeLists.txt @@ -16,7 +16,7 @@ set(target glkernel) # Exit here if required dependencies are not met message(STATUS "Lib ${target}") -# Set API export file and macro +# Set API exportKernel file and macro string(MAKE_C_IDENTIFIER ${target} target_id) string(TOUPPER ${target_id} target_id) set(feature_file "include/${target}/${target}_features.h") @@ -78,7 +78,7 @@ add_library(${META_PROJECT_NAME}::${target} ALIAS ${target}) # Export library for downstream projects export(TARGETS ${target} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target}/${target}-export.cmake) -# Create API export header +# Create API exportKernel header generate_template_export_header(${target} ${target_id} ${template_export_file} diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp index c158823..ab79dfa 100644 --- a/source/tools/glkernel-cli/KernelGenerator.cpp +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -1,6 +1,8 @@ #include "KernelGenerator.hpp" #include +#include +#include #include #include @@ -16,7 +18,11 @@ KernelGenerator::KernelGenerator(const std::string& inputFileName) cppexpose::Variant KernelGenerator::generateKernelFromJavascript() { - auto generatedKernel = glkernel::kernel4{}; // TODO generate from js scriptCode + // TODO generate from js scriptCode + + auto generatedKernel = glkernel::kernel2{ 3, 4, 5 }; + glkernel::noise::uniform(generatedKernel, 0.f, 1.f); + glkernel::sort::distance(generatedKernel, {0.0f, 0.0f}); return cppexpose::Variant::fromValue(generatedKernel); } diff --git a/source/tools/glkernel-cli/export/KernelExporter.hpp b/source/tools/glkernel-cli/export/KernelExporter.hpp index 7204b21..db51223 100644 --- a/source/tools/glkernel-cli/export/KernelExporter.hpp +++ b/source/tools/glkernel-cli/export/KernelExporter.hpp @@ -1,14 +1,17 @@ +#pragma once + #include #include #include -class KernelExporter { +class KernelExporter +{ public: KernelExporter(const cppexpose::Variant & kernelVariant, const std::string & outFileName) : m_kernel{kernelVariant}, m_outFileName{outFileName} {} - virtual void export() = 0; + virtual void exportKernel() = 0; protected: cppexpose::Variant m_kernel; std::string m_outFileName; diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp index 7434386..3bb065f 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp @@ -1,33 +1,84 @@ #include "KernelJsonExporter.hpp" +#include + #include #include +#include -void KernelJsonExporter::export() { +void KernelJsonExporter::exportKernel() { const auto jsonArray = toJsonArray(m_kernel); writeToFile(jsonArray); } -cppexpose::Variant KernelJsonExporter::toJsonArray(const cppexpose::Variant & kernel) { +cppexpose::Variant KernelJsonExporter::toJsonArray(const cppexpose::Variant & kernelVariant) { + + auto kernelArray = cppexpose::Variant::array(); - /* TODO convert kernel to json-stringifyable variant array - * check kernel.hasType, and build corresponding appendComponentToVariantArray lambda - */ + if (kernelVariant.hasType()) + { + auto kernel = kernelVariant.value(); + std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec4 & component) { + this->appendFloatValues(kernelArray.asArray(), component.x, component.y, component.z, component.w); + }); + } + else if (kernelVariant.hasType()) + { + auto kernel = kernelVariant.value(); + std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec3 & component) { + this->appendFloatValues(kernelArray.asArray(), component.x, component.y, component.z); + }); + } + else if (kernelVariant.hasType()) + { + auto kernel = kernelVariant.value(); + std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec2 & component) { + this->appendFloatValues(kernelArray.asArray(), component.x, component.y); + }); + } + else if (kernelVariant.hasType()) + { + auto kernel = kernelVariant.value(); + std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const float component) { + this->appendFloatValues(kernelArray.asArray(), component); + }); + } + else + { + cppassist::error() << "Unknown kernel type found. Aborting..."; + return cppexpose::Variant::fromValue(glkernel::kernel1{ }); + } + + cppexpose::Variant result = cppexpose::Variant::map(); + cppexpose::Variant size = cppexpose::Variant::map(); + + size.asMap()->emplace("height", 1); // TODO actual values + size.asMap()->emplace("width", 1); + size.asMap()->emplace("depth", 1); + + result.asMap()->emplace("size", size); + result.asMap()->emplace("kernel", kernelArray); + + return result; +} + +void KernelJsonExporter::appendFloatValues(cppexpose::VariantArray * kernelArray, const float toAppend, ...) { + kernelArray->insert(kernelArray->end(), { toAppend }); +} - return cppexpose::Variant::fromValue(glkernel::kernel4{ }); +void KernelJsonExporter::appendDoubleValues(cppexpose::VariantArray * kernelArray, const double toAppend, ...) { + kernelArray->insert(kernelArray->end(), { toAppend }); } void KernelJsonExporter::writeToFile(const cppexpose::Variant & jsonArray) { - // TODO: check if file exists - // if (!force && fileExists(outFileName)) { std::cerr << "... / throw? std::ofstream outStream(m_outFileName); if (!outStream.is_open()) { - // TODO exception instead? std::cerr << "ERROR: Output file could not be created. Aborting..." << std::endl; + return; } outStream << stringify(jsonArray) << std::endl; diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp index b90c170..9850daf 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp @@ -6,10 +6,13 @@ class KernelJsonExporter : public KernelExporter { KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName) : KernelExporter{kernel, outFileName} {} - void export() override; + void exportKernel() override; protected: - cppexpose::Variant toJsonArray(const cppexpose::Variant & kernel); + cppexpose::Variant toJsonArray(const cppexpose::Variant & kernelVariant); void writeToFile(const cppexpose::Variant & jsonArray); std::string stringify(const cppexpose::Variant & jsonArray); + + void appendFloatValues(cppexpose::VariantArray *kernelArray, float toAppend, ...); + void appendDoubleValues(cppexpose::VariantArray *kernelArray, double toAppend, ...); }; diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index 0349238..ca59262 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -14,8 +14,8 @@ #include #include "KernelGenerator.hpp" -#include "export/KernelExporter.hpp -#include "export/KernelJsonExporter.hpp +#include "export/KernelExporter.hpp" +#include "export/KernelJsonExporter.hpp" std::string extractInputFormat(const std::string & inFileName) { @@ -154,7 +154,7 @@ int main(int argc, char* argv[]) auto kernelGenerator = KernelGenerator{inputFile}; auto kernelVariant = kernelGenerator.generateKernelFromJavascript(); auto kernelExporter = KernelJsonExporter{kernelVariant, outputFile}; - kernelExporter.export(); + kernelExporter.exportKernel(); } return 0; From c1e4b27449bdf6aa353be41ebbe3dfda42a92b5f Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Thu, 11 Jan 2018 10:44:39 +0100 Subject: [PATCH 22/83] Use initializer_list instead of variadic arguments in appendFloatValues --- .../glkernel-cli/export/KernelJsonExporter.cpp | 18 +++++++++--------- .../glkernel-cli/export/KernelJsonExporter.hpp | 3 +-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp index 3bb065f..b95466f 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp @@ -20,28 +20,28 @@ cppexpose::Variant KernelJsonExporter::toJsonArray(const cppexpose::Variant & ke { auto kernel = kernelVariant.value(); std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec4 & component) { - this->appendFloatValues(kernelArray.asArray(), component.x, component.y, component.z, component.w); + this->appendFloatValues(kernelArray.asArray(), { component.x, component.y, component.z, component.w }); }); } else if (kernelVariant.hasType()) { auto kernel = kernelVariant.value(); std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec3 & component) { - this->appendFloatValues(kernelArray.asArray(), component.x, component.y, component.z); + this->appendFloatValues(kernelArray.asArray(), { component.x, component.y, component.z }); }); } else if (kernelVariant.hasType()) { auto kernel = kernelVariant.value(); std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec2 & component) { - this->appendFloatValues(kernelArray.asArray(), component.x, component.y); + this->appendFloatValues(kernelArray.asArray(), { component.x, component.y }); }); } else if (kernelVariant.hasType()) { auto kernel = kernelVariant.value(); std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const float component) { - this->appendFloatValues(kernelArray.asArray(), component); + this->appendFloatValues(kernelArray.asArray(), { component }); }); } else @@ -63,12 +63,12 @@ cppexpose::Variant KernelJsonExporter::toJsonArray(const cppexpose::Variant & ke return result; } -void KernelJsonExporter::appendFloatValues(cppexpose::VariantArray * kernelArray, const float toAppend, ...) { - kernelArray->insert(kernelArray->end(), { toAppend }); -} +void KernelJsonExporter::appendFloatValues(cppexpose::VariantArray * kernelArray, std::initializer_list component) { + auto componentArrayVariant = cppexpose::Variant::array(); + auto componentArray = componentArrayVariant.asArray(); + componentArray->insert(componentArray->end(), component.begin(), component.end()); + kernelArray->push_back(componentArrayVariant); -void KernelJsonExporter::appendDoubleValues(cppexpose::VariantArray * kernelArray, const double toAppend, ...) { - kernelArray->insert(kernelArray->end(), { toAppend }); } diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp index 9850daf..4035e8a 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp @@ -13,6 +13,5 @@ class KernelJsonExporter : public KernelExporter { void writeToFile(const cppexpose::Variant & jsonArray); std::string stringify(const cppexpose::Variant & jsonArray); - void appendFloatValues(cppexpose::VariantArray *kernelArray, float toAppend, ...); - void appendDoubleValues(cppexpose::VariantArray *kernelArray, double toAppend, ...); + void appendFloatValues(cppexpose::VariantArray *kernelArray, std::initializer_list component); }; From 3af2bcc9f5614261e81ad50a81664350dd2e98aa Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Sat, 13 Jan 2018 14:51:38 +0100 Subject: [PATCH 23/83] Rewrite KernelJsonExporter using tkernel cell templates --- .../export/KernelJsonExporter.cpp | 106 +++++++++++++----- .../export/KernelJsonExporter.hpp | 10 +- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp index b95466f..60e18e0 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.cpp @@ -6,6 +6,41 @@ #include #include +void appendCell(cppexpose::VariantArray *kernelArray, std::initializer_list cell) { + auto componentArrayVariant = cppexpose::Variant::array(); + auto componentArray = componentArrayVariant.asArray(); + componentArray->insert(componentArray->end(), cell.begin(), cell.end()); + kernelArray->push_back(componentArrayVariant); +} + +template +void appendCell(cppexpose::VariantArray * widthArray, const T & cell); + +template <> +void appendCell(cppexpose::VariantArray * widthArray, const glm::vec4 & cell) +{ + appendCell(widthArray, {cell.x, cell.y, cell.z, cell.w}); +} + +template <> +void appendCell(cppexpose::VariantArray * widthArray, const glm::vec3 & cell) +{ + appendCell(widthArray, {cell.x, cell.y, cell.z}); +} + +template <> +void appendCell(cppexpose::VariantArray * widthArray, const glm::vec2 & cell) +{ + appendCell(widthArray, {cell.x, cell.y}); +} + +template <> +void appendCell(cppexpose::VariantArray * widthArray, const float & cell) +{ + widthArray->push_back(cell); +} + + void KernelJsonExporter::exportKernel() { const auto jsonArray = toJsonArray(m_kernel); @@ -14,61 +49,73 @@ void KernelJsonExporter::exportKernel() { cppexpose::Variant KernelJsonExporter::toJsonArray(const cppexpose::Variant & kernelVariant) { - auto kernelArray = cppexpose::Variant::array(); - if (kernelVariant.hasType()) { - auto kernel = kernelVariant.value(); - std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec4 & component) { - this->appendFloatValues(kernelArray.asArray(), { component.x, component.y, component.z, component.w }); - }); + return toJsonArray(kernelVariant.value()); } else if (kernelVariant.hasType()) { - auto kernel = kernelVariant.value(); - std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec3 & component) { - this->appendFloatValues(kernelArray.asArray(), { component.x, component.y, component.z }); - }); + return toJsonArray(kernelVariant.value()); } else if (kernelVariant.hasType()) { - auto kernel = kernelVariant.value(); - std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const glm::vec2 & component) { - this->appendFloatValues(kernelArray.asArray(), { component.x, component.y }); - }); + return toJsonArray(kernelVariant.value()); } else if (kernelVariant.hasType()) { - auto kernel = kernelVariant.value(); - std::for_each(kernel.cbegin(), kernel.cend(), [&kernelArray, this](const float component) { - this->appendFloatValues(kernelArray.asArray(), { component }); - }); + return toJsonArray(kernelVariant.value()); } else { cppassist::error() << "Unknown kernel type found. Aborting..."; return cppexpose::Variant::fromValue(glkernel::kernel1{ }); } +} - cppexpose::Variant result = cppexpose::Variant::map(); - cppexpose::Variant size = cppexpose::Variant::map(); +template +cppexpose::Variant KernelJsonExporter::toJsonArray(const glkernel::tkernel & kernel) +{ + auto kernelArray = cppexpose::Variant::array(); - size.asMap()->emplace("height", 1); // TODO actual values - size.asMap()->emplace("width", 1); - size.asMap()->emplace("depth", 1); + for (auto z = 0; z < kernel.depth(); ++z) + { + auto heightArray = cppexpose::Variant::array(); + + for (auto y = 0; y < kernel.height(); ++y) + { + auto widthArray = cppexpose::Variant::array(); + + for (auto x = 0; x < kernel.width(); ++x) + { + const T& cell = kernel.value(x, y, z); + appendCell(widthArray.asArray(), cell); + } + heightArray.asArray()->push_back(widthArray); + } + kernelArray.asArray()->push_back(heightArray); + } - result.asMap()->emplace("size", size); + + auto result = prepareResult(kernel); result.asMap()->emplace("kernel", kernelArray); return result; } -void KernelJsonExporter::appendFloatValues(cppexpose::VariantArray * kernelArray, std::initializer_list component) { - auto componentArrayVariant = cppexpose::Variant::array(); - auto componentArray = componentArrayVariant.asArray(); - componentArray->insert(componentArray->end(), component.begin(), component.end()); - kernelArray->push_back(componentArrayVariant); +template +cppexpose::Variant KernelJsonExporter::prepareResult(const glkernel::tkernel & kernel) +{ + cppexpose::Variant result = cppexpose::Variant::map(); + cppexpose::Variant size = cppexpose::Variant::map(); + + size.asMap()->emplace("width", kernel.width()); + size.asMap()->emplace("height", kernel.height()); + size.asMap()->emplace("depth", kernel.depth()); + + result.asMap()->emplace("size", size); + + return result; } @@ -84,6 +131,7 @@ void KernelJsonExporter::writeToFile(const cppexpose::Variant & jsonArray) { outStream << stringify(jsonArray) << std::endl; } + std::string KernelJsonExporter::stringify(const cppexpose::Variant &array) { return cppexpose::JSON::stringify(array, cppexpose::JSON::OutputMode::Beautify); } diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp index 4035e8a..816cedd 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp +++ b/source/tools/glkernel-cli/export/KernelJsonExporter.hpp @@ -10,8 +10,14 @@ class KernelJsonExporter : public KernelExporter { protected: cppexpose::Variant toJsonArray(const cppexpose::Variant & kernelVariant); + + template + cppexpose::Variant toJsonArray(const glkernel::tkernel & kernel); + + template + cppexpose::Variant prepareResult(const glkernel::tkernel &kernel); + void writeToFile(const cppexpose::Variant & jsonArray); - std::string stringify(const cppexpose::Variant & jsonArray); - void appendFloatValues(cppexpose::VariantArray *kernelArray, std::initializer_list component); + std::string stringify(const cppexpose::Variant & jsonArray); }; From 707eab27e3503caa3768867a2c73a5c6f278e49a Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Sat, 13 Jan 2018 14:54:36 +0100 Subject: [PATCH 24/83] Undo automatic renaming mistake --- source/glkernel/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/glkernel/CMakeLists.txt b/source/glkernel/CMakeLists.txt index 80c7f05..3db89cb 100644 --- a/source/glkernel/CMakeLists.txt +++ b/source/glkernel/CMakeLists.txt @@ -16,7 +16,7 @@ set(target glkernel) # Exit here if required dependencies are not met message(STATUS "Lib ${target}") -# Set API exportKernel file and macro +# Set API export file and macro string(MAKE_C_IDENTIFIER ${target} target_id) string(TOUPPER ${target_id} target_id) set(feature_file "include/${target}/${target}_features.h") @@ -78,7 +78,7 @@ add_library(${META_PROJECT_NAME}::${target} ALIAS ${target}) # Export library for downstream projects export(TARGETS ${target} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target}/${target}-export.cmake) -# Create API exportKernel header +# Create API export header generate_template_export_header(${target} ${target_id} ${template_export_file} From 898c22044e1124c583630d0970ffec9e72a851cc Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Sat, 13 Jan 2018 15:47:28 +0100 Subject: [PATCH 25/83] Connect scripting and json export in first example --- source/tools/glkernel-cli/KernelGenerator.cpp | 99 ++++++++++++++++++- source/tools/glkernel-cli/main.cpp | 2 - source/tools/glkernel-cli/scripting.cpp | 99 ++----------------- source/tools/glkernel-cli/scripting.h | 2 +- 4 files changed, 105 insertions(+), 97 deletions(-) diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp index ab79dfa..2ec0c4b 100644 --- a/source/tools/glkernel-cli/KernelGenerator.cpp +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -1,7 +1,9 @@ #include "KernelGenerator.hpp" +#include "scripting.h" #include #include + #include #include @@ -18,11 +20,98 @@ KernelGenerator::KernelGenerator(const std::string& inputFileName) cppexpose::Variant KernelGenerator::generateKernelFromJavascript() { - // TODO generate from js scriptCode + // TODO use m_scriptCode + auto script = R"javascript( + var _Kernel = function(x,y,z) { + this._initialize = function(x,y,z) { + var that = this; + + this.kernel = this.generateKernel(x,y,z); + + this.sequence = { + uniform: function(min, max) { + _glkernel.uniform(that.kernel, min, max); + } + }; + this.shuffle = { + random: function() { + _glkernel.shuffle_random(that.kernel); + } + }; + this.scale = { + range: function(toMin, toMax, fromMin, fromMax) { + // Defining default values for some parameters + fromMin = (typeof fromMin !== 'undefined') ? fromMin : 0.0; + fromMax = (typeof fromMax !== 'undefined') ? fromMax : 1.0; + + _glkernel.scale_range(that.kernel, toMin, toMax, fromMin, fromMax); + } + }; + this.sort = { + distance: function(origin) { + _glkernel.sort_distance(that.kernel, origin); + } + }; + }; + }; + + var Kernel1 = function(x,y,z) { + this.generateKernel = function(x,y,z) { + return _glkernel.createKernel1(x,y,z); + } + this._initialize(x,y,z); + } + + Kernel1.prototype = new _Kernel; + + // Done with preparation + + var kernel = new Kernel1(10, 1, 1); + + kernel.sequence.uniform(0.0, 1.0); + kernel.shuffle.random(); + kernel.scale.range(-1,1); + kernel.sort.distance(0); + + f = function(arg) { + if (typeof arg === "number") + return "float"; + + if (typeof arg === "object") { + var keys = Object.keys(arg); + if ("0" in keys && typeof arg[0] === "number") { + if ("1" in keys && typeof arg[1] === "number") { + if ("2" in keys && typeof arg[2] === "number") { + if ("3" in keys && typeof arg[3] === "number") + return "vec4"; + else + return "vec3"; + } + else + return "vec2"; + } + else + return "vec1"; + } + } + + return "unknown"; + } + + _glkernel.print(f(1)); // float + _glkernel.print(f([1])); // vec1 + _glkernel.print(f([1,2])); // vec2 + _glkernel.print(f([1,2,3])); // vec3 + _glkernel.print(f([1,2,3,4])); // vec4 + _glkernel.print(f(["wrong"])); // unknown + _glkernel.print(f([1,2,"wrong later"])); // vec2 + _glkernel.print(f("completely wrong")); // unknown + + kernel.kernel; + + )javascript"; - auto generatedKernel = glkernel::kernel2{ 3, 4, 5 }; - glkernel::noise::uniform(generatedKernel, 0.f, 1.f); - glkernel::sort::distance(generatedKernel, {0.0f, 0.0f}); - return cppexpose::Variant::fromValue(generatedKernel); + auto generatedKernel = executeScript(script); + return generatedKernel; } diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index cedaea0..913ae0a 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -178,7 +178,5 @@ int main(int argc, char* argv[]) } } - doScripting(); - return 0; } diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index 232964d..a794655 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -10,7 +10,7 @@ #include #include -void doScripting() +cppexpose::Variant executeScript(const std::string & script) { ScriptingObject obj; @@ -20,96 +20,17 @@ void doScripting() std::cerr << msg << std::endl; }); - auto script = R"javascript( - var _Kernel = function(x,y,z) { - this._initialize = function(x,y,z) { - var that = this; - - this.kernel = this.generateKernel(x,y,z); - - this.sequence = { - uniform: function(min, max) { - _glkernel.uniform(that.kernel, min, max); - } - }; - this.shuffle = { - random: function() { - _glkernel.shuffle_random(that.kernel); - } - }; - this.scale = { - range: function(toMin, toMax, fromMin, fromMax) { - // Defining default values for some parameters - fromMin = (typeof fromMin !== 'undefined') ? fromMin : 0.0; - fromMax = (typeof fromMax !== 'undefined') ? fromMax : 1.0; - - _glkernel.scale_range(that.kernel, toMin, toMax, fromMin, fromMax); - } - }; - this.sort = { - distance: function(origin) { - _glkernel.sort_distance(that.kernel, origin); - } - }; - }; - }; - - var Kernel1 = function(x,y,z) { - this.generateKernel = function(x,y,z) { - return _glkernel.createKernel1(x,y,z); - } - this._initialize(x,y,z); - } - - Kernel1.prototype = new _Kernel; - - // Done with preparation - - var kernel = new Kernel1(10, 1, 1); - - kernel.sequence.uniform(0.0, 1.0); - kernel.shuffle.random(); - kernel.scale.range(-1,1); - kernel.sort.distance(0); - - f = function(arg) { - if (typeof arg === "number") - return "float"; - - if (typeof arg === "object") { - var keys = Object.keys(arg); - if ("0" in keys && typeof arg[0] === "number") { - if ("1" in keys && typeof arg[1] === "number") { - if ("2" in keys && typeof arg[2] === "number") { - if ("3" in keys && typeof arg[3] === "number") - return "vec4"; - else - return "vec3"; - } - else - return "vec2"; - } - else - return "vec1"; - } - } - - return "unknown"; - } - - _glkernel.print(f(1)); // float - _glkernel.print(f([1])); // vec1 - _glkernel.print(f([1,2])); // vec2 - _glkernel.print(f([1,2,3])); // vec3 - _glkernel.print(f([1,2,3,4])); // vec4 - _glkernel.print(f(["wrong"])); // unknown - _glkernel.print(f([1,2,"wrong later"])); // vec2 - _glkernel.print(f("completely wrong")); // unknown - - )javascript"; + auto variant = scriptContext.evaluate(script); - std::cout << variant.toString(); + std::cout << variant.type().name() << std::endl; + if (variant.hasType()) + { + auto kernelObject = variant.value(); + auto kernel1Object = dynamic_cast(kernelObject); + return cppexpose::Variant::fromValue(kernel1Object->kernel()); + } + return variant; } ScriptingObject::ScriptingObject() diff --git a/source/tools/glkernel-cli/scripting.h b/source/tools/glkernel-cli/scripting.h index dc87d13..e77a544 100644 --- a/source/tools/glkernel-cli/scripting.h +++ b/source/tools/glkernel-cli/scripting.h @@ -61,4 +61,4 @@ class Kernel4Object : public cppexpose::Object glkernel::kernel4 m_kernel; }; -void doScripting(); +cppexpose::Variant executeScript(const std::string & script); From 1933908af7026bd9cda43c34eee3f999b4164181 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Sat, 13 Jan 2018 15:53:27 +0100 Subject: [PATCH 26/83] Add createKernel{2,3,4} --- source/tools/glkernel-cli/KernelGenerator.cpp | 5 +---- source/tools/glkernel-cli/scripting.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp index 2ec0c4b..acb8382 100644 --- a/source/tools/glkernel-cli/KernelGenerator.cpp +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -3,7 +3,6 @@ #include #include - #include #include @@ -111,7 +110,5 @@ cppexpose::Variant KernelGenerator::generateKernelFromJavascript() )javascript"; - - auto generatedKernel = executeScript(script); - return generatedKernel; + return executeScript(script); } diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index a794655..16e9492 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -20,8 +20,6 @@ cppexpose::Variant executeScript(const std::string & script) std::cerr << msg << std::endl; }); - - auto variant = scriptContext.evaluate(script); std::cout << variant.type().name() << std::endl; if (variant.hasType()) @@ -42,6 +40,10 @@ ScriptingObject::ScriptingObject() addFunction("sort_distance", this, &ScriptingObject::sort_distance); addFunction("createKernel1", this, &ScriptingObject::createKernel1); + addFunction("createKernel2", this, &ScriptingObject::createKernel2); + addFunction("createKernel3", this, &ScriptingObject::createKernel3); + addFunction("createKernel4", this, &ScriptingObject::createKernel4); + addFunction("print", this, &ScriptingObject::print); } @@ -229,4 +231,3 @@ glkernel::kernel4& Kernel4Object::kernel() { return m_kernel; } - From 4118ad166ede2bfb3e3f61cc8f3e99cbef053867 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Sat, 13 Jan 2018 15:56:45 +0100 Subject: [PATCH 27/83] Use kernel2 and different dimensions to test them --- source/tools/glkernel-cli/KernelGenerator.cpp | 11 ++++++++++- source/tools/glkernel-cli/scripting.cpp | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp index acb8382..b5d8563 100644 --- a/source/tools/glkernel-cli/KernelGenerator.cpp +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -63,9 +63,18 @@ cppexpose::Variant KernelGenerator::generateKernelFromJavascript() Kernel1.prototype = new _Kernel; + var Kernel2 = function(x,y,z) { + this.generateKernel = function(x,y,z) { + return _glkernel.createKernel2(x,y,z); + } + this._initialize(x,y,z); + } + + Kernel2.prototype = new _Kernel; + // Done with preparation - var kernel = new Kernel1(10, 1, 1); + var kernel = new Kernel2(10, 5, 2); kernel.sequence.uniform(0.0, 1.0); kernel.shuffle.random(); diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index 16e9492..27d9ce1 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -25,8 +25,18 @@ cppexpose::Variant executeScript(const std::string & script) if (variant.hasType()) { auto kernelObject = variant.value(); + auto kernel1Object = dynamic_cast(kernelObject); - return cppexpose::Variant::fromValue(kernel1Object->kernel()); + if (kernel1Object) + { + cppexpose::Variant::fromValue(kernel1Object->kernel()); + } + + auto kernel2Object = dynamic_cast(kernelObject); + if (kernel2Object) + { + cppexpose::Variant::fromValue(kernel2Object->kernel()); + } } return variant; } From 57d2aca7ea00aadf84fcdcf855681b6b5bf49599 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 15 Jan 2018 16:21:24 +0100 Subject: [PATCH 28/83] Remove debugging print, return variants in scripting --- source/tools/glkernel-cli/scripting.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/tools/glkernel-cli/scripting.cpp b/source/tools/glkernel-cli/scripting.cpp index 27d9ce1..8394680 100644 --- a/source/tools/glkernel-cli/scripting.cpp +++ b/source/tools/glkernel-cli/scripting.cpp @@ -21,7 +21,7 @@ cppexpose::Variant executeScript(const std::string & script) }); auto variant = scriptContext.evaluate(script); - std::cout << variant.type().name() << std::endl; + if (variant.hasType()) { auto kernelObject = variant.value(); @@ -29,13 +29,13 @@ cppexpose::Variant executeScript(const std::string & script) auto kernel1Object = dynamic_cast(kernelObject); if (kernel1Object) { - cppexpose::Variant::fromValue(kernel1Object->kernel()); + return cppexpose::Variant::fromValue(kernel1Object->kernel()); } auto kernel2Object = dynamic_cast(kernelObject); if (kernel2Object) { - cppexpose::Variant::fromValue(kernel2Object->kernel()); + return cppexpose::Variant::fromValue(kernel2Object->kernel()); } } return variant; From 4c309bba693eecc2ce121539d1738541ee9bbdb6 Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 15 Jan 2018 16:24:58 +0100 Subject: [PATCH 29/83] Rename KernelExporter, fix comma in description, remove export folder, rename .hpp files to .h --- .../KernelExporter.hpp => AbstractKernelExporter.h} | 4 ++-- source/tools/glkernel-cli/CMakeLists.txt | 8 ++++---- source/tools/glkernel-cli/KernelGenerator.cpp | 2 +- .../{KernelGenerator.hpp => KernelGenerator.h} | 0 .../glkernel-cli/{export => }/KernelJsonExporter.cpp | 2 +- .../KernelJsonExporter.hpp => KernelJsonExporter.h} | 6 +++--- source/tools/glkernel-cli/main.cpp | 8 ++++---- 7 files changed, 15 insertions(+), 15 deletions(-) rename source/tools/glkernel-cli/{export/KernelExporter.hpp => AbstractKernelExporter.h} (68%) rename source/tools/glkernel-cli/{KernelGenerator.hpp => KernelGenerator.h} (100%) rename source/tools/glkernel-cli/{export => }/KernelJsonExporter.cpp (99%) rename source/tools/glkernel-cli/{export/KernelJsonExporter.hpp => KernelJsonExporter.h} (79%) diff --git a/source/tools/glkernel-cli/export/KernelExporter.hpp b/source/tools/glkernel-cli/AbstractKernelExporter.h similarity index 68% rename from source/tools/glkernel-cli/export/KernelExporter.hpp rename to source/tools/glkernel-cli/AbstractKernelExporter.h index db51223..28e39c3 100644 --- a/source/tools/glkernel-cli/export/KernelExporter.hpp +++ b/source/tools/glkernel-cli/AbstractKernelExporter.h @@ -5,10 +5,10 @@ #include -class KernelExporter +class AbstractKernelExporter { public: - KernelExporter(const cppexpose::Variant & kernelVariant, const std::string & outFileName) : + AbstractKernelExporter(const cppexpose::Variant & kernelVariant, const std::string & outFileName) : m_kernel{kernelVariant}, m_outFileName{outFileName} {} virtual void exportKernel() = 0; diff --git a/source/tools/glkernel-cli/CMakeLists.txt b/source/tools/glkernel-cli/CMakeLists.txt index 79fbad2..69c7e83 100644 --- a/source/tools/glkernel-cli/CMakeLists.txt +++ b/source/tools/glkernel-cli/CMakeLists.txt @@ -19,14 +19,14 @@ set(target glkernel-cli) # set(headers - export/KernelExporter.hpp - export/KernelJsonExporter.hpp - KernelGenerator.hpp + AbstractKernelExporter.h + KernelJsonExporter.h + KernelGenerator.h ) set(sources main.cpp - export/KernelJsonExporter.cpp + KernelJsonExporter.cpp KernelGenerator.cpp ) diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp index ab79dfa..1b5a1d0 100644 --- a/source/tools/glkernel-cli/KernelGenerator.cpp +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -1,4 +1,4 @@ -#include "KernelGenerator.hpp" +#include "KernelGenerator.h" #include #include diff --git a/source/tools/glkernel-cli/KernelGenerator.hpp b/source/tools/glkernel-cli/KernelGenerator.h similarity index 100% rename from source/tools/glkernel-cli/KernelGenerator.hpp rename to source/tools/glkernel-cli/KernelGenerator.h diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp b/source/tools/glkernel-cli/KernelJsonExporter.cpp similarity index 99% rename from source/tools/glkernel-cli/export/KernelJsonExporter.cpp rename to source/tools/glkernel-cli/KernelJsonExporter.cpp index 60e18e0..e6d8471 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.cpp +++ b/source/tools/glkernel-cli/KernelJsonExporter.cpp @@ -1,4 +1,4 @@ -#include "KernelJsonExporter.hpp" +#include "KernelJsonExporter.h" #include diff --git a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp b/source/tools/glkernel-cli/KernelJsonExporter.h similarity index 79% rename from source/tools/glkernel-cli/export/KernelJsonExporter.hpp rename to source/tools/glkernel-cli/KernelJsonExporter.h index 816cedd..5d63295 100644 --- a/source/tools/glkernel-cli/export/KernelJsonExporter.hpp +++ b/source/tools/glkernel-cli/KernelJsonExporter.h @@ -1,10 +1,10 @@ -#include "KernelExporter.hpp" +#include "AbstractKernelExporter.h" -class KernelJsonExporter : public KernelExporter { +class KernelJsonExporter : public AbstractKernelExporter { protected: public: KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName) : - KernelExporter{kernel, outFileName} {} + AbstractKernelExporter{kernel, outFileName} {} void exportKernel() override; diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index ca59262..b2179a9 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -13,9 +13,9 @@ #include #include -#include "KernelGenerator.hpp" -#include "export/KernelExporter.hpp" -#include "export/KernelJsonExporter.hpp" +#include "KernelGenerator.h" +#include "AbstractKernelExporter.h" +#include "KernelJsonExporter.h" std::string extractInputFormat(const std::string & inFileName) { @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) "--format", "-f", "outputFileFormat", - "File format for the generated / converted kernel (e.g. .json, .png, .h)", + "File format for the generated / converted kernel (e.g., json, png, h)", cppassist::CommandLineOption::Optional }; From 4eb2e29d3e87ae3d2e3c1b7070f6350ba2e2fac5 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Mon, 15 Jan 2018 16:25:56 +0100 Subject: [PATCH 30/83] Replace hardcoded script with loaded script from js file --- scripts/kernel.js | 8 +++ source/tools/glkernel-cli/KernelGenerator.cpp | 52 ++----------------- 2 files changed, 11 insertions(+), 49 deletions(-) create mode 100644 scripts/kernel.js diff --git a/scripts/kernel.js b/scripts/kernel.js new file mode 100644 index 0000000..375ed60 --- /dev/null +++ b/scripts/kernel.js @@ -0,0 +1,8 @@ +var kernel = new Kernel2(10, 5, 2); + +kernel.sequence.uniform(0.0, 1.0); +kernel.shuffle.random(); +kernel.scale.range(-1,1); +kernel.sort.distance(0); + +kernel.kernel diff --git a/source/tools/glkernel-cli/KernelGenerator.cpp b/source/tools/glkernel-cli/KernelGenerator.cpp index b5d8563..4c0c1b7 100644 --- a/source/tools/glkernel-cli/KernelGenerator.cpp +++ b/source/tools/glkernel-cli/KernelGenerator.cpp @@ -19,8 +19,8 @@ KernelGenerator::KernelGenerator(const std::string& inputFileName) cppexpose::Variant KernelGenerator::generateKernelFromJavascript() { - // TODO use m_scriptCode - auto script = R"javascript( + // TODO: replace API string with pregenerated API JS file + auto api = R"javascript( var _Kernel = function(x,y,z) { this._initialize = function(x,y,z) { var that = this; @@ -71,53 +71,7 @@ cppexpose::Variant KernelGenerator::generateKernelFromJavascript() } Kernel2.prototype = new _Kernel; - - // Done with preparation - - var kernel = new Kernel2(10, 5, 2); - - kernel.sequence.uniform(0.0, 1.0); - kernel.shuffle.random(); - kernel.scale.range(-1,1); - kernel.sort.distance(0); - - f = function(arg) { - if (typeof arg === "number") - return "float"; - - if (typeof arg === "object") { - var keys = Object.keys(arg); - if ("0" in keys && typeof arg[0] === "number") { - if ("1" in keys && typeof arg[1] === "number") { - if ("2" in keys && typeof arg[2] === "number") { - if ("3" in keys && typeof arg[3] === "number") - return "vec4"; - else - return "vec3"; - } - else - return "vec2"; - } - else - return "vec1"; - } - } - - return "unknown"; - } - - _glkernel.print(f(1)); // float - _glkernel.print(f([1])); // vec1 - _glkernel.print(f([1,2])); // vec2 - _glkernel.print(f([1,2,3])); // vec3 - _glkernel.print(f([1,2,3,4])); // vec4 - _glkernel.print(f(["wrong"])); // unknown - _glkernel.print(f([1,2,"wrong later"])); // vec2 - _glkernel.print(f("completely wrong")); // unknown - - kernel.kernel; - )javascript"; - return executeScript(script); + return executeScript(api + m_scriptCode); } From b75b9cbb57f92c4b5b5e5967c826a2e2f8f7449b Mon Sep 17 00:00:00 2001 From: Jonas Beyer Date: Mon, 15 Jan 2018 16:39:59 +0100 Subject: [PATCH 31/83] Add beautify switch, adapt stringify method --- source/tools/glkernel-cli/KernelJsonExporter.cpp | 5 ++++- source/tools/glkernel-cli/KernelJsonExporter.h | 6 ++++-- source/tools/glkernel-cli/main.cpp | 10 +++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/tools/glkernel-cli/KernelJsonExporter.cpp b/source/tools/glkernel-cli/KernelJsonExporter.cpp index e6d8471..858edcd 100644 --- a/source/tools/glkernel-cli/KernelJsonExporter.cpp +++ b/source/tools/glkernel-cli/KernelJsonExporter.cpp @@ -133,5 +133,8 @@ void KernelJsonExporter::writeToFile(const cppexpose::Variant & jsonArray) { std::string KernelJsonExporter::stringify(const cppexpose::Variant &array) { - return cppexpose::JSON::stringify(array, cppexpose::JSON::OutputMode::Beautify); + auto outputMode = m_beautify + ? cppexpose::JSON::OutputMode::Beautify + : cppexpose::JSON::OutputMode::Compact; + return cppexpose::JSON::stringify(array, outputMode); } diff --git a/source/tools/glkernel-cli/KernelJsonExporter.h b/source/tools/glkernel-cli/KernelJsonExporter.h index 5d63295..5a6f2d1 100644 --- a/source/tools/glkernel-cli/KernelJsonExporter.h +++ b/source/tools/glkernel-cli/KernelJsonExporter.h @@ -3,8 +3,8 @@ class KernelJsonExporter : public AbstractKernelExporter { protected: public: - KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName) : - AbstractKernelExporter{kernel, outFileName} {} + KernelJsonExporter(const cppexpose::Variant & kernel, const std::string & outFileName, const bool beautify) : + AbstractKernelExporter{kernel, outFileName}, m_beautify{beautify} {} void exportKernel() override; @@ -20,4 +20,6 @@ class KernelJsonExporter : public AbstractKernelExporter { void writeToFile(const cppexpose::Variant & jsonArray); std::string stringify(const cppexpose::Variant & jsonArray); + + bool m_beautify; }; diff --git a/source/tools/glkernel-cli/main.cpp b/source/tools/glkernel-cli/main.cpp index b2179a9..7b572a4 100644 --- a/source/tools/glkernel-cli/main.cpp +++ b/source/tools/glkernel-cli/main.cpp @@ -95,10 +95,18 @@ int main(int argc, char* argv[]) cppassist::CommandLineSwitch::Optional }; + auto swBeautify = cppassist::CommandLineSwitch{ + "--beautify", + "-b", + "Beautify the output (only applies to json output format)", + cppassist::CommandLineSwitch::Optional + }; + actionRun.add(¶mInputFile); actionRun.add(&optOutputFile); actionRun.add(&optOutputFormat); actionRun.add(&swForce); + actionRun.add(&swBeautify); program.add(&actionRun); @@ -153,7 +161,7 @@ int main(int argc, char* argv[]) auto kernelGenerator = KernelGenerator{inputFile}; auto kernelVariant = kernelGenerator.generateKernelFromJavascript(); - auto kernelExporter = KernelJsonExporter{kernelVariant, outputFile}; + auto kernelExporter = KernelJsonExporter{kernelVariant, outputFile, swBeautify.activated()}; kernelExporter.exportKernel(); } From 92196cbbc512644ade30e7391651d58568bf3a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kn=C3=B6schke?= Date: Mon, 15 Jan 2018 17:02:29 +0100 Subject: [PATCH 32/83] WIP: Code generation JS done (hopefully) C++ to do --- scripts/generate.py | 294 +++++++++++++++++++++++++++++++++++ scripts/glkernel.js.template | 44 ++++++ 2 files changed, 338 insertions(+) create mode 100644 scripts/generate.py create mode 100644 scripts/glkernel.js.template diff --git a/scripts/generate.py b/scripts/generate.py new file mode 100644 index 0000000..40f51d7 --- /dev/null +++ b/scripts/generate.py @@ -0,0 +1,294 @@ +from pathlib import Path +import re + +# TODOs: +# (more TODOs in code) + +# ------------ +# large-scale parsing + +def findPairedBrace(code): + nl = 1 + + for i,c in enumerate(code): + if c == '}': nl -= 1 + if c == '{': nl += 1 + + if nl == 0: + return i + +def getNamespaces(code): + namespaces = dict() + global namespaceBeginPattern + namespaceBeginPattern = re.compile(r"^namespace(?:\s+(?P\w+))?\s*\{", re.M | re.S) + + lastEnd = 0 + for match in namespaceBeginPattern.finditer(code): + # skip inner namespaces + if match.start() < lastEnd: + continue + + nsStart = match.end() # behind opening brace + nsEnd = findPairedBrace(code[nsStart:]) + nsStart # index of closing brace + + subNamespaces = getNamespaces(code[nsStart:nsEnd]) + namespaces[range(nsStart,nsEnd)] = (match["name"] or "", subNamespaces) + + # remember end for skipping inner namespaces + lastEnd = nsEnd + + return namespaces + +def namespaceAtPosition(namespaces, pos): + for span in namespaces: + if pos in span: + innerNS = namespaceAtPosition(namespaces[span][1], pos - span.start) + + return namespaces[span][0] + ("::" + innerNS if innerNS else "") + + return "" + +# ------------ +# small-scale parsing + +def splitParams(paramString): + splitParams = [p.strip() for p in paramString.split(',') if p.strip()] + + i = 0 + while i < len(splitParams)-1: + if splitParams[i].count('<') != splitParams[i].count('>'): + splitParams[i:i+2] = [splitParams[i] + "," + splitParams[i+1]] + else: + i += 1 + + paramDefaults = [(split[0].strip(), split[1].strip() if len(split) > 1 else '') for split in [p.rsplit('=', 1) for p in splitParams]] + paramsSplit = [(l.strip(), r.strip(), d) for l,r,d in [p.rsplit(' ', 1) + [d] for p,d in paramDefaults]] + + # Debug + while False: + cmd = input('>>>') + if not cmd: break + print(eval(cmd)) + + return paramsSplit + +def removeParamDefaults(params): + return [(p[0], p[1]) for p in params] + +def getParamNames(params): + return [p[1] for p in params] + +def getParamTypes(params): + return [p[0] for p in params] + +def getParamDefaults(params): + return [(p[1], p[2]) for p in params if p[2]] + +def possibleTypes(argType, templateList): + # currently unused + if re.match("^\w+$", argType): + if "std::enable_if::value>::type" in templateList: + return {"vec1"} + else: + return {"vec1", "vec2", "vec3", "vec4"} + + genVecMatch = re.match("(\w+)\s*<\s*\w+\s*,\s*\w+\s*>", argType) + if genVecMatch: + if re.search("template\s*<\s*(?:typename|class)\s*,\s*glm::precision\s*>\s*(?:typename|class)\s*" + genVecMatch[1], templateList): + return {"vec2", "vec3", "vec4"} + + specVecMatch = re.match("glm::tvec(\d)<.*?>", argType) + if specVecMatch: + return {"vec"+specVecMatch[1]} + + return argType + +def getEnumValues(valueDefString): + definitions = [d.strip() for d in valueDefString.split(',')] + values = [] + + i = 0 + for d in definitions: + if '=' in d: + _, _, expr = d.partition('=') + i = eval(expr, dict(values)) + + values.append((d,i)) + i += 1 + + return values + +# ------------ +# generation + +def enumForJS(value, enums): + if "::" not in value: + return value + + enumDict = {enum["name"]: {valueName:value for valueName, value in enum["values"]} for enum in enums} + + enumName, _, valueName = value.partition("::") + + if enumName not in enumDict: + # TODO: Warning? + return value + + if valueName not in enumDict[enumName]: + # TODO: Warning? + return value + + # TODO: Prefix of enum object + return enumName + "." + valueName + +def jsFunction(func, enums): + assert func["namespace"].startswith("glkernel::"), "function \""+func["name"]+"\" from outside glkernel namespace: " + func["namespace"] + + namespaceStack = func["namespace"].split("::") + namespaceStack.pop(0) # ignore outmost namespace glkernel + +# argCleans = '\n'.join([" {name} = cleanArg({name});".format(name=name) for name in getParamNames(func["params"])]) +# if argCleans: +# argCleans = "\n // Clean arguments\n" + argCleans + "\n" + + defaultChecks = '\n'.join([" {name} = (typeof {name} !== 'undefined') ? {name} : {default};".format(name=name, default=enumForJS(default, enums)) for name, default in getParamDefaults(func["params"])]) + if defaultChecks: + defaultChecks = "\n // Defaults\n" + defaultChecks + "\n" + + jsCode = """ {name}: function({params}) {{{defaultChecks} + _glkernel.{generatedName}(that.kernel{paramsWithKomma}); + return that; + }}""".format( + name = func["name"], + params = ', '.join(getParamNames(func["params"])), + paramsWithKomma = ''.join([', ' + p for p in getParamNames(func["params"])]), + generatedName = "_".join(namespaceStack + [func["name"]]), +# argCleans = argCleans, + defaultChecks = defaultChecks + ) + + return jsCode + +def buildJSNamespaces(funcs, enums): + namespaces = dict() + + for func in funcs: + if func["namespace"] not in namespaces: + namespaces[func["namespace"]] = [] + + namespaces[func["namespace"]].append(jsFunction(func, enums)) + + nsCodes = [] + + for ns, codes in namespaces.items(): + name = ns[len("glkernel::"):] + + nsCodes.append( + """ this.{name} = {{ +{funcCodes} + }};""".format( + name = name, + funcCodes = ",\n".join(codes) + ) + ) + + return "\n".join(nsCodes) + +def buildJSEnums(enums): + return "\n".join([ + """{name} = {{ +{members} +}};""".format( + name = enum["name"], + members = ",\n".join([" {name}: {value}".format(name=name, value=value) for name, value in enum["values"]]) + ) for enum in enums + ]) + +# ------------ +# misc + +def dedupeFuncs(funcs): + i = 1 + while i < len(funcs): + currentFunc = funcs[i] + for otherFunc in funcs[:i]: + if otherFunc["namespace"] != currentFunc["namespace"]: + continue + if otherFunc["name"] != currentFunc["name"]: + continue + + if getParamNames(otherFunc["params"]) == getParamNames(currentFunc["params"]): + # identical in JS -> can be safely removed + funcs.remove(currentFunc) + i -= 1 + + if "alternatives" not in otherFunc: + otherFunc["alternatives"] = [] + otherFunc["alternatives"].append(currentFunc) + + break + + print("Warning: Method \"" + currentFunc["namespace"] + "::" + currentFunc["name"] + "\" has overloads that can not be trivially resolved!") + + # Debug + while False: + cmd = input('>>>') + if not cmd: break + print(eval(cmd)) + + i += 1 + +# ------------ +# main + +def main(): + glkernelIncludeDir = Path("../source/glkernel/include/glkernel") + sourceFiles = [str(p) for p in glkernelIncludeDir.glob("*.h") if p.name not in ["Kernel.h", "glm_compatability.h"]] + + funcPattern = re.compile(r"^template\s*<(?P