inkcpp_rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (273) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/CHANGELOG.md +1 -0
  4. data/Gemfile +10 -0
  5. data/Gemfile.lock +84 -0
  6. data/LICENSE +7 -0
  7. data/README.md +3 -0
  8. data/Rakefile +16 -0
  9. data/bin/console +15 -0
  10. data/bin/setup +10 -0
  11. data/bin/tapioca +29 -0
  12. data/ext/inkcpp_rb/extconf.rb +19 -0
  13. data/ext/inkcpp_rb/inkcpp/.clang-format +99 -0
  14. data/ext/inkcpp_rb/inkcpp/.github/FUNDING.yml +1 -0
  15. data/ext/inkcpp_rb/inkcpp/.github/workflows/build.yml +344 -0
  16. data/ext/inkcpp_rb/inkcpp/.github/workflows/release.yml +49 -0
  17. data/ext/inkcpp_rb/inkcpp/.gitignore +25 -0
  18. data/ext/inkcpp_rb/inkcpp/.gitmodules +9 -0
  19. data/ext/inkcpp_rb/inkcpp/CMakeLists.txt +170 -0
  20. data/ext/inkcpp_rb/inkcpp/CODE_OF_CONDUCT.md +76 -0
  21. data/ext/inkcpp_rb/inkcpp/CONTRIBUTING.md +55 -0
  22. data/ext/inkcpp_rb/inkcpp/Config.cmake.in +2 -0
  23. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/CMakeLists.txt +13 -0
  24. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.c +38 -0
  25. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.cpp +40 -0
  26. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink +8 -0
  27. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink.json +1 -0
  28. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example.zip +0 -0
  29. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/InkCPP_DEMO.zip +0 -0
  30. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/CreateThread.png +0 -0
  31. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/HandleChoice.png +0 -0
  32. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ListElementOf.png +0 -0
  33. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalRuntime.png +0 -0
  34. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalThread.png +0 -0
  35. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ObseverChange.png +0 -0
  36. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/TagListGetValue.png +0 -0
  37. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/YieldResume.png +0 -0
  38. data/ext/inkcpp_rb/inkcpp/Doxyfile +2825 -0
  39. data/ext/inkcpp_rb/inkcpp/LICENSE.txt +22 -0
  40. data/ext/inkcpp_rb/inkcpp/Minimal.runsettings +8 -0
  41. data/ext/inkcpp_rb/inkcpp/README.md +192 -0
  42. data/ext/inkcpp_rb/inkcpp/inkcpp/CMakeLists.txt +67 -0
  43. data/ext/inkcpp_rb/inkcpp/inkcpp/array.h +481 -0
  44. data/ext/inkcpp_rb/inkcpp/inkcpp/avl_array.h +833 -0
  45. data/ext/inkcpp_rb/inkcpp/inkcpp/casting.h +93 -0
  46. data/ext/inkcpp_rb/inkcpp/inkcpp/choice.cpp +54 -0
  47. data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.cpp +124 -0
  48. data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.h +406 -0
  49. data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.cpp +52 -0
  50. data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.h +34 -0
  51. data/ext/inkcpp_rb/inkcpp/inkcpp/executioner.h +179 -0
  52. data/ext/inkcpp_rb/inkcpp/inkcpp/functional.cpp +86 -0
  53. data/ext/inkcpp_rb/inkcpp/inkcpp/functions.cpp +54 -0
  54. data/ext/inkcpp_rb/inkcpp/inkcpp/functions.h +40 -0
  55. data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.cpp +289 -0
  56. data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.h +149 -0
  57. data/ext/inkcpp_rb/inkcpp/inkcpp/header.cpp +44 -0
  58. data/ext/inkcpp_rb/inkcpp/inkcpp/include/choice.h +106 -0
  59. data/ext/inkcpp_rb/inkcpp/inkcpp/include/functional.h +327 -0
  60. data/ext/inkcpp_rb/inkcpp/inkcpp/include/globals.h +196 -0
  61. data/ext/inkcpp_rb/inkcpp/inkcpp/include/list.h +187 -0
  62. data/ext/inkcpp_rb/inkcpp/inkcpp/include/runner.h +291 -0
  63. data/ext/inkcpp_rb/inkcpp/inkcpp/include/snapshot.h +61 -0
  64. data/ext/inkcpp_rb/inkcpp/inkcpp/include/story.h +219 -0
  65. data/ext/inkcpp_rb/inkcpp/inkcpp/include/story_ptr.h +233 -0
  66. data/ext/inkcpp_rb/inkcpp/inkcpp/include/traits.h +270 -0
  67. data/ext/inkcpp_rb/inkcpp/inkcpp/include/types.h +169 -0
  68. data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.cpp +79 -0
  69. data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.h +39 -0
  70. data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.cpp +276 -0
  71. data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.h +356 -0
  72. data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.cpp +841 -0
  73. data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.h +450 -0
  74. data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.cpp +40 -0
  75. data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.h +529 -0
  76. data/ext/inkcpp_rb/inkcpp/inkcpp/operation_bases.h +164 -0
  77. data/ext/inkcpp_rb/inkcpp/inkcpp/operations.h +100 -0
  78. data/ext/inkcpp_rb/inkcpp/inkcpp/output.cpp +528 -0
  79. data/ext/inkcpp_rb/inkcpp/inkcpp/output.h +153 -0
  80. data/ext/inkcpp_rb/inkcpp/inkcpp/platform.h +22 -0
  81. data/ext/inkcpp_rb/inkcpp/inkcpp/random.h +38 -0
  82. data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.cpp +1396 -0
  83. data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.h +336 -0
  84. data/ext/inkcpp_rb/inkcpp/inkcpp/simple_restorable_stack.h +335 -0
  85. data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.cpp +182 -0
  86. data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.h +91 -0
  87. data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_interface.h +57 -0
  88. data/ext/inkcpp_rb/inkcpp/inkcpp/stack.cpp +618 -0
  89. data/ext/inkcpp_rb/inkcpp/inkcpp/stack.h +243 -0
  90. data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.cpp +361 -0
  91. data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.h +92 -0
  92. data/ext/inkcpp_rb/inkcpp/inkcpp/story_ptr.cpp +75 -0
  93. data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.cpp +125 -0
  94. data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.h +67 -0
  95. data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.cpp +149 -0
  96. data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.h +47 -0
  97. data/ext/inkcpp_rb/inkcpp/inkcpp/string_utils.h +207 -0
  98. data/ext/inkcpp_rb/inkcpp/inkcpp/system.cpp +39 -0
  99. data/ext/inkcpp_rb/inkcpp/inkcpp/tuple.hpp +151 -0
  100. data/ext/inkcpp_rb/inkcpp/inkcpp/value.cpp +279 -0
  101. data/ext/inkcpp_rb/inkcpp/inkcpp/value.h +666 -0
  102. data/ext/inkcpp_rb/inkcpp/inkcpp_c/CMakeLists.txt +62 -0
  103. data/ext/inkcpp_rb/inkcpp/inkcpp_c/include/inkcpp.h +393 -0
  104. data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp.cpp +344 -0
  105. data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp_c.pc.in +10 -0
  106. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/ExternalFunction.c +56 -0
  107. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Globals.c +98 -0
  108. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Lists.c +73 -0
  109. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Observer.c +36 -0
  110. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Snapshot.c +65 -0
  111. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/CMakeLists.txt +49 -0
  112. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/inkcpp_cl.cpp +215 -0
  113. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.cpp +209 -0
  114. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.h +8 -0
  115. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/CMakeLists.txt +37 -0
  116. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.cpp +446 -0
  117. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.h +70 -0
  118. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.cpp +166 -0
  119. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.h +79 -0
  120. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/command.cpp +107 -0
  121. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/compiler.cpp +96 -0
  122. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.cpp +62 -0
  123. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.h +104 -0
  124. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compilation_results.h +22 -0
  125. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compiler.h +44 -0
  126. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json.hpp +24596 -0
  127. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.cpp +411 -0
  128. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.h +62 -0
  129. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.cpp +47 -0
  130. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.h +70 -0
  131. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.cpp +107 -0
  132. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.h +55 -0
  133. data/ext/inkcpp_rb/inkcpp/inkcpp_py/CMakeLists.txt +19 -0
  134. data/ext/inkcpp_rb/inkcpp/inkcpp_py/example.py +78 -0
  135. data/ext/inkcpp_rb/inkcpp/inkcpp_py/src/module.cpp +317 -0
  136. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/conftest.py +53 -0
  137. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_ExternalFunctions.py +35 -0
  138. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Globals.py +40 -0
  139. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Lists.py +43 -0
  140. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Observer.py +27 -0
  141. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Snapshot.py +57 -0
  142. data/ext/inkcpp_rb/inkcpp/inkcpp_py/unreal_example.ink +71 -0
  143. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Array.cpp +115 -0
  144. data/ext/inkcpp_rb/inkcpp/inkcpp_test/CMakeLists.txt +117 -0
  145. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Callstack.cpp +392 -0
  146. data/ext/inkcpp_rb/inkcpp/inkcpp_test/EmptyStringForDivert.cpp +36 -0
  147. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ExternalFunctionsExecuteProperly.cpp +34 -0
  148. data/ext/inkcpp_rb/inkcpp/inkcpp_test/FallbackFunction.cpp +77 -0
  149. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Globals.cpp +73 -0
  150. data/ext/inkcpp_rb/inkcpp/inkcpp_test/InkyJson.cpp +34 -0
  151. data/ext/inkcpp_rb/inkcpp/inkcpp_test/LabelCondition.cpp +60 -0
  152. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Lists.cpp +144 -0
  153. data/ext/inkcpp_rb/inkcpp/inkcpp_test/LookaheadSafe.cpp +46 -0
  154. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Main.cpp +7 -0
  155. data/ext/inkcpp_rb/inkcpp/inkcpp_test/MoveTo.cpp +95 -0
  156. data/ext/inkcpp_rb/inkcpp/inkcpp_test/NewLines.cpp +76 -0
  157. data/ext/inkcpp_rb/inkcpp/inkcpp_test/NoEarlyTags.cpp +33 -0
  158. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Observer.cpp +245 -0
  159. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Pointer.cpp +191 -0
  160. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Restorable.cpp +294 -0
  161. data/ext/inkcpp_rb/inkcpp/inkcpp_test/SpaceAfterBracketChoice.cpp +45 -0
  162. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Stack.cpp +224 -0
  163. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Tags.cpp +131 -0
  164. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ThirdTierChoiceAfterBrackets.cpp +38 -0
  165. data/ext/inkcpp_rb/inkcpp/inkcpp_test/UTF8.cpp +56 -0
  166. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Value.cpp +210 -0
  167. data/ext/inkcpp_rb/inkcpp/inkcpp_test/catch.hpp +17970 -0
  168. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/AHF.ink +7 -0
  169. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ChoiceBracketStory.ink +7 -0
  170. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/EmptyStringForDivert.ink +13 -0
  171. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ExternalFunctionsExecuteProperly.ink +11 -0
  172. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/FallBack.ink +15 -0
  173. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/GlobalStory.ink +9 -0
  174. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LabelConditionStory.ink +5 -0
  175. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LinesStory.ink +42 -0
  176. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListLogicStory.ink +40 -0
  177. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListStory.ink +8 -0
  178. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LookaheadSafe.ink +14 -0
  179. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/MoveTo.ink +36 -0
  180. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/NoEarlyTags.ink +19 -0
  181. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ObserverStory.ink +8 -0
  182. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/SimpleStoryFlow.ink +65 -0
  183. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TagsStory.ink +22 -0
  184. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TheIntercept.ink +1686 -0
  185. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ThirdTierChoiceAfterBracketsStory.ink +13 -0
  186. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF-8-demo.txt +212 -0
  187. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF8Story.ink +218 -0
  188. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inklecate.json +154 -0
  189. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inky.json +160 -0
  190. data/ext/inkcpp_rb/inkcpp/notes/ArchitectureNotes.md +54 -0
  191. data/ext/inkcpp_rb/inkcpp/notes/ListNotes.md +69 -0
  192. data/ext/inkcpp_rb/inkcpp/notes/OperationNotes.md +35 -0
  193. data/ext/inkcpp_rb/inkcpp/notes/TagsNotes.md +24 -0
  194. data/ext/inkcpp_rb/inkcpp/notes/WhitespaceNotes.md +28 -0
  195. data/ext/inkcpp_rb/inkcpp/proofing/README.md +3 -0
  196. data/ext/inkcpp_rb/inkcpp/proofing/inkcpp_runtime_driver +12 -0
  197. data/ext/inkcpp_rb/inkcpp/pyproject.toml +63 -0
  198. data/ext/inkcpp_rb/inkcpp/setup.py +166 -0
  199. data/ext/inkcpp_rb/inkcpp/shared/CMakeLists.txt +14 -0
  200. data/ext/inkcpp_rb/inkcpp/shared/private/command.h +172 -0
  201. data/ext/inkcpp_rb/inkcpp/shared/private/header.h +46 -0
  202. data/ext/inkcpp_rb/inkcpp/shared/public/config.h +53 -0
  203. data/ext/inkcpp_rb/inkcpp/shared/public/system.h +307 -0
  204. data/ext/inkcpp_rb/inkcpp/shared/public/version.h +14 -0
  205. data/ext/inkcpp_rb/inkcpp/tests/TestAllSequenceTypes.ink +59 -0
  206. data/ext/inkcpp_rb/inkcpp/tests/TestArithmetic.ink +17 -0
  207. data/ext/inkcpp_rb/inkcpp/tests/TestBasicStringLiterals.ink +8 -0
  208. data/ext/inkcpp_rb/inkcpp/tests/TestBasicTunnel.ink +10 -0
  209. data/ext/inkcpp_rb/inkcpp/tests/TestBlanksInInlineSequences.ink +51 -0
  210. data/ext/inkcpp_rb/inkcpp/tests/TestCallStackEvaluation.ink +15 -0
  211. data/ext/inkcpp_rb/inkcpp/tests/TestChoiceCount.ink +15 -0
  212. data/ext/inkcpp_rb/inkcpp/tests/TestChoiceDivertsToDone.ink +6 -0
  213. data/ext/inkcpp_rb/inkcpp/tests/TestChoiceWithBracketsOnly.ink +9 -0
  214. data/ext/inkcpp_rb/inkcpp/tests/TestCompareDivertTargets.ink +26 -0
  215. data/ext/inkcpp_rb/inkcpp/tests/TestComplexTunnels.ink +22 -0
  216. data/ext/inkcpp_rb/inkcpp/tests/TestConditionalChoiceInWeave.ink +19 -0
  217. data/ext/inkcpp_rb/inkcpp/tests/TestTunnelOnwardsAfterTunnel.ink +17 -0
  218. data/ext/inkcpp_rb/inkcpp/unreal/CMakeLists.txt +51 -0
  219. data/ext/inkcpp_rb/inkcpp/unreal/UE_example.ink +92 -0
  220. data/ext/inkcpp_rb/inkcpp/unreal/blueprint_filter.js +377 -0
  221. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Resources/Icon128.png +0 -0
  222. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkAsset.cpp +47 -0
  223. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkChoice.cpp +40 -0
  224. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkList.cpp +86 -0
  225. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkRuntime.cpp +265 -0
  226. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkThread.cpp +239 -0
  227. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkVar.cpp +143 -0
  228. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/TagList.cpp +95 -0
  229. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/inkcpp.cpp +13 -0
  230. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h +50 -0
  231. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h +58 -0
  232. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h +139 -0
  233. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkList.h +102 -0
  234. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h +177 -0
  235. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h +30 -0
  236. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkThread.h +215 -0
  237. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkVar.h +245 -0
  238. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/TagList.h +77 -0
  239. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h +217 -0
  240. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/inkcpp.Build.cs +62 -0
  241. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.cpp +237 -0
  242. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.h +43 -0
  243. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inkcpp_editor.cpp +13 -0
  244. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inklecate_cmd.cpp.in +24 -0
  245. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Public/inkcpp_editor.h +9 -0
  246. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/inkcpp_editor.Build.cs +61 -0
  247. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/inkcpp.uplugin +44 -0
  248. data/ext/inkcpp_rb/inkcpp/unreal/render.css +1 -0
  249. data/ext/inkcpp_rb/inkcpp_rb.cpp +321 -0
  250. data/inkcpp_rb.gemspec +54 -0
  251. data/rbi/inkcpp_rb.rbi +211 -0
  252. data/sorbet/config +4 -0
  253. data/sorbet/rbi/annotations/.gitattributes +1 -0
  254. data/sorbet/rbi/annotations/minitest.rbi +119 -0
  255. data/sorbet/rbi/gems/.gitattributes +1 -0
  256. data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
  257. data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
  258. data/sorbet/rbi/gems/minitest@5.25.4.rbi +1547 -0
  259. data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
  260. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  261. data/sorbet/rbi/gems/prism@1.3.0.rbi +40040 -0
  262. data/sorbet/rbi/gems/rake-compiler@1.2.8.rbi +9 -0
  263. data/sorbet/rbi/gems/rake@13.2.1.rbi +3033 -0
  264. data/sorbet/rbi/gems/rbi@0.2.2.rbi +4527 -0
  265. data/sorbet/rbi/gems/rice@4.3.3.rbi +44 -0
  266. data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
  267. data/sorbet/rbi/gems/tapioca@0.16.7.rbi +3611 -0
  268. data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
  269. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
  270. data/sorbet/rbi/gems/yard@0.9.37.rbi +18379 -0
  271. data/sorbet/tapioca/config.yml +13 -0
  272. data/sorbet/tapioca/require.rb +4 -0
  273. metadata +400 -0
