From bf925e72401c7e4c6e3008aa760f83df5e7c59ab Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 22 Sep 2023 10:22:09 +0200 Subject: [PATCH 1/2] Added support for closing container without done command as shown by [Jerry](https://discordapp.com/users/jerrytron) adds inky a empty container at the end of the story. Which resultet in unexpected EOF. Now there is a check iff we leave the top level container and are at the end of the story file, the story ends. --- inkcpp/runner_impl.cpp | 11 ++++------- inkcpp_cl/inkcpp_cl.cpp | 12 ++++++++++-- unreal/CMakeLists.txt | 6 +++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/inkcpp/runner_impl.cpp b/inkcpp/runner_impl.cpp index 02e31147..f6685bd4 100644 --- a/inkcpp/runner_impl.cpp +++ b/inkcpp/runner_impl.cpp @@ -523,7 +523,7 @@ namespace ink::runtime::internal bool runner_impl::has_tags() const { - return _tags.size() > 0; + return num_tags() > 0; } size_t runner_impl::num_tags() const @@ -1212,7 +1212,7 @@ namespace ink::runtime::internal if (!_threads.empty()) { on_done(false); - return; + break; } else if (_stack.has_frame(&type) && type == frame_type::function) // implicit return is only for functions { @@ -1222,12 +1222,9 @@ namespace ink::runtime::internal // HACK _ptr += sizeof(Command) + sizeof(CommandFlag); execute_return(); + } else if (_container.empty() && _ptr == _story->end()){ + on_done(true); } - /*else TODO I had to remove this to make a test work.... is this important? Have I broken something? - { - on_done(false); // do we need to not set _done here? It wasn't set in the original code #implieddone - return; - }*/ } } break; case Command::VISIT: diff --git a/inkcpp_cl/inkcpp_cl.cpp b/inkcpp_cl/inkcpp_cl.cpp index acdb1c64..f5d55f4b 100644 --- a/inkcpp_cl/inkcpp_cl.cpp +++ b/inkcpp_cl/inkcpp_cl.cpp @@ -21,6 +21,7 @@ void usage() << "Usage: inkcpp_cl \n" << "\t-o :\tOutput file name\n" << "\t-p []:\tPlay mode\n\toptional snapshot file to load\n\tto create a snapshot file enter '-1' as choice\n" + << "\t--ommit-choice-tags:\tdo not print tags after choices, primarly used to be compatible with inkclecat output" << endl; } @@ -35,7 +36,10 @@ int main(int argc, const char** argv) // Parse options std::string outputFilename; - bool playMode = false, testMode = false, testDirectory = false; + bool playMode = false, + testMode = false, + testDirectory = false, + ommit_choice_tags = false; std::string snapshotFile; for (int i = 1; i < argc - 1; i++) { @@ -52,6 +56,10 @@ int main(int argc, const char** argv) snapshotFile = argv[i]; } } + else if (option == "--ommit-choice-tags") + { + ommit_choice_tags = true; + } else if (option == "-t") testMode = true; else if (option == "-td") @@ -180,7 +188,7 @@ int main(int argc, const char** argv) for (const ink::runtime::choice& c : *thread) { std::cout << index++ << ": " << c.text(); - if(c.has_tags()) { + if(!ommit_choice_tags && c.has_tags()) { std::cout << "\n\t"; for(size_t i = 0; i < c.num_tags(); ++i) { std::cout << "# " << c.get_tag(i) << " "; diff --git a/unreal/CMakeLists.txt b/unreal/CMakeLists.txt index ea0dd498..f5c072e0 100644 --- a/unreal/CMakeLists.txt +++ b/unreal/CMakeLists.txt @@ -22,7 +22,7 @@ set(INKLECATE_CMD "") if(WIN32) FetchContent_MakeAvailable(inklecate_windows) if(NOT inklecate_windows_SOURCE_DIR) - message(WARNING "failed to downloawd inklecate for windows, " + message(WARNING "failed to download inklecate for windows, " "the unreal plugin will be unable use a .ink file as asset directly") else() set(INKLECATE_CMD "Resources/inklecate/windows/inklecate.exe") @@ -30,7 +30,7 @@ if(WIN32) elseif(APPLE) FetchContent_MakeAvailable(inklecate_mac) if(NOT inklecate_mac_SOURCE_DIRE) - message(WARNING "failed to downloawd inklecate for MacOS, " + message(WARNING "failed to download inklecate for MacOS, " "the unreal plugin will be unable use a .ink file as asset directly") else() set(INKLECATE_CMD "Resources/inklecate/mac/inklecate") @@ -38,7 +38,7 @@ elseif(APPLE) elseif(UNIX) FetchContent_MakeAvailable(inklecate_linux) if(NOT inklecate_linux_SOURCE_DIR) - message(WARNING "failed to downloawd inklecate for linux, " + message(WARNING "failed to download inklecate for linux, " "the unreal plugin will be unable use a .ink file as asset directly") else() set(INKLECATE_CMD "Resources/inklecate/linux/inklecate") From 282f3c7a9a08ee18f138c8b9dd666f4ba2559e0d Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 22 Sep 2023 10:58:34 +0200 Subject: [PATCH 2/2] Add test for different compiled json Ensures compability for different ink compilers (bonus: use link for inkcpp_test resource file should now also supported on windows) --- inkcpp_test/CMakeLists.txt | 4 +- inkcpp_test/InkyJson.cpp | 33 ++++ inkcpp_test/ink/simple-1.1.1-inklecate.json | 154 +++++++++++++++++++ inkcpp_test/ink/simple-1.1.1-inky.json | 160 ++++++++++++++++++++ 4 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 inkcpp_test/InkyJson.cpp create mode 100644 inkcpp_test/ink/simple-1.1.1-inklecate.json create mode 100644 inkcpp_test/ink/simple-1.1.1-inky.json diff --git a/inkcpp_test/CMakeLists.txt b/inkcpp_test/CMakeLists.txt index f046c378..7ffc8aff 100644 --- a/inkcpp_test/CMakeLists.txt +++ b/inkcpp_test/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(inkcpp_test catch.hpp Main.cpp FallbackFunction.cpp LabelCondition.cpp Observer.cpp + InkyJson.cpp ) target_link_libraries(inkcpp_test PUBLIC inkcpp inkcpp_compiler inkcpp_shared) @@ -29,11 +30,12 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") endif() add_test(NAME UnitTests COMMAND $) + set (source "${CMAKE_CURRENT_SOURCE_DIR}/ink") set (destination "${CMAKE_CURRENT_BINARY_DIR}/ink") add_custom_command( TARGET inkcpp_test POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${source} ${destination} + COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${destination} DEPENDS ${destination} COMMENT "symbolic link resources folder from ${source} => ${destination}" ) diff --git a/inkcpp_test/InkyJson.cpp b/inkcpp_test/InkyJson.cpp new file mode 100644 index 00000000..2a39af88 --- /dev/null +++ b/inkcpp_test/InkyJson.cpp @@ -0,0 +1,33 @@ +#include "catch.hpp" +// #include "../inkcpp_cl/test.cpp" + +#include +#include +#include +#include + +using namespace ink::runtime; + +static constexpr const char* OUTPUT_PART_1 = "Once upon a time...\n"; +static constexpr const char* OUTPUT_PART_2 = "There were two choices.\nThey lived happily ever after.\n"; +static constexpr size_t CHOICE = 0; + +SCENARIO("run inklecate 1.1.1 story") +{ + auto compiler = GENERATE("inklecate", "inky"); + GIVEN(compiler) + { + auto input_file = std::string("ink/simple-1.1.1-") + compiler + ".json"; + ink::compiler::run(input_file.c_str(), "simple.bin"); + auto ink = story::from_file("simple.bin"); + runner thread = ink->new_runner(); + + THEN("Expect normal output") { + REQUIRE(thread->getall() == OUTPUT_PART_1); + REQUIRE(thread->has_choices()); + REQUIRE(thread->num_choices() == 2); + thread->choose(CHOICE); + REQUIRE(thread->getall() == OUTPUT_PART_2); + } + } +} diff --git a/inkcpp_test/ink/simple-1.1.1-inklecate.json b/inkcpp_test/ink/simple-1.1.1-inklecate.json new file mode 100644 index 00000000..e49985a8 --- /dev/null +++ b/inkcpp_test/ink/simple-1.1.1-inklecate.json @@ -0,0 +1,154 @@ +{ + "inkVersion": 21, + "root": [ + [ + { + "->": "start" + }, + [ + "done", + { + "#n": "g-0" + } + ], + null + ], + "done", + { + "start": [ + [ + "^Once upon a time...", + "\n", + [ + "ev", + { + "^->": "start.0.2.$r1" + }, + { + "temp=": "$r" + }, + "str", + { + "->": ".^.s" + }, + [ + { + "#n": "$r1" + } + ], + "/str", + "/ev", + { + "*": ".^.^.c-0", + "flg": 18 + }, + { + "s": [ + "^There were two choices.", + { + "->": "$r", + "var": true + }, + null + ] + } + ], + [ + "ev", + { + "^->": "start.0.3.$r1" + }, + { + "temp=": "$r" + }, + "str", + { + "->": ".^.s" + }, + [ + { + "#n": "$r1" + } + ], + "/str", + "/ev", + { + "*": ".^.^.c-1", + "flg": 18 + }, + { + "s": [ + "^There were four lines of content.", + { + "->": "$r", + "var": true + }, + null + ] + } + ], + { + "c-0": [ + "ev", + { + "^->": "start.0.c-0.$r2" + }, + "/ev", + { + "temp=": "$r" + }, + { + "->": ".^.^.2.s" + }, + [ + { + "#n": "$r2" + } + ], + "\n", + { + "->": ".^.^.g-0" + }, + { + "#f": 5 + } + ], + "c-1": [ + "ev", + { + "^->": "start.0.c-1.$r2" + }, + "/ev", + { + "temp=": "$r" + }, + { + "->": ".^.^.3.s" + }, + [ + { + "#n": "$r2" + } + ], + "\n", + { + "->": ".^.^.g-0" + }, + { + "#f": 5 + } + ], + "g-0": [ + "^They lived happily ever after.", + "\n", + "end", + null + ] + } + ], + null + ] + } + ], + "listDefs": {} +} diff --git a/inkcpp_test/ink/simple-1.1.1-inky.json b/inkcpp_test/ink/simple-1.1.1-inky.json new file mode 100644 index 00000000..7677a825 --- /dev/null +++ b/inkcpp_test/ink/simple-1.1.1-inky.json @@ -0,0 +1,160 @@ +{ + "inkVersion": 21, + "root": [ + [ + { + "->": "start" + }, + [ + "done", + { + "#f": 5, + "#n": "g-0" + } + ], + null + ], + "done", + { + "start": [ + [ + "^Once upon a time...", + "\n", + [ + "ev", + { + "^->": "start.0.2.$r1" + }, + { + "temp=": "$r" + }, + "str", + { + "->": ".^.s" + }, + [ + { + "#n": "$r1" + } + ], + "/str", + "/ev", + { + "*": ".^.^.c-0", + "flg": 18 + }, + { + "s": [ + "^There were two choices.", + { + "->": "$r", + "var": true + }, + null + ] + } + ], + [ + "ev", + { + "^->": "start.0.3.$r1" + }, + { + "temp=": "$r" + }, + "str", + { + "->": ".^.s" + }, + [ + { + "#n": "$r1" + } + ], + "/str", + "/ev", + { + "*": ".^.^.c-1", + "flg": 18 + }, + { + "s": [ + "^There were four lines of content.", + { + "->": "$r", + "var": true + }, + null + ] + } + ], + { + "c-0": [ + "ev", + { + "^->": "start.0.c-0.$r2" + }, + "/ev", + { + "temp=": "$r" + }, + { + "->": ".^.^.2.s" + }, + [ + { + "#n": "$r2" + } + ], + "\n", + { + "->": ".^.^.g-0" + }, + { + "#f": 5 + } + ], + "c-1": [ + "ev", + { + "^->": "start.0.c-1.$r2" + }, + "/ev", + { + "temp=": "$r" + }, + { + "->": ".^.^.3.s" + }, + [ + { + "#n": "$r2" + } + ], + "\n", + { + "->": ".^.^.g-0" + }, + { + "#f": 5 + } + ], + "g-0": [ + "^They lived happily ever after.", + "\n", + "end", + { + "#f": 5 + } + ] + } + ], + { + "#f": 1 + } + ], + "#f": 1 + } + ], + "listDefs": {} +}