inkcpp_rb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +84 -0
- data/LICENSE +7 -0
- data/README.md +3 -0
- data/Rakefile +16 -0
- data/bin/console +15 -0
- data/bin/setup +10 -0
- data/bin/tapioca +29 -0
- data/ext/inkcpp_rb/extconf.rb +19 -0
- data/ext/inkcpp_rb/inkcpp/.clang-format +99 -0
- data/ext/inkcpp_rb/inkcpp/.github/FUNDING.yml +1 -0
- data/ext/inkcpp_rb/inkcpp/.github/workflows/build.yml +344 -0
- data/ext/inkcpp_rb/inkcpp/.github/workflows/release.yml +49 -0
- data/ext/inkcpp_rb/inkcpp/.gitignore +25 -0
- data/ext/inkcpp_rb/inkcpp/.gitmodules +9 -0
- data/ext/inkcpp_rb/inkcpp/CMakeLists.txt +170 -0
- data/ext/inkcpp_rb/inkcpp/CODE_OF_CONDUCT.md +76 -0
- data/ext/inkcpp_rb/inkcpp/CONTRIBUTING.md +55 -0
- data/ext/inkcpp_rb/inkcpp/Config.cmake.in +2 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/CMakeLists.txt +13 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.c +38 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.cpp +40 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink.json +1 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example.zip +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/InkCPP_DEMO.zip +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/CreateThread.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/HandleChoice.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ListElementOf.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalRuntime.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalThread.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ObseverChange.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/TagListGetValue.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/YieldResume.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Doxyfile +2825 -0
- data/ext/inkcpp_rb/inkcpp/LICENSE.txt +22 -0
- data/ext/inkcpp_rb/inkcpp/Minimal.runsettings +8 -0
- data/ext/inkcpp_rb/inkcpp/README.md +192 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/CMakeLists.txt +67 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/array.h +481 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/avl_array.h +833 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/casting.h +93 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/choice.cpp +54 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.cpp +124 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.h +406 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.cpp +52 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.h +34 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/executioner.h +179 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/functional.cpp +86 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/functions.cpp +54 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/functions.h +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.cpp +289 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.h +149 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/header.cpp +44 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/choice.h +106 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/functional.h +327 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/globals.h +196 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/list.h +187 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/runner.h +291 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/snapshot.h +61 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/story.h +219 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/story_ptr.h +233 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/traits.h +270 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/types.h +169 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.cpp +79 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.h +39 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.cpp +276 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.h +356 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.cpp +841 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.h +450 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.cpp +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.h +529 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/operation_bases.h +164 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/operations.h +100 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/output.cpp +528 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/output.h +153 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/platform.h +22 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/random.h +38 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.cpp +1396 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.h +336 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/simple_restorable_stack.h +335 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.cpp +182 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.h +91 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_interface.h +57 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/stack.cpp +618 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/stack.h +243 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.cpp +361 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.h +92 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/story_ptr.cpp +75 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.cpp +125 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.h +67 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.cpp +149 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.h +47 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_utils.h +207 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/system.cpp +39 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/tuple.hpp +151 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/value.cpp +279 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/value.h +666 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/CMakeLists.txt +62 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/include/inkcpp.h +393 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp.cpp +344 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp_c.pc.in +10 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/ExternalFunction.c +56 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Globals.c +98 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Lists.c +73 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Observer.c +36 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Snapshot.c +65 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/CMakeLists.txt +49 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/inkcpp_cl.cpp +215 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.cpp +209 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.h +8 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/CMakeLists.txt +37 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.cpp +446 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.h +70 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.cpp +166 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.h +79 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/command.cpp +107 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/compiler.cpp +96 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.cpp +62 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.h +104 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compilation_results.h +22 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compiler.h +44 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json.hpp +24596 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.cpp +411 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.h +62 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.cpp +47 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.h +70 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.cpp +107 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.h +55 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/CMakeLists.txt +19 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/example.py +78 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/src/module.cpp +317 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/conftest.py +53 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_ExternalFunctions.py +35 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Globals.py +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Lists.py +43 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Observer.py +27 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Snapshot.py +57 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/unreal_example.ink +71 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Array.cpp +115 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/CMakeLists.txt +117 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Callstack.cpp +392 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/EmptyStringForDivert.cpp +36 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ExternalFunctionsExecuteProperly.cpp +34 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/FallbackFunction.cpp +77 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Globals.cpp +73 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/InkyJson.cpp +34 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/LabelCondition.cpp +60 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Lists.cpp +144 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/LookaheadSafe.cpp +46 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Main.cpp +7 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/MoveTo.cpp +95 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/NewLines.cpp +76 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/NoEarlyTags.cpp +33 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Observer.cpp +245 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Pointer.cpp +191 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Restorable.cpp +294 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/SpaceAfterBracketChoice.cpp +45 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Stack.cpp +224 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Tags.cpp +131 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ThirdTierChoiceAfterBrackets.cpp +38 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/UTF8.cpp +56 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Value.cpp +210 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/catch.hpp +17970 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/AHF.ink +7 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ChoiceBracketStory.ink +7 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/EmptyStringForDivert.ink +13 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ExternalFunctionsExecuteProperly.ink +11 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/FallBack.ink +15 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/GlobalStory.ink +9 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LabelConditionStory.ink +5 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LinesStory.ink +42 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListLogicStory.ink +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListStory.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LookaheadSafe.ink +14 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/MoveTo.ink +36 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/NoEarlyTags.ink +19 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ObserverStory.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/SimpleStoryFlow.ink +65 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TagsStory.ink +22 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TheIntercept.ink +1686 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ThirdTierChoiceAfterBracketsStory.ink +13 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF-8-demo.txt +212 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF8Story.ink +218 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inklecate.json +154 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inky.json +160 -0
- data/ext/inkcpp_rb/inkcpp/notes/ArchitectureNotes.md +54 -0
- data/ext/inkcpp_rb/inkcpp/notes/ListNotes.md +69 -0
- data/ext/inkcpp_rb/inkcpp/notes/OperationNotes.md +35 -0
- data/ext/inkcpp_rb/inkcpp/notes/TagsNotes.md +24 -0
- data/ext/inkcpp_rb/inkcpp/notes/WhitespaceNotes.md +28 -0
- data/ext/inkcpp_rb/inkcpp/proofing/README.md +3 -0
- data/ext/inkcpp_rb/inkcpp/proofing/inkcpp_runtime_driver +12 -0
- data/ext/inkcpp_rb/inkcpp/pyproject.toml +63 -0
- data/ext/inkcpp_rb/inkcpp/setup.py +166 -0
- data/ext/inkcpp_rb/inkcpp/shared/CMakeLists.txt +14 -0
- data/ext/inkcpp_rb/inkcpp/shared/private/command.h +172 -0
- data/ext/inkcpp_rb/inkcpp/shared/private/header.h +46 -0
- data/ext/inkcpp_rb/inkcpp/shared/public/config.h +53 -0
- data/ext/inkcpp_rb/inkcpp/shared/public/system.h +307 -0
- data/ext/inkcpp_rb/inkcpp/shared/public/version.h +14 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestAllSequenceTypes.ink +59 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestArithmetic.ink +17 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestBasicStringLiterals.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestBasicTunnel.ink +10 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestBlanksInInlineSequences.ink +51 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestCallStackEvaluation.ink +15 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestChoiceCount.ink +15 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestChoiceDivertsToDone.ink +6 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestChoiceWithBracketsOnly.ink +9 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestCompareDivertTargets.ink +26 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestComplexTunnels.ink +22 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestConditionalChoiceInWeave.ink +19 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestTunnelOnwardsAfterTunnel.ink +17 -0
- data/ext/inkcpp_rb/inkcpp/unreal/CMakeLists.txt +51 -0
- data/ext/inkcpp_rb/inkcpp/unreal/UE_example.ink +92 -0
- data/ext/inkcpp_rb/inkcpp/unreal/blueprint_filter.js +377 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Resources/Icon128.png +0 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkAsset.cpp +47 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkChoice.cpp +40 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkList.cpp +86 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkRuntime.cpp +265 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkThread.cpp +239 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkVar.cpp +143 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/TagList.cpp +95 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/inkcpp.cpp +13 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h +50 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h +58 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h +139 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkList.h +102 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h +177 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h +30 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkThread.h +215 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkVar.h +245 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/TagList.h +77 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h +217 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/inkcpp.Build.cs +62 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.cpp +237 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.h +43 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inkcpp_editor.cpp +13 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inklecate_cmd.cpp.in +24 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Public/inkcpp_editor.h +9 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/inkcpp_editor.Build.cs +61 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/inkcpp.uplugin +44 -0
- data/ext/inkcpp_rb/inkcpp/unreal/render.css +1 -0
- data/ext/inkcpp_rb/inkcpp_rb.cpp +321 -0
- data/inkcpp_rb.gemspec +54 -0
- data/rbi/inkcpp_rb.rbi +211 -0
- data/sorbet/config +4 -0
- data/sorbet/rbi/annotations/.gitattributes +1 -0
- data/sorbet/rbi/annotations/minitest.rbi +119 -0
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
- data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
- data/sorbet/rbi/gems/minitest@5.25.4.rbi +1547 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
- data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
- data/sorbet/rbi/gems/prism@1.3.0.rbi +40040 -0
- data/sorbet/rbi/gems/rake-compiler@1.2.8.rbi +9 -0
- data/sorbet/rbi/gems/rake@13.2.1.rbi +3033 -0
- data/sorbet/rbi/gems/rbi@0.2.2.rbi +4527 -0
- data/sorbet/rbi/gems/rice@4.3.3.rbi +44 -0
- data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
- data/sorbet/rbi/gems/tapioca@0.16.7.rbi +3611 -0
- data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
- data/sorbet/rbi/gems/yard@0.9.37.rbi +18379 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- metadata +400 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include "CoreMinimal.h"
|
|
10
|
+
#include "TagList.generated.h"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Helpful tag list
|
|
14
|
+
* @ingroup unreal
|
|
15
|
+
*/
|
|
16
|
+
UCLASS()
|
|
17
|
+
class INKCPP_API UTagList : public UObject
|
|
18
|
+
{
|
|
19
|
+
GENERATED_BODY()
|
|
20
|
+
|
|
21
|
+
public:
|
|
22
|
+
UTagList();
|
|
23
|
+
|
|
24
|
+
/** Initializes the tag list from an array
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
void Initialize(const TArray<FString>& tags);
|
|
28
|
+
|
|
29
|
+
UFUNCTION(BlueprintPure, Category = "Ink")
|
|
30
|
+
/** Checks if the tag is present in the array.
|
|
31
|
+
*
|
|
32
|
+
* @blueprint
|
|
33
|
+
*/
|
|
34
|
+
bool Has(const FString& tag) const;
|
|
35
|
+
|
|
36
|
+
UFUNCTION(BlueprintPure, Category = "Ink")
|
|
37
|
+
/** Check if tag list contains enum flag.
|
|
38
|
+
* Check if one of the enum flag string represntations is equal
|
|
39
|
+
* to one flag in the list.
|
|
40
|
+
* @param Enum the enum class to check flags from
|
|
41
|
+
* @param value of the flag iff one was found
|
|
42
|
+
* @retval true if a flag was found
|
|
43
|
+
* @attention if multiple flags are present in the list, only the first will be returned
|
|
44
|
+
* @see #GetEnum()
|
|
45
|
+
*
|
|
46
|
+
* @blueprint
|
|
47
|
+
*/
|
|
48
|
+
bool HasEnum(const UEnum* Enum, uint8& value) const;
|
|
49
|
+
|
|
50
|
+
UFUNCTION(BlueprintPure, Category = "Ink")
|
|
51
|
+
/** Searches for a tag that begins with 'name:' and returns the string after the colon
|
|
52
|
+
* @retval "" if no value was found, or if there are nothing behind ':'
|
|
53
|
+
*
|
|
54
|
+
* @blueprint
|
|
55
|
+
*/
|
|
56
|
+
FString GetValue(const FString& name) const;
|
|
57
|
+
|
|
58
|
+
UFUNCTION(BlueprintPure, Category = "Ink")
|
|
59
|
+
/** Searches for a tag thats begins with 'EnumName:' and returns the enum value corresponding to
|
|
60
|
+
* the text after the ':'
|
|
61
|
+
* @attention If the enum appears multiple times, the first instance will be used
|
|
62
|
+
* @retval true if a tag in the form "EnumName:FlagName" was found
|
|
63
|
+
*
|
|
64
|
+
* @blueprint
|
|
65
|
+
*/
|
|
66
|
+
bool GetEnum(const UEnum* Enum, uint8& value) const;
|
|
67
|
+
|
|
68
|
+
UFUNCTION(BlueprintPure, Category = "Ink")
|
|
69
|
+
/** Get all tags as array.
|
|
70
|
+
*
|
|
71
|
+
* @blueprint
|
|
72
|
+
*/
|
|
73
|
+
const TArray<FString>& GetTags() const;
|
|
74
|
+
|
|
75
|
+
private:
|
|
76
|
+
TArray<FString> Tags;
|
|
77
|
+
};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#pragma once
|
|
8
|
+
#include "Logging/LogMacros.h"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @defgroup unreal Unreal Blueprints
|
|
12
|
+
* Blueprint Classes usable in Unreal. An example can be found
|
|
13
|
+
* [here](unreal/InkCPP_DEMO.zip), do not forgett to install the plugin via the
|
|
14
|
+
* [marketplace](https://www.unrealengine.com/marketplace/product/inkcpp) or unzipping the
|
|
15
|
+
* `unreal.zip` from the [release page](https://github.com/JBenda/inkcpp/releases/latest) to
|
|
16
|
+
* `/YOUR_UNREAL_PROJECT/Plugins/`. <br/> And eitherway activating the plugin.
|
|
17
|
+
*
|
|
18
|
+
* The C++ API will be available soon([Issue](https://github.com/JBenda/inkcpp/issues/60)).
|
|
19
|
+
*
|
|
20
|
+
* + @ref ue_setup "General setup"
|
|
21
|
+
* + @ref ue_components "UE5 Blueprits"
|
|
22
|
+
* + @ref ue_example "Demo project & setup"
|
|
23
|
+
*
|
|
24
|
+
* @section ue_setup Setup
|
|
25
|
+
*
|
|
26
|
+
* After installing the plugin (see above) you need to activate it via `Plugins->...`.
|
|
27
|
+
* Then to run your Ink script you need a instance of @ref AInkRuntime. The story will
|
|
28
|
+
* only proceed if this actor is active.
|
|
29
|
+
*
|
|
30
|
+
* On this instance set the `Ink|InkAsset` property to the story that you will run.
|
|
31
|
+
* To create this InkAsset you need to import a `.ink` file or `.ink.json` file.
|
|
32
|
+
*
|
|
33
|
+
* With the @ref AInkRuntime you can then create a @ref UInkThread with @ref AInkRuntime::Start().
|
|
34
|
+
* In addition does the runtime allows you access to the global variables via @ref
|
|
35
|
+
* AInkRuntime::ObserverVariableChange() "observer" or directly @ref
|
|
36
|
+
* AInkRuntime::SetGlobalVariable() "setter" und @ref AInkRuntime::GetGlobalVariable() "getter".
|
|
37
|
+
*
|
|
38
|
+
* Notice that all threads spawned in the
|
|
39
|
+
* same runtime will share a global state. So if you want to play the same story with different
|
|
40
|
+
* states, you need multiple runtimes.
|
|
41
|
+
*
|
|
42
|
+
* The @ref UInkThread class provides will fire events when new context is available. The easiest
|
|
43
|
+
* way to implement then is to create a custom Blueprint based on @ref UInkThread. For a overview
|
|
44
|
+
* see @ref ue_thread.
|
|
45
|
+
*
|
|
46
|
+
* Below you can find the blueprints of a @ref ue_example_minimal "minimal example". Which is
|
|
47
|
+
* included for further inspection inside the @ref ue_example "Example project" (in the map
|
|
48
|
+
* `Minimal`).
|
|
49
|
+
*
|
|
50
|
+
* @section ue_components Components
|
|
51
|
+
*
|
|
52
|
+
* @subsection ue_runtime Runtime
|
|
53
|
+
* The @ref AInkRuntime handles the runtime as actor.
|
|
54
|
+
* At every Tick all @ref UInkThread of the runtime will be further executed if appropiate.
|
|
55
|
+
*
|
|
56
|
+
* The asset containing the story to run can be set via the Ink|InkAsset attribute.
|
|
57
|
+
*
|
|
58
|
+
* The runtime is the position to set observer (e.g. @ref AInkRuntime::ObserverVariableChange() )
|
|
59
|
+
* and create new threads (@ref AInkRuntime::Start() & @ref AInkRuntime::StartExisting() ).
|
|
60
|
+
*
|
|
61
|
+
* It is adviced to create you own Blueprint which inherites @ref AInkRuntime to overwrite the
|
|
62
|
+
* events as necessary.
|
|
63
|
+
*
|
|
64
|
+
* @subsection ue_thread Thread
|
|
65
|
+
* A @ref UInkThread is like a pointer inside the story. It contains informations can advance and
|
|
66
|
+
* will therby output the context it encounters.
|
|
67
|
+
*
|
|
68
|
+
* All threads inside the same runtime will share the same variables but can be at different points
|
|
69
|
+
* in the story.
|
|
70
|
+
*
|
|
71
|
+
* The most importent events/functions are:
|
|
72
|
+
* + @ref UInkThread::OnLineWritten() which is called by each new line of output
|
|
73
|
+
* + @ref UInkThread::OnChoice() which is called if a choice is encounterd and must be handled
|
|
74
|
+
* + @ref UInkThread::PickChoice() to pick a choice and continue the thread.
|
|
75
|
+
*
|
|
76
|
+
* @subsection ue_choice Choice
|
|
77
|
+
* A @ref UInkChoice contains all data relevant for a branch at a choice point.
|
|
78
|
+
* + @ref UInkChoice::GetText() the text of the choice
|
|
79
|
+
* + @ref UInkChoice::GetIndex() the index used in @ref UInkThread::PickChoice()
|
|
80
|
+
* + @ref UInkChoice::GetTags() tags assoziated with this branch/choice
|
|
81
|
+
*
|
|
82
|
+
* @subsection ue_taglist TagList
|
|
83
|
+
* A @ref UTagList is a wrapper for the array of tags each line of context and each choice can have.
|
|
84
|
+
*
|
|
85
|
+
* @subsection ue_ivar InkVar
|
|
86
|
+
* A wrapper for variables of the ink runtime.
|
|
87
|
+
* To get/set variables you need access to the runtime:
|
|
88
|
+
* @ref AInkRuntime::GetGlobalVariable(), @ref AInkRuntime::SetGlobalVariable()
|
|
89
|
+
*
|
|
90
|
+
* please note that get returns a copy of the variables value and to change it you need to call set.
|
|
91
|
+
*
|
|
92
|
+
* @subsection ue_list InkList
|
|
93
|
+
* @ref UInkList is a wrapper for the list type inside ink.
|
|
94
|
+
* A ink list is like a set for enum values. For a in depth explenation please refer to the [offical
|
|
95
|
+
* guide](https://blueprintue.com/blueprint/hdybtdjp/)
|
|
96
|
+
*
|
|
97
|
+
* If you define Enums simular to the Lists in the ink script you can use them for an easier access.
|
|
98
|
+
*
|
|
99
|
+
* @section ue_example The Example project
|
|
100
|
+
*
|
|
101
|
+
* [Download](../unreal/InkCPP_DEMO.zip)
|
|
102
|
+
*
|
|
103
|
+
* @subsection ue_example_setup Setup
|
|
104
|
+
*
|
|
105
|
+
* To setup the [example project](../unreal/InkCPP_DEMO.zip) install the Plugin via the [UE
|
|
106
|
+
* marketplace](https://www.unrealengine.com/product/inkcpp) place unpack
|
|
107
|
+
* the `unreal.zip` from the [release page](https://github.com/JBenda/inkcpp/releases/latest) inside
|
|
108
|
+
* `/PATH/InkCPP_DEMO/Plugins/`.
|
|
109
|
+
*
|
|
110
|
+
* Next open the project via the `InkCPP_DEMO/InkCPP_DEMO.uproject` flie.
|
|
111
|
+
*
|
|
112
|
+
* Than you can hit play to run the demo.
|
|
113
|
+
*
|
|
114
|
+
* The example contains two maps:
|
|
115
|
+
* + @ref ue_example_demo "`Demo`": An extensive example demonstrating many but not all features
|
|
116
|
+
* provided by inkCPP like:
|
|
117
|
+
* + snapshots: for creating save games
|
|
118
|
+
* + observers: to easily refelct a variable of the ink story in the game.
|
|
119
|
+
* + external function + yield: to stop playing the story while the game plays a transition
|
|
120
|
+
* + a second runner: for a inventory menu
|
|
121
|
+
* + interopariblity between UE Enums and Lists in Ink
|
|
122
|
+
* + Tag attributes: use tags to modify showed text
|
|
123
|
+
* + Tag attributes as enums: use tags to modify choices
|
|
124
|
+
* + @ref ue_example_minimal "`Minimal`": An example for a minimal, still sensible usage example of
|
|
125
|
+
* InkCPP in UE5.
|
|
126
|
+
*
|
|
127
|
+
* @subsection ue_example_demo Demo
|
|
128
|
+
*
|
|
129
|
+
* The Demo map contains the Actor `DemoThread` which is a child of `InkRuntime`.
|
|
130
|
+
* All UI elements and other used components are created on the `BeginPlay` event in the following
|
|
131
|
+
* order.
|
|
132
|
+
* 1. The UI components are created and configured
|
|
133
|
+
* 2. Load an existing save game if its exists (the Save game is stored at
|
|
134
|
+
* `InkCPP_DEMO/Saved/SaveGames`).
|
|
135
|
+
* 3. Create the main thread of class `DemoThread` and register the external function.
|
|
136
|
+
* 4. Create menu thread(`InfoThread`), set path to `Wait` to avoid any output in the beginging.
|
|
137
|
+
* 5. Set observer for the variable `Heath` to update the healthbar.
|
|
138
|
+
* 6. Set observer for the variable `Inventory` to update the inventory columns.
|
|
139
|
+
*
|
|
140
|
+
* @subsubsection ue_example_ui UI
|
|
141
|
+
*
|
|
142
|
+
* + `DialogHUD` contains all static UI elements.
|
|
143
|
+
* + `Context`: text box containing thelines of the ink story.
|
|
144
|
+
* + `Choices`: A container which should be populated with the choice buttons
|
|
145
|
+
* + `Clues` & `Potions`: container which should be populated with inventory buttons
|
|
146
|
+
* + `SC_Button`: Button to triggern save and close action
|
|
147
|
+
* + `Health`: health bar showing current health
|
|
148
|
+
* + `DMG_Numbers`: container which should be populated with damage numbers
|
|
149
|
+
* + `Popup`/`PopupContext`/`PopopChoices`: elements needed for the Info/"Item interaction thread"
|
|
150
|
+
* + `TransitionBlob`: A animated entity used to simulate a transition.
|
|
151
|
+
* + `DMG_Number` animated text block used to display damage numbers
|
|
152
|
+
* + `InventoryButton`/`ChoiceButton`: Wrapper for buttons, primarly for attaching data
|
|
153
|
+
* to a button for a parametrized clicked event.
|
|
154
|
+
*
|
|
155
|
+
* @subsubsection ue_example_demo_DemoRunner DemoRunner
|
|
156
|
+
*
|
|
157
|
+
* @htmlonly
|
|
158
|
+
* <a href="https://blueprintue.com/blueprint/owj83khu/">
|
|
159
|
+
* <img
|
|
160
|
+
* alt="Thread Creation Blueprint"
|
|
161
|
+
* src="../unreal/imgs/CreateThread.png"
|
|
162
|
+
* width="80%"/></a>
|
|
163
|
+
* @endhtmlonly
|
|
164
|
+
*
|
|
165
|
+
* @htmlonly
|
|
166
|
+
* <a href="https://blueprintue.com/blueprint/7bjjjb6u/">
|
|
167
|
+
* <img
|
|
168
|
+
* alt="Observe Change of variable Blueprint"
|
|
169
|
+
* src="../unreal/imgs/ObseverChange.png"
|
|
170
|
+
* width="80%"/></a>
|
|
171
|
+
* @endhtmlonly
|
|
172
|
+
*
|
|
173
|
+
* @htmlonly
|
|
174
|
+
* <a href="https://blueprintue.com/blueprint/hdybtdjp/">
|
|
175
|
+
* <img
|
|
176
|
+
* alt="Usage example for InkList::ElementOf in a Blueprint"
|
|
177
|
+
* src="../unreal/imgs/ListElementOf.png"
|
|
178
|
+
* width="80%"/></a>
|
|
179
|
+
* @endhtmlonly
|
|
180
|
+
*
|
|
181
|
+
* <a href="https://blueprintue.com/blueprint/mf-hwyg5/">
|
|
182
|
+
* <img
|
|
183
|
+
* alt="A InkThread Yield Resume example Blueprint"
|
|
184
|
+
* src="../unreal/imgs/YieldResume.png"
|
|
185
|
+
* width="80%"/></a>
|
|
186
|
+
*
|
|
187
|
+
* @subsubsection ue_example_demo_DemoThread DemoThread
|
|
188
|
+
*
|
|
189
|
+
* <a href="https://blueprintue.com/blueprint/q8wep7r6/">
|
|
190
|
+
* <img
|
|
191
|
+
* alt="Example of the ussage of TagList::GetValue inside processing a new context line."
|
|
192
|
+
* src="../unreal/imgs/TagListGetValue.png"
|
|
193
|
+
* width="80%"/></a>
|
|
194
|
+
*
|
|
195
|
+
* <a href="https://blueprintue.com/blueprint/r5jbthpn/">
|
|
196
|
+
* <img
|
|
197
|
+
* alt="Example for choice handling."
|
|
198
|
+
* src="../unreal/imgs/HandleChoice.png"
|
|
199
|
+
* width="80%"/></a>
|
|
200
|
+
*
|
|
201
|
+
* @subsection ue_example_minimal Minimal
|
|
202
|
+
*
|
|
203
|
+
* <a href="https://blueprintue.com/blueprint/712hsqyl/">
|
|
204
|
+
* <img
|
|
205
|
+
* alt="Minmal InkRuntime Blueprint"
|
|
206
|
+
* src="../unreal/imgs/MinimalRuntime.png"
|
|
207
|
+
* width="80%"/></a>
|
|
208
|
+
*
|
|
209
|
+
* <a href="https://blueprintue.com/blueprint/-da0bqy5/">
|
|
210
|
+
* <img
|
|
211
|
+
* alt="Minimal InkThread Blueprint"
|
|
212
|
+
* src="../unreal/imgs/MinimalThread.png"
|
|
213
|
+
* width="80%"/></a>
|
|
214
|
+
*
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
DECLARE_LOG_CATEGORY_EXTERN(InkCpp, Log, All);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
using System.IO;
|
|
4
|
+
using UnrealBuildTool;
|
|
5
|
+
|
|
6
|
+
public class inkcpp : ModuleRules
|
|
7
|
+
{
|
|
8
|
+
public inkcpp(ReadOnlyTargetRules Target) : base(Target)
|
|
9
|
+
{
|
|
10
|
+
// Enable C++20 support
|
|
11
|
+
PCHUsage = ModuleRules.PCHUsageMode.NoSharedPCHs;
|
|
12
|
+
PrivatePCHHeaderFile = "Public/inkcpp.h";
|
|
13
|
+
CppStandard = CppStandardVersion.Cpp20;
|
|
14
|
+
|
|
15
|
+
PublicIncludePaths.AddRange(
|
|
16
|
+
new string[] {
|
|
17
|
+
Path.Combine(ModuleDirectory, "../shared/Public")
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
PrivateIncludePaths.AddRange(
|
|
23
|
+
new string[] {
|
|
24
|
+
Path.Combine(ModuleDirectory, "../shared/Private"),
|
|
25
|
+
Path.Combine(ModuleDirectory, "Private/ink"),
|
|
26
|
+
Path.Combine(ModuleDirectory, "Public/ink"),
|
|
27
|
+
Path.Combine(ModuleDirectory, "../ThirdParty/Private"),
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
PublicDependencyModuleNames.AddRange(
|
|
33
|
+
new string[]
|
|
34
|
+
{
|
|
35
|
+
"Core",
|
|
36
|
+
// ... add other public dependencies that you statically link with here ...
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
PrivateDependencyModuleNames.AddRange(
|
|
42
|
+
new string[]
|
|
43
|
+
{
|
|
44
|
+
"CoreUObject",
|
|
45
|
+
"Engine",
|
|
46
|
+
"Slate",
|
|
47
|
+
"SlateCore",
|
|
48
|
+
// ... add private dependencies that you statically link with here ...
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
DynamicallyLoadedModuleNames.AddRange(
|
|
54
|
+
new string[]
|
|
55
|
+
{
|
|
56
|
+
// ... add any modules that your module loads dynamically here ...
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#include "InkAssetFactory.h"
|
|
8
|
+
|
|
9
|
+
#include "EditorFramework/AssetImportData.h"
|
|
10
|
+
#include "Misc/FileHelper.h"
|
|
11
|
+
#include "Misc/Paths.h"
|
|
12
|
+
#include "Interfaces/IPluginManager.h"
|
|
13
|
+
#include "Internationalization/Regex.h"
|
|
14
|
+
|
|
15
|
+
#include "InkAsset.h"
|
|
16
|
+
#include "ink/compiler.h"
|
|
17
|
+
#include "inklecate_cmd.cpp"
|
|
18
|
+
|
|
19
|
+
#include <sstream>
|
|
20
|
+
#include <cstdlib>
|
|
21
|
+
#include <filesystem>
|
|
22
|
+
#include <fstream>
|
|
23
|
+
#include <unordered_set>
|
|
24
|
+
#include <cstdio>
|
|
25
|
+
|
|
26
|
+
UInkAssetFactory::UInkAssetFactory(const FObjectInitializer& ObjectInitializer)
|
|
27
|
+
: UFactory(ObjectInitializer), FReimportHandler(), object_ptr(this)
|
|
28
|
+
{
|
|
29
|
+
// Add ink format
|
|
30
|
+
Formats.Add(FString(TEXT("json;")) + NSLOCTEXT("UInkAssetFactory", "FormatInkJSON", "Ink JSON File").ToString());
|
|
31
|
+
Formats.Add(FString(TEXT("ink;")) + NSLOCTEXT("UInkAssetFactory", "FormatInk", "Ink File").ToString());
|
|
32
|
+
|
|
33
|
+
// Set class
|
|
34
|
+
SupportedClass = UInkAsset::StaticClass();
|
|
35
|
+
bCreateNew = false;
|
|
36
|
+
bEditorImport = true;
|
|
37
|
+
|
|
38
|
+
// Fuck data tables TODO - some criteria?
|
|
39
|
+
ImportPriority = 99999;
|
|
40
|
+
FReimportManager::Instance()->RegisterHandler(*this);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
UInkAssetFactory::~UInkAssetFactory() { FReimportManager::Instance()->UnregisterHandler(*this); }
|
|
44
|
+
|
|
45
|
+
/// @todo only finds first include match?
|
|
46
|
+
void TraversImports(
|
|
47
|
+
UAssetImportData& AssetImportData, std::unordered_set<std::filesystem::path>& visited,
|
|
48
|
+
std::filesystem::path filepath
|
|
49
|
+
)
|
|
50
|
+
{
|
|
51
|
+
UE_LOG(
|
|
52
|
+
InkCpp, Display, TEXT("InkAsset Import: Traverse '%s'"), *FString(filepath.string().c_str())
|
|
53
|
+
);
|
|
54
|
+
if (visited.find(filepath) != visited.end()) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
int id = visited.size();
|
|
58
|
+
visited.insert(filepath);
|
|
59
|
+
AssetImportData.AddFileName(
|
|
60
|
+
FString(filepath.string().c_str()), id, id == 0 ? TEXT("MainFile") : TEXT("Include")
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
std::ifstream file(filepath);
|
|
64
|
+
if (! file) {
|
|
65
|
+
UE_LOG(
|
|
66
|
+
InkCpp, Warning, TEXT("Failed to open story file: %s"), *FString(filepath.string().c_str())
|
|
67
|
+
);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
std::stringstream file_data;
|
|
71
|
+
file_data << file.rdbuf();
|
|
72
|
+
FRegexMatcher matcher(
|
|
73
|
+
FRegexPattern(FString("(^|\n)[ \t]*INCLUDE[ \t]+(.*)"), ERegexPatternFlags{0}),
|
|
74
|
+
FString(file_data.str().c_str())
|
|
75
|
+
);
|
|
76
|
+
while (matcher.FindNext()) {
|
|
77
|
+
std::filesystem::path match_file_path = filepath;
|
|
78
|
+
match_file_path.replace_filename(TCHAR_TO_ANSI(*matcher.GetCaptureGroup(2)));
|
|
79
|
+
TraversImports(AssetImportData, visited, match_file_path);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
UObject* UInkAssetFactory::FactoryCreateFile(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, const FString& Filename, const TCHAR* Parms, FFeedbackContext* Warn, bool& bOutOperationCanceled)
|
|
84
|
+
{
|
|
85
|
+
std::stringstream output;
|
|
86
|
+
std::stringstream cmd{};
|
|
87
|
+
const std::string inklecate_cmd = get_inklecate_cmd();
|
|
88
|
+
static const std::string ink_suffix{".ink"};
|
|
89
|
+
try
|
|
90
|
+
{
|
|
91
|
+
using path = std::filesystem::path;
|
|
92
|
+
std::string cFilename = TCHAR_TO_ANSI(*Filename);
|
|
93
|
+
path story_path(cFilename, path::format::generic_format);
|
|
94
|
+
story_path.make_preferred();
|
|
95
|
+
bool use_temp_file = false;
|
|
96
|
+
if (cFilename.size() > ink_suffix.size()
|
|
97
|
+
&& std::equal(ink_suffix.rbegin(), ink_suffix.rend(), cFilename.rbegin()))
|
|
98
|
+
{
|
|
99
|
+
use_temp_file = true;
|
|
100
|
+
if(inklecate_cmd.size() == 0) {
|
|
101
|
+
UE_LOG(InkCpp, Warning, TEXT("Inklecate provided with the plugin, please import ink.json files"));
|
|
102
|
+
return nullptr;
|
|
103
|
+
}
|
|
104
|
+
path path_bin(TCHAR_TO_ANSI(*IPluginManager::Get().FindPlugin(TEXT("InkCPP"))->GetBaseDir()), path::format::generic_format);
|
|
105
|
+
path_bin.make_preferred();
|
|
106
|
+
path_bin /= path(inklecate_cmd, path::format::generic_format).make_preferred();
|
|
107
|
+
const char* filename = std::tmpnam(nullptr);
|
|
108
|
+
if(filename == nullptr) {
|
|
109
|
+
UE_LOG(InkCpp, Error, TEXT("Failed to create temporary file"));
|
|
110
|
+
return nullptr;
|
|
111
|
+
}
|
|
112
|
+
cFilename = filename;
|
|
113
|
+
path json_path(cFilename, path::format::generic_format);
|
|
114
|
+
json_path.make_preferred();
|
|
115
|
+
cmd
|
|
116
|
+
// if std::system start with a quote, the pair of qoute is removed, which leads to errors with pathes with spaces
|
|
117
|
+
// but if the quote is not the first symbol it works fine (a"b" is glued to ab from bash)
|
|
118
|
+
<< path_bin.string()[0] << "\"" << (path_bin.string().c_str() + 1) << "\""
|
|
119
|
+
<< " -o \"" << json_path.string() << "\" "
|
|
120
|
+
<< '"' << story_path.string() << "\" 2>&1";
|
|
121
|
+
auto cmd_str = cmd.str();
|
|
122
|
+
int result = std::system(cmd_str.c_str());
|
|
123
|
+
if (result != 0) {
|
|
124
|
+
UE_LOG(InkCpp, Warning, TEXT("Inklecate failed with exit code %i, executed was: '%s'"), result, *FString(cmd_str.c_str()));
|
|
125
|
+
return nullptr;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
ink::compiler::run(cFilename.c_str(), output);
|
|
129
|
+
if(use_temp_file) {
|
|
130
|
+
std::filesystem::remove(cFilename);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Create ink asset
|
|
134
|
+
UInkAsset* asset = NewObject<UInkAsset>(InParent, InClass, InName, Flags);
|
|
135
|
+
|
|
136
|
+
// Load it up
|
|
137
|
+
std::string data = output.str();
|
|
138
|
+
asset->CompiledStory.SetNum(data.length());
|
|
139
|
+
FMemory::Memcpy(asset->CompiledStory.GetData(), data.c_str(), data.length());
|
|
140
|
+
|
|
141
|
+
// Paths
|
|
142
|
+
std::unordered_set<std::filesystem::path> visited{};
|
|
143
|
+
TraversImports(*asset->AssetImportData, visited, story_path);
|
|
144
|
+
|
|
145
|
+
// Not cancelled
|
|
146
|
+
bOutOperationCanceled = false;
|
|
147
|
+
|
|
148
|
+
// Return
|
|
149
|
+
return asset;
|
|
150
|
+
}
|
|
151
|
+
catch (...)
|
|
152
|
+
{
|
|
153
|
+
// some kind of error?
|
|
154
|
+
return nullptr;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return nullptr;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
bool UInkAssetFactory::FactoryCanImport(const FString& Filename)
|
|
161
|
+
{
|
|
162
|
+
return true; // Fuck you Unreal
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
bool UInkAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames)
|
|
166
|
+
{
|
|
167
|
+
// Can reimport story assets
|
|
168
|
+
UInkAsset* InkAsset = Cast<UInkAsset>(Obj);
|
|
169
|
+
if (InkAsset != nullptr && InkAsset->AssetImportData)
|
|
170
|
+
{
|
|
171
|
+
UE_LOG(InkCpp, Warning, TEXT("Can Reimport"));
|
|
172
|
+
InkAsset->AssetImportData->ExtractFilenames(OutFilenames);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
UE_LOG(InkCpp, Warning, TEXT("Failed to reimport"));
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
void UInkAssetFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths)
|
|
180
|
+
{
|
|
181
|
+
UE_LOG(InkCpp, Warning, TEXT("SetReimportPaths"));
|
|
182
|
+
UInkAsset* InkAsset = Cast<UInkAsset>(Obj);
|
|
183
|
+
if (InkAsset != nullptr && NewReimportPaths.Num() > 0) {
|
|
184
|
+
InkAsset->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
int32 UInkAssetFactory::GetPriority() const
|
|
189
|
+
{
|
|
190
|
+
return ImportPriority;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
TObjectPtr<UObject>* UInkAssetFactory::GetFactoryObject() const
|
|
194
|
+
{
|
|
195
|
+
return const_cast<TObjectPtr<UObject>*>(&object_ptr);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
EReimportResult::Type UInkAssetFactory::Reimport(UObject* Obj, int SourceID)
|
|
199
|
+
{
|
|
200
|
+
UE_LOG(InkCpp, Warning, TEXT("Reimport started"));
|
|
201
|
+
UInkAsset* InkAsset = Cast<UInkAsset>(Obj);
|
|
202
|
+
if (!InkAsset)
|
|
203
|
+
return EReimportResult::Failed;
|
|
204
|
+
|
|
205
|
+
const FString Filename = InkAsset->AssetImportData->GetFirstFilename();
|
|
206
|
+
if (!Filename.Len() || IFileManager::Get().FileSize(*Filename) == INDEX_NONE)
|
|
207
|
+
{
|
|
208
|
+
return EReimportResult::Failed;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Run the import again
|
|
212
|
+
EReimportResult::Type Result = EReimportResult::Failed;
|
|
213
|
+
bool OutCanceled = false;
|
|
214
|
+
|
|
215
|
+
if (ImportObject(InkAsset->GetClass(), InkAsset->GetOuter(), *InkAsset->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled) != nullptr)
|
|
216
|
+
{
|
|
217
|
+
/// TODO: add aditional pathes
|
|
218
|
+
InkAsset->AssetImportData->Update(Filename);
|
|
219
|
+
|
|
220
|
+
// Try to find the outer package so we can dirty it up
|
|
221
|
+
if (InkAsset->GetOuter())
|
|
222
|
+
{
|
|
223
|
+
InkAsset->GetOuter()->MarkPackageDirty();
|
|
224
|
+
}
|
|
225
|
+
else
|
|
226
|
+
{
|
|
227
|
+
InkAsset->MarkPackageDirty();
|
|
228
|
+
}
|
|
229
|
+
Result = EReimportResult::Succeeded;
|
|
230
|
+
}
|
|
231
|
+
else
|
|
232
|
+
{
|
|
233
|
+
Result = EReimportResult::Failed;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return Result;
|
|
237
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include "EditorReimportHandler.h"
|
|
10
|
+
#include "Factories/Factory.h"
|
|
11
|
+
#include "UObject/ObjectMacros.h"
|
|
12
|
+
|
|
13
|
+
#include "InkAssetFactory.generated.h"
|
|
14
|
+
|
|
15
|
+
UCLASS(hidecategories=Object)
|
|
16
|
+
class UInkAssetFactory : public UFactory, public FReimportHandler
|
|
17
|
+
{
|
|
18
|
+
GENERATED_BODY()
|
|
19
|
+
|
|
20
|
+
public:
|
|
21
|
+
UInkAssetFactory(const FObjectInitializer& ObjectInitializer);
|
|
22
|
+
~UInkAssetFactory();
|
|
23
|
+
|
|
24
|
+
// Begin UFactory
|
|
25
|
+
virtual UObject* FactoryCreateFile(UClass* InClass, UObject* InParent, FName InName,
|
|
26
|
+
EObjectFlags Flags, const FString& Filename, const TCHAR* Parms,
|
|
27
|
+
FFeedbackContext* Warn, bool& bOutOperationCanceled) override;
|
|
28
|
+
virtual bool FactoryCanImport(const FString& Filename) override;
|
|
29
|
+
// End UFactory
|
|
30
|
+
|
|
31
|
+
// Begin FReimportHandler
|
|
32
|
+
virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override;
|
|
33
|
+
virtual TObjectPtr<UObject>* GetFactoryObject() const override;
|
|
34
|
+
virtual EReimportResult::Type Reimport(UObject* Obj, int SourceID) override;
|
|
35
|
+
|
|
36
|
+
virtual EReimportResult::Type Reimport(UObject* Obj) override { return Reimport(Obj, 0); }
|
|
37
|
+
|
|
38
|
+
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
|
|
39
|
+
virtual int32 GetPriority() const override;
|
|
40
|
+
// End FReimportHandle
|
|
41
|
+
private:
|
|
42
|
+
TObjectPtr<UObject> object_ptr;
|
|
43
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#include "inkcpp_editor.h"
|
|
8
|
+
|
|
9
|
+
#include "CoreMinimal.h"
|
|
10
|
+
#include "Modules/ModuleManager.h"
|
|
11
|
+
|
|
12
|
+
IMPLEMENT_MODULE(FDefaultGameModuleImpl, inkcpp_editor)
|
|
13
|
+
DEFINE_LOG_CATEGORY(InkCpp);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include "Kismet/GameplayStatics.h"
|
|
10
|
+
#include "string"
|
|
11
|
+
|
|
12
|
+
inline std::string get_inklecate_cmd() {
|
|
13
|
+
FString platform = UGameplayStatics::GetPlatformName();
|
|
14
|
+
if (platform == TEXT("Windows")) {
|
|
15
|
+
return std::string("@INKLECATE_CMD_WIN@");
|
|
16
|
+
} else if (platform == TEXT("Mac")) {
|
|
17
|
+
return std::string("@INKLECATE_CMD_MAC@");
|
|
18
|
+
} else if (platform == TEXT("Linux")) {
|
|
19
|
+
return std::string("@INKLECATE_CMD_LINUX@");
|
|
20
|
+
} else {
|
|
21
|
+
// UE_LOG(InkCpp, Warning, TEXT("Platform: '%s' is not know. For compiling a .ink file a system wide 'inklecate' executable wil be tried to use."), platform);
|
|
22
|
+
return std::string("inklecate");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#pragma once
|
|
8
|
+
#include "Logging/LogMacros.h"
|
|
9
|
+
DECLARE_LOG_CATEGORY_EXTERN(InkCpp, Log, All);
|