From f39030d3f6266e6d8297879e62c1efb9400f656f Mon Sep 17 00:00:00 2001 From: "Vedant R. Nimje" Date: Wed, 20 Sep 2023 23:03:43 +0530 Subject: [PATCH] [Scripting] Added interfacing of C++ references with QF variables (#22) * Added ability to use C++ references with QF ints * Added ability to use C++ std::string references with QF strs * Updated README to reflect new changes in scripting * Fixing failing builds due to redefinitions * Updated roadmap for v0.2 release Signed-off-by: Vedant --- README.md | 88 +++++++++++++++++++++------------------- cpp_examples/example.cpp | 24 +++++------ include/quick-ftxui.hpp | 56 +++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index c62ba4e..4ac2bd1 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ https://github.com/vrnimje/quick-ftxui/assets/103848930/715c821b-b259-4e2b-ab25- * #### Variables - Used as hooks, so that we can obtain the input given to the Terminal UI. Currenlty, supports `int` and `str` data types + Used as hooks, so that we can obtain the input given to the Terminal UI. Currently, supports `int` and `str` data types Check out the examples in [this directory](./examples/) @@ -166,7 +166,7 @@ https://github.com/vrnimje/quick-ftxui/assets/103848930/715c821b-b259-4e2b-ab25- * #### Embedded scripting supported in C++ - Supports basic scripting functionality, with functions to add & access the quick-ftxui variables. + Supports basic scripting functionality, with functions (or hooks) to add & access the quick-ftxui variables. We can also use C++ references to integers and string data types to access the values inside the QF script. See the example given below. [Full Example](./cpp_examples/example.cpp) @@ -179,46 +179,52 @@ https://github.com/vrnimje/quick-ftxui/assets/103848930/715c821b-b259-4e2b-ab25- using namespace quick_ftxui; int main() { - - set_int_var("x", 5); - set_str_var("y", ""); - string source_code = R"(Vertical{ - str z = "init" - str a - int o = 0 - Input { - "Type something...", - Password, - y - } - Slider { - "Test: ", - x, - 0, - 100, - 2 - } - Button{ - "ls", - System("/usr/bin/google-chrome-stable"), - Ascii, - z - } - Menu{ - [ "Physics", "Maths", "Chemistry", "Biology",], - VerticalAnimated, - o - } - Button { - "Exit", - "Exit" - } - })"; - - parse_qf(source_code); + int x = 5; + string y = "Init value"; + set_int_var("x", &x); + set_str_var("y", &y); + string source_code = R"(Border Vertical{ + str z = "init" + str a + int o = 0 + Input { + "Type something...", + y + } + RedLight Slider { + "Test: ", + x, + 0, + 100, + 2 + } + Magenta Button{ + "Chrome", + System("/usr/bin/google-chrome-stable"), + Animated, + z + } + Green Menu{ + [ "Physics", "Maths", "Chemistry", "Biology",], + VerticalAnimated, + o + } + Button { + "Exit", + "Exit" + } + })"; + + parse_qf(source_code); + + cout << "Slider value is: " << x << "\n"; + cout << "User input is: " << y << "\n"; + cout << "Option no. selected in Menu is: " << get_int("o") + 1 << "\n"; + cout << "Chrome debug msgs are: " << get_str("z") << "\n"; + } ``` - **Note:** To run this above example, build this repository with examples, steps [given here](#build-with-examples) + **Note:** To run this example, build this repository with examples, steps [given here](#build-with-examples) ## Build instructions: ~~~bash @@ -242,7 +248,7 @@ ninja - [x] Adding color (component wise) - [x] Adding FTXUI DOM elements (like seperator, border) -- [ ] Adding a way to use C++ defined variables directly, instead of depending on script-variables +- [x] Adding a way to use C++ defined variables directly, instead of depending on script-variables - [ ] Adding detailed user documentation ## Dependencies diff --git a/cpp_examples/example.cpp b/cpp_examples/example.cpp index 9defc3e..87158d9 100644 --- a/cpp_examples/example.cpp +++ b/cpp_examples/example.cpp @@ -6,16 +6,16 @@ using namespace std; using namespace quick_ftxui; int main() { - - set_int_var("x", 5); - set_str_var("y", ""); - string source_code = R"(Vertical{ + int x = 5; + string y = "Init value"; + set_int_var("x", &x); + set_str_var("y", &y); + string source_code = R"(Border Vertical{ str z = "init" str a int o = 0 Input { "Type something...", - Password, y } RedLight Slider { @@ -26,12 +26,12 @@ int main() { 2 } Magenta Button{ - "ls", + "Chrome", System("/usr/bin/google-chrome-stable"), - Ascii, + Animated, z } - Menu{ + Green Menu{ [ "Physics", "Maths", "Chemistry", "Biology",], VerticalAnimated, o @@ -44,8 +44,8 @@ int main() { parse_qf(source_code); - cout << "x is: " << get_int("x") << "\n"; - cout << "y is: " << get_str("y") << "\n"; - cout << "o is: " << get_int("o") << "\n"; - cout << "z is: " << get_str("z") << "\n"; + cout << "Slider value is: " << x << "\n"; + cout << "User input is: " << y << "\n"; + cout << "Option no. selected in Menu is: " << get_int("o") + 1 << "\n"; + cout << "Chrome debug msgs are: " << get_str("z") << "\n"; } \ No newline at end of file diff --git a/include/quick-ftxui.hpp b/include/quick-ftxui.hpp index 7621564..2f5eff5 100644 --- a/include/quick-ftxui.hpp +++ b/include/quick-ftxui.hpp @@ -30,6 +30,9 @@ namespace quick_ftxui_ast { std::map numbers; std::map strings; +std::map ref_nums; +std::map ref_strs; + /////////////////////////////////////////////////////////////////////////// // The AST /////////////////////////////////////////////////////////////////////////// @@ -1087,6 +1090,17 @@ void parse_qf(std::string source_code) { } screen.Loop(main_renderer); + + for (auto It : quick_ftxui_ast::ref_nums) { + *(It.first) = quick_ftxui_ast::numbers[It.second]; + } + + for (auto It : quick_ftxui_ast::ref_nums) { + *(It.first) = quick_ftxui_ast::numbers[It.second]; + } + for (auto It : quick_ftxui_ast::ref_strs) { + *(It.first) = quick_ftxui_ast::strings[It.second]; + } } } else { throw std::runtime_error("Parsing failed\n"); @@ -1114,6 +1128,27 @@ void set_int_var(std::string var_name, int init_value) { } } +void set_int_var(std::string var_name, int *init_value) { + if (auto It = quick_ftxui_ast::numbers.find(var_name); + It != quick_ftxui_ast::numbers.end()) { + throw std::runtime_error("Integer variable with name " + var_name + + " already exists, please use another name"); + } else { + quick_ftxui_ast::numbers.insert({var_name, (*init_value)}); + quick_ftxui_ast::ref_nums.insert({init_value, var_name}); + } +} + +void set_int_var(std::string var_name) { + if (auto It = quick_ftxui_ast::numbers.find(var_name); + It != quick_ftxui_ast::numbers.end()) { + throw std::runtime_error("Integer variable with name " + var_name + + " already exists, please use another name"); + } else { + quick_ftxui_ast::numbers.insert({var_name, 0}); + } +} + std::string get_str(std::string var_name) { if (auto It = quick_ftxui_ast::strings.find(std::string(var_name)); It != quick_ftxui_ast::strings.end()) { @@ -1135,6 +1170,27 @@ void set_str_var(std::string var_name, std::string init_value) { } } +void set_str_var(std::string var_name) { + if (auto It = quick_ftxui_ast::strings.find(var_name); + It != quick_ftxui_ast::strings.end()) { + throw std::runtime_error("Integer variable with name " + var_name + + " already exists, please use another name"); + } else { + quick_ftxui_ast::strings.insert({var_name, ""}); + } +} + +void set_str_var(std::string var_name, std::string *init_value) { + if (auto It = quick_ftxui_ast::strings.find(var_name); + It != quick_ftxui_ast::strings.end()) { + throw std::runtime_error("Integer variable with name " + var_name + + " already exists, please use another name"); + } else { + quick_ftxui_ast::strings.insert({var_name, (*init_value)}); + quick_ftxui_ast::ref_strs.insert({init_value, var_name}); + } +} + } // namespace quick_ftxui #endif // QUICK_FTXUI_HPP \ No newline at end of file