@@ -0,0 +1,55 @@
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 "compilation_results.h"
10
+ #include <sstream>
11
+
12
+ namespace ink::compiler::internal
13
+ {
14
+ class error_strbuf : public std::stringbuf
15
+ {
16
+ public:
17
+ // start a new error message to be outputted to a given list
18
+ void start(error_list* list);
19
+
20
+ // If set, the next sync will throw an exception
21
+ void throw_on_sync(bool);
22
+ protected:
23
+ virtual int sync() override;
24
+
25
+ private:
26
+ error_list* _list = nullptr;
27
+ bool _throw = false;
28
+ };
29
+
30
+ class reporter
31
+ {
32
+ protected:
33
+ reporter();
34
+ virtual ~reporter() { }
35
+
36
+ // sets the results pointer for this reporter
37
+ void set_results(compilation_results*);
38
+
39
+ // clears the results pointer
40
+ void clear_results();
41
+
42
+ // report warning
43
+ std::ostream& warn();
44
+
45
+ // report error
46
+ std::ostream& err();
47
+
48
+ // report critical error
49
+ std::ostream& crit();
50
+ private:
51
+ compilation_results* _results;
52
+ error_strbuf _buffer;
53
+ std::ostream _stream;
54
+ };
55
+ } // namespace ink::compiler::internal
@@ -0,0 +1,19 @@
1
+ add_subdirectory(pybind11)
2
+ pybind11_add_module(inkcpp_py src/module.cpp)
3
+ target_compile_definitions(inkcpp_py PRIVATE VERSION_INFO=${VERSION})
4
+
5
+ target_link_libraries(inkcpp_py PUBLIC inkcpp inkcpp_compiler inkcpp_shared)
6
+
7
+
8
+ # For https://en.cppreference.com/w/cpp/filesystem#Notes
9
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
10
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.1")
11
+ target_link_libraries(inkcpp_py PRIVATE stdc++fs)
12
+ endif()
13
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
14
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0")
15
+ target_link_libraries(inkcpp_py PRIVATE stdc++fs)
16
+ endif()
17
+ endif()
18
+
19
+ install(TARGETS inkcpp_py DESTINATION . COMPONENT py EXCLUDE_FROM_ALL)
@@ -0,0 +1,78 @@
1
+ #!/bin/python
2
+
3
+ import inkcpp_py
4
+ import sys
5
+ import os
6
+
7
+ story_ink = 'unreal_example.ink'
8
+ story_json = 'unreal_example.ink.json'
9
+ story_bin = 'unreal_example.bin'
10
+
11
+
12
+ # convert .ink / .json file to .bin file
13
+ if not os.path.exists(story_bin):
14
+ if not os.path.exists(story_json):
15
+ os.system('inklecate {}'.format(story_ink))
16
+ inkcpp_py.compile_json(story_json, story_bin)
17
+
18
+ # load story and maybe snapshot
19
+ story = inkcpp_py.Story.from_file(story_bin)
20
+ if len(sys.argv) > 1:
21
+ snap = inkcpp_py.Snapshot.from_file(sys.argv[1])
22
+ globals = story.new_globals_from_snapshot(snap)
23
+ runner = story.new_runner_from_snapshot(snap, globals)
24
+ else:
25
+ globals = story.new_globals()
26
+ runner = story.new_runner(globals)
27
+
28
+ # access global variables
29
+ print("Date: ", globals.date)
30
+ globals.date = inkcpp_py.Value("17.12.2023")
31
+ bg = globals.background.as_list();
32
+ print(bg)
33
+ bg.add('b')
34
+ print(bg)
35
+ bg.remove('a')
36
+ print(bg)
37
+ globals.background = inkcpp_py.Value(bg)
38
+
39
+ # observer examples
40
+ def ob_delta(x, y):
41
+ print("from:",y,"to:",x)
42
+
43
+ globals.observe("brightness", ob_delta)
44
+
45
+
46
+ # external function with no input, but return value
47
+ def greeting(a):
48
+ return inkcpp_py.Value("Tach")
49
+ runner.bind("GetGreeting", greeting)
50
+
51
+ # external function with no return value
52
+ def brightness(args):
53
+ print("Set Brightness: ", args[0])
54
+ runner.bind_void("SetBrightness", brightness)
55
+
56
+ # simple story stepper
57
+ while True:
58
+ while runner.can_continue():
59
+ print(runner.getline())
60
+ print("# tags: ", end="")
61
+ print(', '.join(runner.tags()))
62
+ if runner.has_choices():
63
+ print()
64
+ index = 1
65
+ for c in runner:
66
+ print(str(index) + ": " + c.text())
67
+ print("\t"+', '.join(c.tags()))
68
+ index += 1
69
+ index = int(input('Select choice to continue: '))
70
+ if index == -1:
71
+ snap = runner.create_snapshot();
72
+ snap.write_to_file("story.snap");
73
+ break
74
+ else:
75
+ runner.choose(index - 1)
76
+ else:
77
+ break
78
+ print("Finish")
@@ -0,0 +1,317 @@
1
+ #include "compilation_results.h"
2
+ #include "story_ptr.h"
3
+ #include "types.h"
4
+ #include <pybind11/attr.h>
5
+ #include <pybind11/cast.h>
6
+ #include <pybind11/detail/common.h>
7
+ #include <pybind11/pybind11.h>
8
+ #include <pybind11/pytypes.h>
9
+ #include <pybind11/stl.h>
10
+ #include <pybind11/functional.h>
11
+
12
+ namespace py = pybind11;
13
+
14
+ #include <story.h>
15
+ #include <runner.h>
16
+ #include <compiler.h>
17
+ #include <choice.h>
18
+ #include <globals.h>
19
+ #include <snapshot.h>
20
+
21
+ #include <sstream>
22
+ #include <functional>
23
+
24
+ using runner = ink::runtime::runner_interface;
25
+ using runner_ptr = ink::runtime::runner;
26
+ using globals = ink::runtime::globals_interface;
27
+ using globals_ptr = ink::runtime::globals;
28
+ using story = ink::runtime::story;
29
+ using choice = ink::runtime::choice;
30
+ using value = ink::runtime::value;
31
+ using list = ink::runtime::list_interface;
32
+ using snapshot = ink::runtime::snapshot;
33
+
34
+ PYBIND11_DECLARE_HOLDER_TYPE(T, ink::runtime::story_ptr<T>);
35
+
36
+ struct StringValueWrap : public value {
37
+ StringValueWrap(const std::string& s)
38
+ : value()
39
+ , str{s}
40
+ {
41
+ static_cast<value&>(*this) = value(str.c_str());
42
+ }
43
+
44
+ ~StringValueWrap() {}
45
+
46
+ std::string str;
47
+ };
48
+
49
+ std::string list_to_str(const list& list)
50
+ {
51
+ std::stringstream out;
52
+ out << "[";
53
+ bool first = true;
54
+ for (const auto& flag : list) {
55
+ if (first) {
56
+ first = false;
57
+ } else {
58
+ out << ", ";
59
+ }
60
+ out << flag;
61
+ }
62
+ out << "]";
63
+ return out.str();
64
+ }
65
+
66
+ PYBIND11_MODULE(inkcpp_py, m)
67
+ {
68
+ m.doc()
69
+ = "Python bindings for InkCPP https://github.com/JBenda/inkcpp"; // optional module docstring
70
+
71
+ py::class_<story>(m, "Story")
72
+ .def("from_file", &story::from_file, "Creates a new story from a .bin file")
73
+ .def("new_globals", &story::new_globals, "creates new globals store for the current story")
74
+ .def("new_runner", [](story& self) { return self.new_runner(); })
75
+ .def("new_runner", &story::new_runner, "creates a new runner for the current story")
76
+ .def("new_globals_from_snapshot", &story::new_globals_from_snapshot)
77
+ .def("new_runner_from_snapshot", &story::new_runner_from_snapshot)
78
+ .def(
79
+ "new_runner_from_snapshot", [](story& self, const snapshot& snap, globals_ptr store
80
+ ) { return self.new_runner_from_snapshot(snap, store); }
81
+ )
82
+ .def("new_runner_from_snapshot", [](story& self, const snapshot& snap) {
83
+ return self.new_runner_from_snapshot(snap);
84
+ });
85
+
86
+ py::class_<globals, globals_ptr>(m, "Globals")
87
+ .def(
88
+ "create_snapshot", &globals::create_snapshot,
89
+ "Creates a snapshot from the current state for later usage"
90
+ )
91
+ .def(
92
+ "observe",
93
+ [](globals& self, const char* name,
94
+ std::function<void(const value&, ink::optional<const value>)> f) {
95
+ self.observe(name, f);
96
+ },
97
+ "Get a call with the new and old value (this could be None) each time the variable "
98
+ "changes"
99
+ )
100
+ .def(
101
+ "__getattr__",
102
+ [](const globals& self, const std::string& key) {
103
+ auto res = self.get<value>(key.c_str());
104
+ if (! res.has_value()) {
105
+ throw py::key_error(std::string("No global variable with name '") + key + "' found");
106
+ }
107
+ return res.value();
108
+ },
109
+ "Access global varible if exists, if not throws an key_error"
110
+ )
111
+ .def("__setattr__", [](globals& self, const std::string& key, const value& val) {
112
+ if (! self.set<value>(key.c_str(), val)) {
113
+ throw py::key_error(
114
+ std::string("No global variable with name '") + key
115
+ + "' found or you are trying to override a non string variable with a string"
116
+ );
117
+ }
118
+ });
119
+
120
+ py::class_<list, std::unique_ptr<list, py::nodelete>> py_list(
121
+ m, "List",
122
+ "Allows reading and editing inkcpp lists. !Only valid until next choose ore getline a runner "
123
+ "referncing the corresponding global"
124
+ );
125
+ py_list.def("add", &list::add, "Add flag to list")
126
+ .def("remove", &list::remove, "Remove flag from list")
127
+ .def("contains", &list::contains, "Check if list contains the given flag")
128
+ .def(
129
+ "flags_from",
130
+ [](const list& self, const char* list_name) {
131
+ return py::make_iterator(self.begin(list_name), self.end());
132
+ },
133
+ "Rerutrns all flags contained in list from a list", py::keep_alive<0, 1>()
134
+ )
135
+ .def(
136
+ "__iter__", [](const list& self) { return py::make_iterator(self.begin(), self.end()); },
137
+ py::keep_alive<0, 1>()
138
+ )
139
+ .def("__str__", &list_to_str);
140
+ py::class_<list::iterator::Flag>(
141
+ py_list, "Flag", "A list flag containing the name of the flag and the corresponding list"
142
+ )
143
+ .def_readonly("name", &list::iterator::Flag::flag_name, "The flag")
144
+ .def_readonly(
145
+ "list_name", &list::iterator::Flag::list_name, "Name of the corresponding list"
146
+ );
147
+
148
+ py::class_<value> py_value(m, "Value", "A Value of a Ink Variable");
149
+ py_value.def_readonly("type", &value::type, "Type contained in value");
150
+ py_value.def(py::init<>());
151
+ py_value.def(py::init<bool>());
152
+ py_value.def("__init__", [](value& self, uint32_t v, value::Type type) {
153
+ if (type != value::Type::Uint32) {
154
+ throw py::key_error("only use this signture if you want to explicit pass a uint");
155
+ }
156
+ self = value(v);
157
+ });
158
+ py_value.def(py::init<int32_t>());
159
+ py_value.def(py::init<float>());
160
+ py_value.def(py::init<list*>());
161
+ py_value.def(py::init([](const std::string& str) { return new StringValueWrap(str); }));
162
+ py_value.def(
163
+ "as_list",
164
+ [](const value& self) {
165
+ if (self.type != value::Type::List) {
166
+ throw py::attribute_error("Try to access list of non list value");
167
+ }
168
+ return self.get<value::Type::List>();
169
+ },
170
+ py::return_value_policy::reference
171
+ );
172
+ py_value.def("__str__", [](const value& self) {
173
+ switch (self.type) {
174
+ case value::Type::Bool: return std::string(self.get<value::Type::Bool>() ? "true" : "false");
175
+ case value::Type::Uint32: return std::to_string(self.get<value::Type::Uint32>());
176
+ case value::Type::Int32: return std::to_string(self.get<value::Type::Int32>());
177
+ case value::Type::String: return std::string(self.get<value::Type::String>());
178
+ case value::Type::Float: return std::to_string(self.get<value::Type::Float>());
179
+ case value::Type::List: {
180
+ return list_to_str(*self.get<value::Type::List>());
181
+ }
182
+ }
183
+ throw py::attribute_error("value is in an invalid state");
184
+ });
185
+
186
+ py::enum_<value::Type>(py_value, "Type")
187
+ .value("Bool", value::Type::Bool)
188
+ .value("Uint32", value::Type::Uint32)
189
+ .value("Int32", value::Type::Int32)
190
+ .value("String", value::Type::String)
191
+ .value("Float", value::Type::Float)
192
+ .value("List", value::Type::List)
193
+ .export_values();
194
+
195
+ py::class_<runner, runner_ptr>(m, "Runner")
196
+ .def(
197
+ "create_snapshot", &runner::create_snapshot,
198
+ "Creates a snapshot from the current state for later usage"
199
+ )
200
+ .def("can_continue", &runner::can_continue, "check if there is content left in story")
201
+ .def(
202
+ "getline", static_cast<std::string (runner::*)()>(&runner::getline),
203
+ "Get content of one output line"
204
+ )
205
+ .def(
206
+ "getall", static_cast<std::string (runner::*)()>(&runner::getall),
207
+ "execute getline and append until can_continue is false"
208
+ )
209
+ .def("has_tags", &runner::has_tags, "Where there tags since last getline?")
210
+ .def("num_tags", &runner::num_tags, "Number of tags currently stored")
211
+ .def(
212
+ "get_tag", &runner::get_tag, "Get Tag currently stored at position i",
213
+ py::return_value_policy::reference_internal
214
+ )
215
+ .def(
216
+ "tags",
217
+ [](const runner& self) {
218
+ std::vector<const char*> tags(self.num_tags());
219
+ for (size_t i = 0; i < self.num_tags(); ++i) {
220
+ tags[i] = self.get_tag(i);
221
+ }
222
+ return tags;
223
+ },
224
+ "Get all current assigned tags"
225
+ )
226
+ .def(
227
+ "has_choices", &runner::has_choices,
228
+ "Check if there is at least one open choice at the moment."
229
+ )
230
+ .def(
231
+ "get_choice", &runner::get_choice, "Get current choice at index",
232
+ py::return_value_policy::reference_internal
233
+ )
234
+ .def("num_choices", &runner::num_choices, "Number of current open choices")
235
+ .def(
236
+ "__iter__",
237
+ [](const runner& self) { return py::make_iterator(self.begin(), self.end()); },
238
+ py::keep_alive<0, 1>()
239
+ )
240
+ .def("choose", &runner::choose, "Select a choice to continue")
241
+ .def(
242
+ "bind_void",
243
+ [](runner& self, const char* function_name, std::function<void(std::vector<value>)> f,
244
+ bool lookaheadSafe) {
245
+ self.bind(
246
+ function_name,
247
+ [f](size_t len, const value* vals) {
248
+ std::vector args(vals, vals + len);
249
+ f(args);
250
+ },
251
+ lookaheadSafe
252
+ );
253
+ },
254
+ py::arg("function_name"), py::arg("function"), py::arg_v("lookaheadSafe", false),
255
+ "Bind function with void result"
256
+ )
257
+ .def(
258
+ "bind",
259
+ [](runner& self, const char* function_name, std::function<value(std::vector<value>)> f,
260
+ bool lookaheadSafe) {
261
+ self.bind(function_name, [f](size_t len, const value* vals) {
262
+ std::vector args(vals, vals + len);
263
+ return f(args);
264
+ });
265
+ },
266
+ py::arg("function_name"), py::arg("function"), py::arg_v("lookaheadSafe", false),
267
+ "Bind a function with return value"
268
+ )
269
+ .def(
270
+ "move_to",
271
+ [](runner& self, const char* path) -> bool {
272
+ return self.move_to(ink::hash_string(path));
273
+ },
274
+ "Moves execution pointer to start of container desrcipet by the path"
275
+ );
276
+ py::class_<choice>(m, "Choice")
277
+ .def("text", &choice::text, "Get choice printable content")
278
+ .def("has_tags", &choice::has_tags, "if choices is tagged?")
279
+ .def("num_tags", &choice::num_tags, "Number of tags assigned to choice")
280
+ .def(
281
+ "get_tag", &choice::get_tag, "Get tag at index",
282
+ py::return_value_policy::reference_internal
283
+ )
284
+ .def(
285
+ "tags",
286
+ [](const choice& self) {
287
+ std::vector<const char*> tags(self.num_tags());
288
+ for (size_t i = 0; i < self.num_tags(); ++i) {
289
+ tags[i] = self.get_tag(i);
290
+ }
291
+ return tags;
292
+ },
293
+ "Get all current assinged tags"
294
+ );
295
+ py::class_<snapshot>(
296
+ m, "Snapshot", "Globals and all assoziatet runner stored for later restoration"
297
+ )
298
+ .def("num_runners", &snapshot::num_runners, "Number of different runners stored in snapshot")
299
+ .def("write_to_file", &snapshot::write_to_file, "Store snapshot in file")
300
+ .def("from_file", &snapshot::from_file, "Load snapshot from file");
301
+ m.def(
302
+ "compile_json",
303
+ [](const char* input_file_name, const char* output_filen_ame) {
304
+ ink::compiler::compilation_results results;
305
+ ink::compiler::run(input_file_name, output_filen_ame, &results);
306
+ if (! results.errors.empty()) {
307
+ std::string str;
308
+ for (auto& error : results.errors) {
309
+ str += error;
310
+ str += '\n';
311
+ }
312
+ throw py::value_error(str);
313
+ }
314
+ },
315
+ "Converts a story.json file to a story.bin file used by inkcpp"
316
+ );
317
+ }
@@ -0,0 +1,53 @@
1
+ import pytest
2
+ import os
3
+ import sys
4
+ import inkcpp_py as ink
5
+
6
+ @pytest.fixture(scope='session', autouse=True)
7
+ def inklecate_cmd():
8
+ res = os.getenv("INKLECATE")
9
+ if res is None or res == "":
10
+ return "inklecate"
11
+ return res
12
+
13
+
14
+ def extract_paths(tmpdir):
15
+ def res(ink_source):
16
+ name = os.path.splitext(os.path.basename(ink_source))[0]
17
+ return (
18
+ name,
19
+ list(map(lambda x: tmpdir + ("/" + name + x), [".bin", ".tmp"])) + ["./inkcpp_test/ink/" + ink_source]
20
+ )
21
+ return res
22
+
23
+ @pytest.fixture(scope='session', autouse=True)
24
+ def story_path(tmpdir_factory):
25
+ tmpdir = tmpdir_factory.getbasetemp()
26
+ # tmpdir = os.fsencode('/tmp/pytest')
27
+ return {name: files
28
+ for (name, files) in map(extract_paths(tmpdir),
29
+ filter(
30
+ lambda file: os.path.splitext(file)[1] == ".ink",
31
+ os.listdir("./inkcpp_test/ink/")))}
32
+
33
+ @pytest.fixture(scope='session', autouse=True)
34
+ def assets(story_path, inklecate_cmd):
35
+ res = {}
36
+ for (name, files) in story_path.items():
37
+ if not os.path.exists(files[0]):
38
+ if not os.path.exists(files[1]):
39
+ os.system('{} -o {} {}'.format(inklecate_cmd, files[1], files[2]))
40
+ ink.compile_json(str(files[1]), str(files[0]))
41
+ res[name] = ink.Story.from_file(str(files[0]))
42
+ return res
43
+
44
+ @pytest.fixture(scope='session', autouse=True)
45
+ def generate():
46
+ def g(asset):
47
+ store = asset.new_globals()
48
+ return [
49
+ asset,
50
+ store,
51
+ asset.new_runner(store),
52
+ ]
53
+ return g
@@ -0,0 +1,35 @@
1
+ import inkcpp_py as ink
2
+ import pytest
3
+ import os
4
+
5
+ class Cnt:
6
+ def __init__(self):
7
+ self.cnt = 0
8
+ def __call__(self, _):
9
+ self.cnt += 1
10
+ class TestExternalFunctions:
11
+ def test_lookaheadSafe(self, assets, generate):
12
+ cnt = Cnt()
13
+ [story, globals, runner] = generate(assets['LookaheadSafe'])
14
+ runner.bind_void("foo", cnt, True)
15
+ out = runner.getline()
16
+ assert out == "Call1 glued to Call 2\n"
17
+ assert cnt.cnt == 3
18
+ out = runner.getline()
19
+ assert out == "Call 3 is seperated\n"
20
+ assert cnt.cnt == 4
21
+
22
+ def test_lookahadeUnsafe(self, assets, generate):
23
+ cnt = Cnt()
24
+ [story, globals, runner] = generate(assets['LookaheadSafe'])
25
+ runner.bind_void("foo", cnt)
26
+ out = runner.getline()
27
+ assert out == "Call1\n"
28
+ assert cnt.cnt == 1
29
+ out = runner.getline()
30
+ assert out == "glued to Call 2\n"
31
+ assert cnt.cnt == 2
32
+ out = runner.getline()
33
+ assert out == "Call 3 is seperated\n"
34
+ assert cnt.cnt == 3
35
+
@@ -0,0 +1,40 @@
1
+ import inkcpp_py as ink
2
+ import pytest
3
+
4
+
5
+ class TestGlobals:
6
+ def test_reading_globals(self, assets, generate):
7
+ [story, globals, runner] = generate(assets['GlobalStory'])
8
+
9
+ assert runner.getline() == "My name is Jean Passepartout, but my friend's call me Jackie. I'm 23 years old.\n"
10
+ assert runner.getline() == "Foo:23\n"
11
+
12
+ val = globals.age
13
+ assert val.type == ink.Value.Int32 and str(val) == '23'
14
+ val = globals.friendly_name_of_player
15
+ assert val.type == ink.Value.String and str(val) == 'Jackie'
16
+
17
+ def test_writing_globals(self, assets, generate):
18
+ [story, globals, runner] = generate(assets['GlobalStory'])
19
+ globals.age = ink.Value(30)
20
+ globals.friendly_name_of_player = ink.Value("Freddy")
21
+
22
+
23
+ assert runner.getline() == "My name is Jean Passepartout, but my friend's call me Freddy. I'm 30 years old.\n"
24
+ assert runner.getline() == "Foo:30\n"
25
+
26
+ val = globals.age
27
+ assert val.type == ink.Value.Int32 and str(val) == '30'
28
+ val = globals.friendly_name_of_player
29
+ assert val.type == ink.Value.String and str(val) == 'Freddy'
30
+
31
+
32
+ def test_invalid_operations(self, assets, generate):
33
+ [story, globals, runner] = generate(assets['GlobalStory'])
34
+
35
+ with pytest.raises(KeyError):
36
+ val = globals.foo
37
+ with pytest.raises(KeyError):
38
+ globals.foo = ink.Value(0)
39
+ with pytest.raises(KeyError):
40
+ globals.age = ink.Value('foo')
@@ -0,0 +1,43 @@
1
+ import inkcpp_py as ink
2
+
3
+ class TestLists:
4
+ def test_lists(self, assets, generate):
5
+ [story, globals, runner] = generate(assets['ListStory'])
6
+
7
+ val = globals.list
8
+ l = val.as_list()
9
+ hits = [False, False, False]
10
+ for flag in l:
11
+ if flag.name == 'bird' and flag.list_name == 'animals':
12
+ hits[0] = True
13
+ elif flag.name == 'red' and flag.list_name == 'colors':
14
+ hits[1] = True
15
+ elif flag.name == 'yellow' and flag.list_name == 'colors':
16
+ hits[2] = True
17
+ else:
18
+ assert False
19
+ assert hits[0] and hits[1] and hits[2]
20
+
21
+ hits = [False, False]
22
+ for flag in l.flags_from('colors'):
23
+ if flag.name == 'red' and flag.list_name == 'colors':
24
+ hits[0] = True
25
+ elif flag.name == 'yellow' and flag.list_name == 'colors':
26
+ hits[1] = True
27
+ else:
28
+ assert False
29
+ assert hits[0] and hits[1]
30
+
31
+ assert l.contains('yellow')
32
+ assert not l.contains('white')
33
+
34
+ l.add('white')
35
+ l.remove('yellow')
36
+
37
+ assert not l.contains('yellow')
38
+ assert l.contains('white')
39
+
40
+ globals.list = ink.Value(l)
41
+
42
+ assert runner.getline() == 'cat, snake\n'
43
+ assert runner.get_choice(0).text() == 'list: bird, white, red'
@@ -0,0 +1,27 @@
1
+ import inkcpp_py as ink
2
+ import pytest
3
+
4
+ class Observer:
5
+ def __init__(self):
6
+ self.cnt = 0
7
+ def __call__(self, new, old):
8
+ self.cnt += 1
9
+ if self.cnt == 1:
10
+ assert new.type == ink.Value.Int32 and str(new) == '1'
11
+ assert old is None
12
+ else:
13
+ assert new.type == ink.Value.Int32 and str(new) == '5'
14
+ assert old.type == ink.Value.Int32 and str(old) == '1'
15
+
16
+
17
+ class TestObserver:
18
+ def test_observer(self, assets, generate):
19
+ [story, store, runner] = generate(assets['ObserverStory'])
20
+
21
+ obs = Observer()
22
+ store.observe('var1', obs)
23
+
24
+ assert runner.getline() == "hello line 1 1 hello line 2 5 test line 3 5\n"
25
+ assert obs.cnt == 2
26
+
27
+