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,93 @@
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
+ /// Managing casting between value types.
10
+ /// The casting is defined by an NxN matrix where N = |value_types|.
11
+ /// The entry m,n is the type where we cast to when rh = value_type(m) and
12
+ /// lh = value_type(n).
13
+ /// for that the matrix is symmetric.
14
+ /// `value_type::none` is used to mark an invalid cast
15
+ ///
16
+ /// The entries are set in the `set_cast` function, which iterates over all
17
+ /// value_types combination. For each combination it checks the value of
18
+ /// `cast<v1,v2>` (with v1 < v2). When not other defined it is none.
19
+
20
+ #include "value.h"
21
+
22
+ namespace ink::runtime::internal::casting {
23
+
24
+ /**
25
+ * @brief casting_matrix data and access wrapper.
26
+ */
27
+ struct casting_matrix_type {
28
+ public:
29
+ constexpr casting_matrix_type() : _data{value_type::none}{};
30
+ constexpr value_type get(value_type t1, value_type t2) const {
31
+ return _data[static_cast<size_t>(t1)*N+static_cast<size_t>(t2)];
32
+ }
33
+ static constexpr size_t N = static_cast<size_t>(value_type::OP_END);
34
+ value_type _data[N*N];
35
+ };
36
+
37
+ // iterate through each value_type combination and populate the
38
+ // casting_matrix
39
+ template<value_type t1 = value_type::BEGIN, value_type t2 = value_type::BEGIN>
40
+ constexpr void set_cast (value_type data[casting_matrix_type::N*casting_matrix_type::N]){
41
+
42
+ if constexpr (t2 == value_type::OP_END) {
43
+ // end reached
44
+ } else if constexpr (t1 == value_type::OP_END) {
45
+ // go to next row
46
+ set_cast<value_type::BEGIN, t2+1>(data);
47
+ } else {
48
+ // get entry from cast<t1,t2>
49
+ constexpr size_t n1 = static_cast<size_t>(t1);
50
+ constexpr size_t n2 = static_cast<size_t>(t2);
51
+ // set matrix entry
52
+ if constexpr (n1 < n2) {
53
+ data[n1*casting_matrix_type::N + n2] = cast<t1,t2>::value;
54
+ } else {
55
+ data[n1*casting_matrix_type::N + n2] = cast<t2,t1>::value;
56
+ }
57
+ set_cast<t1+1,t2>(data);
58
+ }
59
+ }
60
+
61
+ // function to populate casting_matrix
62
+ constexpr casting_matrix_type construct_casting_matrix() {
63
+ casting_matrix_type cm;
64
+ set_cast(cm._data);
65
+ return cm;
66
+ }
67
+
68
+ /// NxN matrix which contains in cell i,j the common base of value_type(i)
69
+ /// and value_type(j).
70
+ static constexpr casting_matrix_type casting_matrix = construct_casting_matrix();
71
+
72
+ /**
73
+ * @brief returns a type where each value can be casted to.
74
+ * Result based on `cast<value_type,value_type> = value_type`
75
+ * definitions.
76
+ * @tparam N number of values/value array length
77
+ * @param vs array which contains the values
78
+ * @return value_type::none if there is no common base defined
79
+ * @return common base of types in vs else
80
+ */
81
+ template<size_t N>
82
+ value_type common_base(const value* vs) {
83
+ if constexpr (N == 0) { return value_type::none; }
84
+ else if constexpr (N == 1) { return vs->type(); }
85
+ else {
86
+ value_type ty = vs[0].type();
87
+ for(size_t i = 1; i < N; ++i) {
88
+ ty = casting_matrix.get(ty, vs[i].type());
89
+ }
90
+ return ty;
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,54 @@
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 "choice.h"
8
+
9
+ #include "output.h"
10
+ #include "string_table.h"
11
+ #include "string_utils.h"
12
+
13
+ namespace ink {
14
+ namespace runtime {
15
+ choice& choice::setup( internal::basic_stream& in, internal::string_table& strings, internal::list_table& lists, int index, uint32_t path, thread_t thread, const char* const* tags )
16
+ {
17
+ char* text = nullptr;
18
+ // if we only have one item in our output stream
19
+ if ( in.queued() == 2 )
20
+ {
21
+ // If it's a string, just grab it. Otherwise, use allocation
22
+ const internal::value& data = in.peek();
23
+ switch ( data.type() )
24
+ {
25
+ case internal::value_type::string:
26
+ text = strings.duplicate( data.get<internal::value_type::string>() );
27
+ in.discard( 2 );
28
+ break;
29
+ default:
30
+ text = in.get_alloc( strings, lists );
31
+ }
32
+ }
33
+ else
34
+ {
35
+ // Non-string. Must allocate
36
+ text = in.get_alloc( strings, lists );
37
+ }
38
+ char* end = text;
39
+ while ( *end )
40
+ {
41
+ ++end;
42
+ }
43
+ end = ink::runtime::internal::clean_string<true, true>( text, end );
44
+ *end = 0;
45
+ _text = text;
46
+ // Index/path
47
+ _index = index;
48
+ _path = path;
49
+ _thread = thread;
50
+ _tags = tags;
51
+ return *this;
52
+ }
53
+ }
54
+ } // namespace ink::runtime
@@ -0,0 +1,124 @@
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 "restorable.h"
8
+ #include "../stack.h"
9
+
10
+ namespace ink::runtime::internal
11
+ {
12
+ unsigned char*
13
+ snap_base(unsigned char* ptr, bool write, size_t pos, size_t jump, size_t save, size_t& max)
14
+ {
15
+ ptr = snapshot_interface::snap_write(ptr, pos, write);
16
+ ptr = snapshot_interface::snap_write(ptr, jump, write);
17
+ ptr = snapshot_interface::snap_write(ptr, save, write);
18
+ max = pos;
19
+ if (jump != ~0 && jump > max) {
20
+ max = jump;
21
+ }
22
+ if (save != ~0 && save > max) {
23
+ max = save;
24
+ }
25
+ return ptr;
26
+ }
27
+
28
+ const unsigned char*
29
+ snap_load_base(const unsigned char* ptr, size_t& pos, size_t& jump, size_t& save, size_t& max)
30
+ {
31
+ ptr = snapshot_interface::snap_read(ptr, pos);
32
+ ptr = snapshot_interface::snap_read(ptr, jump);
33
+ ptr = snapshot_interface::snap_read(ptr, save);
34
+ max = pos;
35
+ if (jump != ~0 && jump > max) {
36
+ max = jump;
37
+ }
38
+ if (save != ~0 && save > max) {
39
+ max = save;
40
+ }
41
+ return ptr;
42
+ }
43
+
44
+ template<>
45
+ size_t restorable<entry>::snap(unsigned char* data, const snapper& snapper) const
46
+ {
47
+ unsigned char* ptr = data;
48
+ size_t max;
49
+ ptr = snap_base(ptr, data != nullptr, _pos, _jump, _save, max);
50
+ for (size_t i = 0; i < max; ++i) {
51
+ ptr = snap_write(ptr, _buffer[i].name, data != nullptr);
52
+ ptr += _buffer[i].data.snap(data ? ptr : nullptr, snapper);
53
+ }
54
+ return ptr - data;
55
+ }
56
+
57
+ template<>
58
+ size_t restorable<value>::snap(unsigned char* data, const snapper& snapper) const
59
+ {
60
+ unsigned char* ptr = data;
61
+ size_t max;
62
+ ptr = snap_base(ptr, data != nullptr, _pos, _jump, _save, max);
63
+ for (size_t i = 0; i < max; ++i) {
64
+ ptr += _buffer[i].snap(data ? ptr : nullptr, snapper);
65
+ }
66
+ return ptr - data;
67
+ }
68
+
69
+ template<>
70
+ size_t restorable<int>::snap(unsigned char* data, const snapper&) const
71
+ {
72
+ unsigned char* ptr = data;
73
+ size_t max;
74
+ ptr = snap_base(ptr, data != nullptr, _pos, _jump, _save, max);
75
+ for (size_t i = 0; i < max; ++i) {
76
+ ptr = snap_write(ptr, _buffer[i], data != nullptr);
77
+ }
78
+ return ptr - data;
79
+ }
80
+
81
+ template<>
82
+ const unsigned char* restorable<entry>::snap_load(const unsigned char* ptr, const loader& loader)
83
+ {
84
+ size_t max;
85
+ ptr = snap_load_base(ptr, _pos, _jump, _save, max);
86
+ while (_size < max) {
87
+ overflow(_buffer, _size);
88
+ }
89
+ for (size_t i = 0; i < max; ++i) {
90
+ ptr = snap_read(ptr, _buffer[i].name);
91
+ ptr = _buffer[i].data.snap_load(ptr, loader);
92
+ }
93
+ return ptr;
94
+ }
95
+
96
+ template<>
97
+ const unsigned char* restorable<value>::snap_load(const unsigned char* ptr, const loader& loader)
98
+ {
99
+ size_t max;
100
+ ptr = snap_load_base(ptr, _pos, _jump, _save, max);
101
+ while (_size < max) {
102
+ overflow(_buffer, _size);
103
+ }
104
+ for (size_t i = 0; i < max; ++i) {
105
+ ptr = _buffer[i].snap_load(ptr, loader);
106
+ }
107
+ return ptr;
108
+ }
109
+
110
+ template<>
111
+ const unsigned char* restorable<int>::snap_load(const unsigned char* ptr, const loader& loader)
112
+ {
113
+ size_t max;
114
+ ptr = snap_load_base(ptr, _pos, _jump, _save, max);
115
+ while (_size < max) {
116
+ overflow(_buffer, _size);
117
+ }
118
+ for (size_t i = 0; i < max; ++i) {
119
+ ptr = snap_read(ptr, _buffer[i]);
120
+ }
121
+ return ptr;
122
+ }
123
+
124
+ } // namespace ink::runtime::internal
@@ -0,0 +1,406 @@
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 "../snapshot_impl.h"
10
+
11
+ #include <system.h>
12
+ #include <traits.h>
13
+
14
+ namespace ink::runtime::internal
15
+ {
16
+ struct entry;
17
+ template<typename ElementType>
18
+ constexpr auto EmptyNullPredicate = [](const ElementType&) { return false; };
19
+
20
+ // Iterator type used with restorable
21
+ template<typename ElementType>
22
+ class restorable_iter
23
+ {
24
+ public:
25
+ // Create an iterator moving from start (inclusive) to end (exclusive)
26
+ restorable_iter(ElementType* start, ElementType* end)
27
+ : _current(start), _end(end) { }
28
+
29
+ // Move to the next non-null element
30
+ template<typename IsNullPredicate = decltype(EmptyNullPredicate<ElementType>)>
31
+ bool next(IsNullPredicate isNull = EmptyNullPredicate<ElementType>)
32
+ {
33
+ if (_current != _end)
34
+ {
35
+ // Determine direction of iteration
36
+ int dir = _end - _current > 0 ? 1 : -1;
37
+
38
+ // Move pointer
39
+ _current += dir;
40
+
41
+ // Make sure to skip over null items
42
+ while (isNull(*_current) && _current != _end) {
43
+ _current += dir;
44
+ }
45
+ }
46
+
47
+ // If we've hit the end, return false
48
+ if (_current == _end)
49
+ return false;
50
+
51
+ // Otherwise, iteration is valid
52
+ return true;
53
+ }
54
+
55
+ // Get current element
56
+ inline ElementType* get() { return _current; }
57
+
58
+ // Get current element (const)
59
+ inline const ElementType* get() const { return _current; }
60
+
61
+ // Is iteration complete (opposite of is valid)
62
+ inline bool done() const { return _current == _end; }
63
+
64
+ private:
65
+ // Current point of iteration
66
+ ElementType* _current;
67
+
68
+ // End point (non-valid)
69
+ ElementType* _end;
70
+ };
71
+
72
+ /**
73
+ * A special base class for collections which have save/restore/forget functionality
74
+ *
75
+ * In order to properly handle Ink's glue system, we need to be able to execute beyond
76
+ * the end of the line and "peek" to see if a glue command is executed. If one is, we keep
77
+ * executing (as the next line will be glued to the current). If we don't, or find more content
78
+ * before finding glue, then in actuality, we never should have executed beyond the newline. We
79
+ * need to *restore* back to our state before we moved past the end of line. Collections inheriting
80
+ * from this class gain this functionality.
81
+ */
82
+ template<typename ElementType>
83
+ class restorable : public snapshot_interface
84
+ {
85
+ public:
86
+ restorable(ElementType* buffer, size_t size)
87
+ : _buffer(buffer), _size(size), _pos(0), _jump(~0), _save(~0)
88
+ { }
89
+
90
+ // Checks if we have a save state
91
+ bool is_saved() const { return _save != ~0; }
92
+
93
+ // Creates a save point which can later be restored to or forgotten
94
+ void save()
95
+ {
96
+ inkAssert(_save == ~0, "Collection is already saved. You should never call save twice. Ignoring.");
97
+ if (_save != ~0) {
98
+ return;
99
+ }
100
+
101
+ // Set the save and jump points to the current position.
102
+ _save = _jump = _pos;
103
+ }
104
+
105
+ // Restore to the last save point
106
+ void restore()
107
+ {
108
+ inkAssert(_save != ~0, "Collection can't be restored because it's not saved. Ignoring.");
109
+ if (_save == ~0) {
110
+ return;
111
+ }
112
+
113
+ // Move our position back to the saved position
114
+ _pos = _save;
115
+
116
+ // Clear save point
117
+ _save = _jump = ~0;
118
+ }
119
+
120
+ // Forget the save point and continue with the current data
121
+ template<typename NullifyMethod>
122
+ void forget(NullifyMethod nullify)
123
+ {
124
+ inkAssert(_save != ~0, "Can't forget save point because there is none. Ignoring.");
125
+ if (_save == ~0) {
126
+ return;
127
+ }
128
+
129
+ // If we're behind the save point but past the jump point
130
+ if (_save != _jump && _pos > _jump)
131
+ {
132
+ // Nullify everything between the jump point and the save point
133
+ for (size_t i = _jump; i < _save; ++i)
134
+ nullify(_buffer[i]);
135
+ }
136
+
137
+ // Reset save position
138
+ _save = _jump = ~0;
139
+ }
140
+
141
+ using iterator = restorable_iter<ElementType>;
142
+ using const_iterator = restorable_iter<const ElementType>;
143
+
144
+ // Iterator that begins at the end of the stack
145
+ iterator begin() { return iterator(&_buffer[_pos - 1], _buffer - 1); }
146
+ const_iterator begin() const { return iterator(&_buffer[_pos - 1], _buffer - 1); }
147
+
148
+ // Iterator that points to the element past the beginning of the stack
149
+ iterator end() { return iterator(_buffer - 1, _buffer - 1); }
150
+ iterator end() const { return const_iterator(_buffer - 1, _buffer - 1); }
151
+
152
+ // Push element onto the top of collection
153
+ ElementType& push(const ElementType& elem)
154
+ {
155
+ // Don't destroy saved data. Jump over it
156
+ if (_pos < _save && _save != ~0)
157
+ {
158
+ _jump = _pos;
159
+ _pos = _save;
160
+ }
161
+
162
+ // Overflow check
163
+ if (_pos >= _size)
164
+ overflow(_buffer, _size);
165
+
166
+ // Push onto the top
167
+ _buffer[_pos++] = elem;
168
+
169
+ // Return reference
170
+ return _buffer[_pos - 1];
171
+ }
172
+
173
+ // Pop an element off the top of the collection
174
+ template<typename IsNullPredicate>
175
+ const ElementType& pop(IsNullPredicate isNull)
176
+ {
177
+ // Make sure we have something to pop
178
+ inkAssert(_pos > 0, "Can not pop. No elements to pop!");
179
+
180
+ // Jump over save data
181
+ if (_pos == _save)
182
+ _pos = _jump;
183
+
184
+ // Move over empty data
185
+ while (isNull(_buffer[_pos - 1]))
186
+ _pos--;
187
+
188
+ // Decrement and return
189
+ _pos--;
190
+ return _buffer[_pos];
191
+ }
192
+
193
+ template<typename IsNullPredicate>
194
+ const ElementType& top(IsNullPredicate isNull) const
195
+ {
196
+ inkAssert(_pos > 0, "Can not top. No elememnts to show!");
197
+ auto pos = _pos;
198
+ if (_pos == _save)
199
+ pos = _jump;
200
+ while(isNull(_buffer[pos-1]))
201
+ --pos;
202
+ return _buffer[pos-1];
203
+ }
204
+
205
+ bool is_empty() const { return _pos == 0; }
206
+
207
+ void clear()
208
+ {
209
+ _pos = 0;
210
+ _save = _jump = ~0;
211
+ }
212
+
213
+ // Forward iterate
214
+ template<typename CallbackMethod, typename IsNullPredicate>
215
+ void for_each(CallbackMethod callback, IsNullPredicate isNull) const
216
+ {
217
+ if (_pos == 0) {
218
+ return;
219
+ }
220
+
221
+ // Start at the beginning
222
+ size_t i = 0;
223
+ do
224
+ {
225
+ // Jump over saved data
226
+ if (i == _jump)
227
+ i = _save;
228
+
229
+ // Run callback
230
+ if(!isNull(_buffer[i]))
231
+ callback(_buffer[i]);
232
+
233
+ // Move forward one element
234
+ i++;
235
+ } while (i < _pos);
236
+ }
237
+
238
+ template<typename Predicate>
239
+ const ElementType* find(Predicate predicate) const
240
+ {
241
+ if (_pos == 0) {
242
+ return nullptr;
243
+ }
244
+
245
+ // Start at the beginning
246
+ size_t i = 0;
247
+ do
248
+ {
249
+ // Jump over saved data
250
+ if (i == _jump)
251
+ i = _save;
252
+
253
+ // Run callback
254
+ if (!isNull(_buffer[i]) && predicate(_buffer[i]))
255
+ return &_buffer[i];
256
+
257
+ // Move forward one element
258
+ i++;
259
+ } while (i < _pos);
260
+
261
+ return nullptr;
262
+ }
263
+
264
+ template<typename CallbackMethod>
265
+ void for_each_all(CallbackMethod callback) const
266
+ {
267
+ // no matter if we're saved or not, we iterate everything
268
+ int len = (_save == ~0 || _pos > _save) ? _pos : _save;
269
+
270
+ // Iterate
271
+ for (int i = 0; i < len; i++)
272
+ callback(_buffer[i]);
273
+ }
274
+
275
+ // Reverse iterate
276
+ template<typename CallbackMethod, typename IsNullPredicate>
277
+ void reverse_for_each(CallbackMethod callback, IsNullPredicate isNull) const
278
+ {
279
+ if (_pos == 0) {
280
+ return;
281
+ }
282
+
283
+ // Start at the end
284
+ size_t i = _pos;
285
+ do
286
+ {
287
+ // Move back one element
288
+ i--;
289
+
290
+ // Run callback
291
+ if (!isNull(_buffer[i]))
292
+ callback(_buffer[i]);
293
+
294
+ // Jump over saved data
295
+ if (i == _save)
296
+ i = _jump;
297
+
298
+ } while (i > 0);
299
+ }
300
+
301
+ // Reverse find
302
+ template<typename Predicate>
303
+ ElementType* reverse_find(Predicate predicate) {
304
+ return reverse_find_impl(predicate);
305
+ }
306
+
307
+ template<typename Predicate>
308
+ const ElementType* reverse_find(Predicate predicate) const {
309
+ return reverse_find_impl(predicate);
310
+ }
311
+
312
+ template<typename IsNullPredicate>
313
+ size_t size(IsNullPredicate isNull) const
314
+ {
315
+ if (_pos == 0) {
316
+ return 0;
317
+ }
318
+
319
+ size_t count = 0;
320
+
321
+ // Start at the end
322
+ size_t i = _pos;
323
+ do
324
+ {
325
+ // Move back one element
326
+ i--;
327
+
328
+ // Run callback
329
+ if(!isNull(_buffer[i]))
330
+ count++;
331
+
332
+ // Jump over saved data
333
+ if (i == _save)
334
+ i = _jump;
335
+
336
+ } while (i > 0);
337
+
338
+ return count;
339
+ }
340
+
341
+ // snapshot interface
342
+ virtual size_t snap(unsigned char* data, const snapper&) const;
343
+ const unsigned char* snap_load(const unsigned char* data, const loader&);
344
+
345
+ protected:
346
+ // Called when we run out of space in buffer.
347
+ virtual void overflow(ElementType*& buffer, size_t& size) {
348
+ inkFail("Restorable run out of memory!");
349
+ }
350
+
351
+ private:
352
+
353
+ template<typename Predicate>
354
+ ElementType* reverse_find_impl(Predicate predicate) const
355
+ {
356
+ if (_pos == 0) {
357
+ return nullptr;
358
+ }
359
+
360
+ // Start at the end
361
+ size_t i = _pos;
362
+ do
363
+ {
364
+ // Move back one element
365
+ i--;
366
+
367
+ // Run callback
368
+ if (predicate(_buffer[i]))
369
+ return &_buffer[i];
370
+
371
+ // Jump over saved data
372
+ if (i == _save)
373
+ i = _jump;
374
+
375
+ } while (i > 0);
376
+
377
+ return nullptr;
378
+ }
379
+
380
+ // Data buffer. Collection is stored here
381
+ ElementType* _buffer;
382
+
383
+ // Size of the _buffer array
384
+ size_t _size;
385
+
386
+ // Set to the next empty position in the buffer.
387
+ size_t _pos;
388
+
389
+ // Jump and save points. Used when we've been saved.
390
+ size_t _jump;
391
+ size_t _save;
392
+ };
393
+ template<>
394
+ size_t restorable<value>::snap(unsigned char* data, const snapper& snapper) const;
395
+ template<>
396
+ size_t restorable<entry>::snap(unsigned char* data, const snapper& snapper) const;
397
+ template<>
398
+ size_t restorable<int>::snap(unsigned char* data, const snapper&) const;
399
+
400
+ template<>
401
+ const unsigned char* restorable<value>::snap_load(const unsigned char* data, const loader&);
402
+ template<>
403
+ const unsigned char* restorable<entry>::snap_load(const unsigned char* data, const loader&);
404
+ template<>
405
+ const unsigned char* restorable<int>::snap_load(const unsigned char* data, const loader&);
406
+ }