├── .clang-format ├── .github ├── config.env └── workflows │ ├── build.yml │ ├── docs.yml │ ├── utests-minimal.yml │ └── utests.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── Doxyfile ├── LICENSE ├── README.md ├── build ├── HunterPackages.cmake ├── LLVM.cmake └── zip.cmake ├── docs ├── Extensions.md ├── Getting started.md ├── Graphics effects.md ├── Home.md ├── Virtual machine.md └── theme │ └── doxygen-awesome.css ├── include └── scratchcpp │ ├── asset.h │ ├── block.h │ ├── blockprototype.h │ ├── broadcast.h │ ├── comment.h │ ├── compiler.h │ ├── compilerconstant.h │ ├── compilercontext.h │ ├── compilerlocalvariable.h │ ├── compilervalue.h │ ├── costume.h │ ├── drawable.h │ ├── entity.h │ ├── executablecode.h │ ├── executioncontext.h │ ├── field.h │ ├── global.h │ ├── iengine.h │ ├── iextension.h │ ├── igraphicseffect.h │ ├── imonitorhandler.h │ ├── input.h │ ├── inputvalue.h │ ├── irandomgenerator.h │ ├── ispritehandler.h │ ├── istacktimer.h │ ├── istagehandler.h │ ├── itimer.h │ ├── keyevent.h │ ├── list.h │ ├── monitor.h │ ├── project.h │ ├── promise.h │ ├── rect.h │ ├── scratchconfiguration.h │ ├── script.h │ ├── signal.h │ ├── sound.h │ ├── spimpl.h │ ├── sprite.h │ ├── stage.h │ ├── string_functions.h │ ├── string_pool.h │ ├── stringptr.h │ ├── target.h │ ├── test │ └── scriptbuilder.h │ ├── textbubble.h │ ├── thread.h │ ├── value.h │ ├── value_functions.h │ ├── valuedata.h │ ├── variable.h │ └── veque.h ├── src ├── CMakeLists.txt ├── audio │ ├── CMakeLists.txt │ ├── audioinput.cpp │ ├── audioinput.h │ ├── audiooutput.cpp │ ├── audiooutput.h │ ├── iaudioengine.h │ ├── iaudioinput.h │ ├── iaudioloudness.h │ ├── iaudiooutput.h │ ├── iaudioplayer.h │ └── internal │ │ ├── audioengine.cpp │ │ ├── audioengine.h │ │ ├── audioenginestub.cpp │ │ ├── audioenginestub.h │ │ ├── audioloudness.cpp │ │ ├── audioloudness.h │ │ ├── audioloudnessstub.cpp │ │ ├── audioloudnessstub.h │ │ ├── audioplayer.cpp │ │ ├── audioplayer.h │ │ ├── audioplayerstub.cpp │ │ ├── audioplayerstub.h │ │ └── thirdparty │ │ └── miniaudio │ │ ├── miniaudio.c │ │ └── miniaudio.h ├── blocks │ ├── CMakeLists.txt │ ├── blocks.cpp │ ├── blocks.h │ ├── controlblocks.cpp │ ├── controlblocks.h │ ├── customblocks.cpp │ ├── customblocks.h │ ├── eventblocks.cpp │ ├── eventblocks.h │ ├── listblocks.cpp │ ├── listblocks.h │ ├── looksblocks.cpp │ ├── looksblocks.h │ ├── motionblocks.cpp │ ├── motionblocks.h │ ├── operatorblocks.cpp │ ├── operatorblocks.h │ ├── sensingblocks.cpp │ ├── sensingblocks.h │ ├── soundblocks.cpp │ ├── soundblocks.h │ ├── variableblocks.cpp │ └── variableblocks.h ├── engine │ ├── CMakeLists.txt │ ├── compiler.cpp │ ├── compiler_p.cpp │ ├── compiler_p.h │ ├── compilerconstant.cpp │ ├── compilerconstant_p.cpp │ ├── compilerconstant_p.h │ ├── compilercontext.cpp │ ├── compilercontext_p.cpp │ ├── compilercontext_p.h │ ├── compilerlocalvariable.cpp │ ├── compilerlocalvariable_p.cpp │ ├── compilerlocalvariable_p.h │ ├── compilervalue.cpp │ ├── compilervalue_p.cpp │ ├── compilervalue_p.h │ ├── executioncontext.cpp │ ├── executioncontext_p.cpp │ ├── executioncontext_p.h │ ├── internal │ │ ├── clock.cpp │ │ ├── clock.h │ │ ├── codebuilderfactory.cpp │ │ ├── codebuilderfactory.h │ │ ├── engine.cpp │ │ ├── engine.h │ │ ├── iclock.h │ │ ├── icodebuilder.h │ │ ├── icodebuilderfactory.h │ │ ├── llvm │ │ │ ├── CMakeLists.txt │ │ │ ├── llvmcodebuilder.cpp │ │ │ ├── llvmcodebuilder.h │ │ │ ├── llvmcompilercontext.cpp │ │ │ ├── llvmcompilercontext.h │ │ │ ├── llvmconstantregister.h │ │ │ ├── llvmcoroutine.cpp │ │ │ ├── llvmcoroutine.h │ │ │ ├── llvmexecutablecode.cpp │ │ │ ├── llvmexecutablecode.h │ │ │ ├── llvmexecutioncontext.cpp │ │ │ ├── llvmexecutioncontext.h │ │ │ ├── llvmfunctions.cpp │ │ │ ├── llvmifstatement.h │ │ │ ├── llvminstruction.h │ │ │ ├── llvmlistptr.h │ │ │ ├── llvmloop.h │ │ │ ├── llvmloopscope.h │ │ │ ├── llvmprocedure.h │ │ │ ├── llvmregister.h │ │ │ ├── llvmtypes.cpp │ │ │ ├── llvmtypes.h │ │ │ └── llvmvariableptr.h │ │ ├── randomgenerator.cpp │ │ ├── randomgenerator.h │ │ ├── stacktimer.cpp │ │ ├── stacktimer.h │ │ ├── timer.cpp │ │ └── timer.h │ ├── promise.cpp │ ├── promise_p.cpp │ ├── promise_p.h │ ├── script.cpp │ ├── script_p.cpp │ ├── script_p.h │ ├── thread.cpp │ ├── thread_p.cpp │ └── thread_p.h ├── internal │ ├── CMakeLists.txt │ ├── downloader.cpp │ ├── downloader.h │ ├── downloaderfactory.cpp │ ├── downloaderfactory.h │ ├── idownloader.h │ ├── idownloaderfactory.h │ ├── iprojectdownloader.h │ ├── iprojectdownloaderfactory.h │ ├── iprojectreader.h │ ├── projectdownloader.cpp │ ├── projectdownloader.h │ ├── projectdownloaderfactory.cpp │ ├── projectdownloaderfactory.h │ ├── projectdownloaderstub.cpp │ ├── projectdownloaderstub.h │ ├── projecturl.cpp │ ├── projecturl.h │ ├── reader_common.h │ ├── scratch3reader.cpp │ ├── scratch3reader.h │ ├── zipreader.cpp │ └── zipreader.h ├── project.cpp ├── project_p.cpp ├── project_p.h ├── rect.cpp ├── rect_p.cpp ├── rect_p.h ├── scratch │ ├── CMakeLists.txt │ ├── asset.cpp │ ├── asset_p.cpp │ ├── asset_p.h │ ├── block.cpp │ ├── block_p.cpp │ ├── block_p.h │ ├── blockprototype.cpp │ ├── blockprototype_p.cpp │ ├── blockprototype_p.h │ ├── broadcast.cpp │ ├── broadcast_p.cpp │ ├── broadcast_p.h │ ├── comment.cpp │ ├── comment_p.cpp │ ├── comment_p.h │ ├── costume.cpp │ ├── costume_p.cpp │ ├── costume_p.h │ ├── drawable.cpp │ ├── drawable_p.cpp │ ├── drawable_p.h │ ├── entity.cpp │ ├── entity_p.cpp │ ├── entity_p.h │ ├── field.cpp │ ├── field_p.cpp │ ├── field_p.h │ ├── input.cpp │ ├── input_p.cpp │ ├── input_p.h │ ├── inputvalue.cpp │ ├── inputvalue_p.cpp │ ├── inputvalue_p.h │ ├── keyevent.cpp │ ├── keyevent_p.cpp │ ├── keyevent_p.h │ ├── list.cpp │ ├── list_functions.cpp │ ├── list_functions.h │ ├── list_p.cpp │ ├── list_p.h │ ├── monitor.cpp │ ├── monitor_p.cpp │ ├── monitor_p.h │ ├── sound.cpp │ ├── sound_p.cpp │ ├── sound_p.h │ ├── sprite.cpp │ ├── sprite_p.cpp │ ├── sprite_p.h │ ├── stage.cpp │ ├── stage_p.cpp │ ├── stage_p.h │ ├── string_functions.cpp │ ├── string_pool.cpp │ ├── string_pool_p.h │ ├── target.cpp │ ├── target_p.cpp │ ├── target_p.h │ ├── textbubble.cpp │ ├── textbubble_p.cpp │ ├── textbubble_p.h │ ├── thirdparty │ │ └── fast_float │ │ │ └── fast_float.h │ ├── value_functions.cpp │ ├── value_functions_p.h │ ├── variable.cpp │ ├── variable_p.cpp │ └── variable_p.h ├── scratchconfiguration.cpp ├── scratchconfiguration_p.cpp ├── scratchconfiguration_p.h └── test │ ├── CMakeLists.txt │ ├── scriptbuilder.cpp │ ├── scriptbuilder_p.cpp │ └── scriptbuilder_p.h ├── test ├── 2_frames.sb3 ├── 3_threads.sb3 ├── CMakeLists.txt ├── Meow.wav ├── Pop.wav ├── assets │ ├── CMakeLists.txt │ ├── asset_test.cpp │ ├── costume_test.cpp │ ├── sound_test.cpp │ ├── testasset.cpp │ └── testasset.h ├── audio │ ├── CMakeLists.txt │ ├── audioengine_test.cpp │ ├── audioinput_test.cpp │ ├── audiooutput_test.cpp │ └── audioplayer_test.cpp ├── backdrop_broadcasts.sb3 ├── blocks │ ├── CMakeLists.txt │ ├── control_blocks_test.cpp │ ├── custom_blocks_test.cpp │ ├── event_blocks_test.cpp │ ├── list_blocks_test.cpp │ ├── looks_blocks_test.cpp │ ├── motion_blocks_test.cpp │ ├── operator_blocks_test.cpp │ ├── sensing_blocks_test.cpp │ ├── sound_blocks_test.cpp │ ├── util.cpp │ ├── util.h │ └── variable_blocks_test.cpp ├── broadcasts.sb3 ├── bubble_sort.json ├── bubble_sort.sb3 ├── clock │ ├── CMakeLists.txt │ └── clock_test.cpp ├── clone_limit.sb3 ├── clones.sb3 ├── common.h ├── compiler │ ├── CMakeLists.txt │ ├── compiler_test.cpp │ ├── compilerconstant_test.cpp │ ├── compilercontext_test.cpp │ ├── compilerlocalvariable_test.cpp │ └── compilervalue_test.cpp ├── custom_blocks.sb3 ├── default_project.json ├── default_project.sb3 ├── empty_project.json ├── empty_project.sb3 ├── engine │ ├── CMakeLists.txt │ └── engine_test.cpp ├── execution_order.sb3 ├── executioncontext │ ├── CMakeLists.txt │ └── executioncontext_test.cpp ├── extensions │ ├── CMakeLists.txt │ ├── iextension_test.cpp │ ├── testextension.cpp │ └── testextension.h ├── file_manager.json ├── file_manager.sb3 ├── forever_loop.sb3 ├── if.sb3 ├── if_else.sb3 ├── if_else_empty.sb3 ├── if_empty.sb3 ├── image1.jpg ├── image1.png ├── image2.jpg ├── image2.png ├── llvm │ ├── CMakeLists.txt │ ├── llvmcodebuilder_test.cpp │ ├── llvmexecutablecode_test.cpp │ ├── llvmexecutioncontext_test.cpp │ ├── main.cpp │ ├── testfunctions.cpp │ ├── testfunctions.h │ └── testmock.h ├── load_project │ ├── CMakeLists.txt │ └── load_project_test.cpp ├── load_test.sb3 ├── mocks │ ├── CMakeLists.txt │ ├── audioenginemock.h │ ├── audioinputmock.h │ ├── audioloudnessmock.h │ ├── audiooutputmock.h │ ├── audioplayermock.h │ ├── clockmock.h │ ├── codebuilderfactorymock.h │ ├── codebuildermock.h │ ├── compilercontextmock.h │ ├── downloaderfactorymock.h │ ├── downloadermock.h │ ├── enginemock.h │ ├── executablecodemock.h │ ├── extensionmock.h │ ├── graphicseffectmock.h │ ├── monitorhandlermock.h │ ├── projectdownloaderfactorymock.h │ ├── projectdownloadermock.h │ ├── randomgeneratormock.h │ ├── soundmock.h │ ├── spritehandlermock.h │ ├── stacktimermock.h │ ├── stagehandlermock.h │ ├── targetmock.h │ └── timermock.h ├── mouse_wheel.sb3 ├── nested_statements.sb3 ├── network │ ├── CMakeLists.txt │ ├── downloaderfactory_test.cpp │ ├── projectdownloader_test.cpp │ ├── projectdownloaderfactory_test.cpp │ └── projecturl_test.cpp ├── project │ ├── CMakeLists.txt │ └── project_test.cpp ├── promise │ ├── CMakeLists.txt │ └── promise_test.cpp ├── randomgenerator │ ├── CMakeLists.txt │ └── randomgenerator_test.cpp ├── rect │ ├── CMakeLists.txt │ └── rect_test.cpp ├── regtest_projects │ ├── 186_crash_after_stop.sb3 │ ├── 256_broadcast_self_call_crash.sb3 │ ├── 257_double_broadcast_stop.sb3 │ ├── 277_custom_block_call_running_broadcast_stop.sb3 │ ├── 394_stop_before_starting.sb3 │ ├── 395_reset_running_hats.sb3 │ ├── 437_load_double_values.sb3 │ ├── 445_undefined_variable_or_list_monitor_crash.sb3 │ ├── 446_undefined_variable_or_list_field_crash.sb3 │ ├── 446_undefined_variable_or_list_input_crash.sb3 │ ├── 448_null_monitor_dimension.sb3 │ ├── 488_scientific_notation_conversion.sb3 │ ├── 547_stop_clone_threads_in_stop_all.sb3 │ ├── 563_broadcast_stops_wait_blocks.sb3 │ ├── 567_duplicate_variable_list_id.sb3 │ └── 578_broadcast_and_wait_case_insensitive.sb3 ├── repeat10.sb3 ├── repeat_empty.sb3 ├── repeat_for_each.sb3 ├── repeat_for_each_empty.sb3 ├── repeat_until.sb3 ├── repeat_while.sb3 ├── resolve_id_test.sb3 ├── scratch_classes │ ├── CMakeLists.txt │ ├── block_test.cpp │ ├── blockprototype_test.cpp │ ├── broadcast_test.cpp │ ├── comment_test.cpp │ ├── drawable_test.cpp │ ├── entity_test.cpp │ ├── field_test.cpp │ ├── input_test.cpp │ ├── inputvalue_test.cpp │ ├── keyevent_test.cpp │ ├── list_functions_test.cpp │ ├── list_test.cpp │ ├── monitor_test.cpp │ ├── sprite_test.cpp │ ├── stage_test.cpp │ ├── string_functions_test.cpp │ ├── string_pool_test.cpp │ ├── stringptr_test.cpp │ ├── target_test.cpp │ ├── testextension.cpp │ ├── testextension.h │ ├── textbubble_test.cpp │ ├── value_test.cpp │ └── variable_test.cpp ├── scratchconfiguration │ ├── CMakeLists.txt │ ├── extension1.cpp │ ├── extension1.h │ ├── extension2.cpp │ ├── extension2.h │ ├── extension3.cpp │ ├── extension3.h │ ├── extensionbase.cpp │ ├── extensionbase.h │ └── scratchconfiguration_test.cpp ├── script │ ├── CMakeLists.txt │ └── script_test.cpp ├── sounds.sb3 ├── step.sb3 ├── stop_all.sb3 ├── stop_all_bypass.sb3 ├── stop_other_scripts_in_sprite.sb3 ├── target_click_scripts.sb3 ├── target_interfaces │ ├── CMakeLists.txt │ ├── ispritehandler_test.cpp │ └── istagehandler_test.cpp ├── test_api │ ├── CMakeLists.txt │ ├── scriptbuilder_test.cpp │ ├── testextension.cpp │ └── testextension.h ├── thread │ ├── CMakeLists.txt │ └── thread_test.cpp ├── timer │ ├── CMakeLists.txt │ ├── stacktimer_test.cpp │ └── timer_test.cpp ├── top_level_reporter.sb3 ├── unsupported_blocks.sb3 ├── when_greater_than.sb3 ├── when_key_pressed.sb3 └── zip │ ├── CMakeLists.txt │ └── zip_test.cpp └── thirdparty └── cpp-unicodelib ├── CMakeLists.txt ├── unicodelib.h ├── unicodelib_encodings.h └── unicodelib_names.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Mozilla 3 | AllowAllArgumentsOnNextLine: false 4 | AlwaysBreakAfterDefinitionReturnType: None 5 | AlwaysBreakAfterReturnType: None 6 | BraceWrapping: 7 | AfterCaseLabel: false 8 | AfterClass: true 9 | AfterControlStatement: Never 10 | AfterEnum: true 11 | AfterFunction: true 12 | AfterNamespace: true 13 | AfterObjCDeclaration: false 14 | AfterStruct: true 15 | AfterUnion: true 16 | AfterExternBlock: true 17 | BeforeCatch: false 18 | BeforeElse: false 19 | BeforeLambdaBody: false 20 | BeforeWhile: false 21 | IndentBraces: false 22 | SplitEmptyFunction: true 23 | SplitEmptyRecord: false 24 | SplitEmptyNamespace: true 25 | BreakBeforeBraces: Custom 26 | BreakBeforeTernaryOperators: false 27 | BreakConstructorInitializers: AfterColon 28 | ColumnLimit: 200 29 | ConstructorInitializerIndentWidth: 4 30 | ContinuationIndentWidth: 4 31 | FixNamespaceComments: true 32 | IncludeBlocks: Merge 33 | IndentAccessModifiers: true 34 | IndentWidth: 4 35 | PackConstructorInitializers: Never 36 | PointerAlignment: Right 37 | SortIncludes: Never 38 | SortUsingDeclarations: false 39 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 40 | AllowAllConstructorInitializersOnNextLine: true 41 | AllowShortFunctionsOnASingleLine: InlineOnly 42 | SpaceInEmptyBlock: true 43 | PenaltyIndentedWhitespace: 100 44 | -------------------------------------------------------------------------------- /.github/config.env: -------------------------------------------------------------------------------- 1 | # The documentation repository name 2 | # User name defaults to github.repository_owner and can be changed in .github/workflows/docs.yml 3 | docs_repo=libscratchcpp-docs 4 | 5 | # Whether to build documentation 6 | build_docs=1 7 | 8 | # Whether to deploy documentation to the docs repository (requires build_docs=1) 9 | deploy_docs=1 10 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: '*' 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | BUILD_TYPE: Release 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | submodules: true 20 | 21 | - name: Install dependencies 22 | run: | 23 | sudo apt-get update 24 | sudo apt-get install -y nlohmann-json3-dev libutfcpp-dev 25 | shell: bash 26 | - name: Configure CMake 27 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 28 | 29 | - name: Build 30 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j$(nproc --all) 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Update documentation 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Setup environment 13 | run: | 14 | sed -i -e '/^#/d' .github/config.env 15 | sed -i -e '/^$/d' .github/config.env 16 | cat .github/config.env >> "${GITHUB_ENV}" 17 | - uses: actions/checkout@v3 18 | with: 19 | repository: ${{ github.repository_owner }}/${{ env.docs_repo }} 20 | token: ${{ secrets.PUSH_TOKEN }} 21 | path: docs-repo 22 | - if: env.build_docs == 1 23 | name: Build docs 24 | uses: mattnotmitt/doxygen-action@v1.1.0 25 | with: 26 | doxyfile-path: "./Doxyfile" 27 | working-directory: "." 28 | - if: env.build_docs == 1 && env.deploy_docs == 1 29 | name: Deploy 30 | run: | 31 | cd docs-repo 32 | git checkout --orphan new-branch 33 | sudo chown -R $(whoami):$(whoami) ../docs 34 | git rm -rf . || true 35 | sudo mv ../docs-output/* ./ 36 | git config user.name "GitHub Actions Bot" 37 | git config user.email "<>" 38 | git add -A 39 | git commit -m "Upload docs" 40 | git branch -D master 41 | git branch -m master 42 | git push -f origin master 43 | -------------------------------------------------------------------------------- /.github/workflows/utests-minimal.yml: -------------------------------------------------------------------------------- 1 | name: Unit tests (minimal build) 2 | 3 | on: 4 | push: 5 | branches: '*' 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | submodules: true 20 | 21 | - name: Configure CMake 22 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DLIBSCRATCHCPP_BUILD_UNIT_TESTS=ON -DLIBSCRATCHCPP_AUDIO_SUPPORT=OFF -DLIBSCRATCHCPP_NETWORK_SUPPORT=OFF 23 | 24 | - name: Build 25 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j$(nproc --all) 26 | 27 | - name: Run unit tests 28 | run: ctest --test-dir build -V 29 | -------------------------------------------------------------------------------- /.github/workflows/utests.yml: -------------------------------------------------------------------------------- 1 | name: Unit tests 2 | 3 | on: 4 | push: 5 | branches: '*' 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | submodules: true 20 | 21 | - name: Install dependencies 22 | run: | 23 | sudo apt-get update 24 | sudo apt-get install -y nlohmann-json3-dev libutfcpp-dev 25 | shell: bash 26 | - name: Configure CMake 27 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DLIBSCRATCHCPP_BUILD_UNIT_TESTS=ON 28 | 29 | - name: Build 30 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j$(nproc --all) 31 | 32 | - name: Run unit tests 33 | run: ctest --test-dir build -V 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.o 9 | *.obj 10 | *.orig 11 | *.rej 12 | *.so 13 | *.so.* 14 | *_pch.h.cpp 15 | *_resource.rc 16 | .#* 17 | *.*# 18 | core 19 | !core/ 20 | tags 21 | .DS_Store 22 | .directory 23 | *.debug 24 | Makefile* 25 | *.app 26 | Thumbs.db 27 | *.res 28 | *.rc 29 | 30 | # qtcreator generated files 31 | *.pro.user* 32 | *.user 33 | 34 | # xemacs temporary files 35 | *.flc 36 | 37 | # Vim temporary files 38 | .*.swp 39 | 40 | # Visual Studio generated files 41 | *.ib_pdb_index 42 | *.idb 43 | *.ilk 44 | *.pdb 45 | *.sln 46 | *.suo 47 | *.vcproj 48 | *vcproj.*.*.user 49 | *.ncb 50 | *.sdf 51 | *.opensdf 52 | *.vcxproj 53 | *vcxproj.* 54 | 55 | # MinGW generated files 56 | *.Debug 57 | *.Release 58 | 59 | # Python byte code 60 | *.pyc 61 | 62 | # Binaries 63 | # -------- 64 | *.dll 65 | *.exe 66 | 67 | # Docs 68 | docs-output/ 69 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "thirdparty/zip"] 2 | path = thirdparty/zip 3 | url = https://github.com/kuba--/zip 4 | [submodule "thirdparty/googletest"] 5 | path = thirdparty/googletest 6 | url = https://github.com/google/googletest 7 | [submodule "thirdparty/utfcpp"] 8 | path = thirdparty/utfcpp 9 | url = https://github.com/nemtrif/utfcpp 10 | -------------------------------------------------------------------------------- /build/HunterPackages.cmake: -------------------------------------------------------------------------------- 1 | # https://layle.me/posts/using-llvm-with-cmake/ 2 | # HUNTER_URL is the URL to the latest source code archive on GitHub 3 | # HUNTER_SHA1 is the hash of the downloaded archive 4 | 5 | set(OLD_PROJECT_NAME ${PROJECT_NAME}) 6 | set(PROJECT_NAME "") 7 | 8 | set(HUNTER_URL "https://github.com/scratchcpp/hunter/archive/ee768cdd2c027b5be346f114e726d4b0c4296de6.zip") 9 | set(HUNTER_SHA1 "4A018750743AC656A859C99C655723EAF68EE038") 10 | 11 | set(HUNTER_LLVM_VERSION 19.1.0) 12 | set(HUNTER_LLVM_CMAKE_ARGS 13 | LLVM_ENABLE_CRASH_OVERRIDES=OFF 14 | LLVM_ENABLE_ZLIB=OFF 15 | LLVM_ENABLE_RTTI=ON 16 | LLVM_BUILD_EXAMPLES=OFF 17 | LLVM_BUILD_TOOLS=OFF 18 | LLVM_BUILD_LLVM_DYLIB=ON 19 | LLVM_INCLUDE_EXAMPLES=OFF 20 | LLVM_TARGETS_TO_BUILD=host 21 | ) 22 | 23 | if(CMAKE_BUILD_TYPE EQUAL "Debug") 24 | set(HUNTER_LLVM_CMAKE_ARGS ${HUNTER_LLVM_CMAKE_ARGS} LLVM_ENABLE_ASSERTIONS=ON) 25 | else() 26 | set(HUNTER_LLVM_CMAKE_ARGS ${HUNTER_LLVM_CMAKE_ARGS} LLVM_ENABLE_ASSERTIONS=OFF) 27 | endif() 28 | 29 | set(HUNTER_PACKAGES LLVM) 30 | 31 | include(FetchContent) 32 | message(STATUS "Fetching hunter...") 33 | FetchContent_Declare(SetupHunter GIT_REPOSITORY https://github.com/cpp-pm/gate) 34 | FetchContent_MakeAvailable(SetupHunter) 35 | 36 | set(PROJECT_NAME ${OLD_PROJECT_NAME}) 37 | -------------------------------------------------------------------------------- /build/zip.cmake: -------------------------------------------------------------------------------- 1 | set(ZIP_SRC ${PROJECT_SOURCE_DIR}/thirdparty/zip/src) 2 | 3 | add_library(zip SHARED 4 | ${ZIP_SRC}/zip.c 5 | ${ZIP_SRC}/zip.h 6 | ${ZIP_SRC}/miniz.h 7 | ) 8 | 9 | target_include_directories(zip PUBLIC ${ZIP_SRC}) 10 | install(TARGETS zip DESTINATION lib) 11 | -------------------------------------------------------------------------------- /docs/Getting started.md: -------------------------------------------------------------------------------- 1 | \page gettingStarted Getting started 2 | 3 | libscratchcpp doesn't have any GUI support, but sprites and the stage can be easily implemented using 4 | the \link libscratchcpp::IStageHandler IStageHandler \endlink and 5 | \link libscratchcpp::ISpriteHandler ISpriteHandler \endlink interfaces. 6 | 7 | They can be subclassed for listening to events such as when the X and Y coordinates 8 | of a sprite change. 9 | 10 | ## CLI-only example 11 | ```cpp 12 | #include 13 | 14 | int main(int argc, char **argv) { 15 | libscratchcpp::Project p("/path/to/project.sb3"); 16 | bool ret = p.load(); 17 | if (!ret) 18 | return 1; 19 | 20 | p.run(); 21 | return 0; 22 | } 23 | ``` 24 | The \link libscratchcpp::Project::run() run() \endlink method runs an event loop which stops after all scripts finish. 25 | 26 | For CLI project players, using \link libscratchcpp::Project::run() run() \endlink is enough. If you are developing 27 | a GUI project player and need to receive input events such as key presses, you'll need to use \link libscratchcpp::IEngine::step() step() \endlink 28 | for ticks and \link libscratchcpp::Project::start() start() \endlink and \link libscratchcpp::Project::stop() stop() \endlink 29 | -------------------------------------------------------------------------------- /docs/Home.md: -------------------------------------------------------------------------------- 1 | **libscratchcpp** is a library for building C++ based Scratch project players. 2 | 3 | It provides an API for reading and running Scratch projects which makes it easy 4 | to create a GUI application that runs Scratch projects. 5 | 6 | The idea is to implement Scratch blocks in C++ to build a fast project player 7 | that is faster than the original Scratch VM. 8 | 9 | ## NOTE 10 | This library is still in development and it shouldn't be used 11 | to build complete Scratch project players yet. 12 | 13 | **The instructions below might not be accurate and can change anytime.** 14 | 15 | **There might be incompatible API changes anytime before version 1.0.0 releases!** 16 | 17 | ## Getting started 18 | See the [Getting started](gettingStarted.html) page. 19 | 20 | ## Extending 21 | See the [Extensions](extensions.html) page for instructions on how to create extensions. 22 | -------------------------------------------------------------------------------- /include/scratchcpp/asset.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "entity.h" 6 | #include "spimpl.h" 7 | #include "global.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Target; 13 | class AssetPrivate; 14 | 15 | /*! \brief The Asset class represents a Scratch asset, for example a Costume or a Sound. */ 16 | class LIBSCRATCHCPP_EXPORT Asset : public Entity 17 | { 18 | public: 19 | Asset(const std::string &name, const std::string &id, const std::string &format); 20 | Asset(const Asset &) = delete; 21 | 22 | virtual ~Asset(); 23 | 24 | void setId(const std::string &id); 25 | 26 | const std::string &name() const; 27 | 28 | const std::string &fileName() const; 29 | 30 | const std::string &dataFormat() const; 31 | 32 | const void *data() const; 33 | unsigned int dataSize() const; 34 | void setData(unsigned int size, void *data); 35 | 36 | Target *target() const; 37 | void setTarget(Target *target); 38 | 39 | protected: 40 | virtual void processData(unsigned int size, void *data) { } 41 | virtual bool isClone() const { return false; } 42 | 43 | private: 44 | spimpl::unique_impl_ptr impl; 45 | }; 46 | 47 | } // namespace libscratchcpp 48 | -------------------------------------------------------------------------------- /include/scratchcpp/broadcast.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "entity.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class BroadcastPrivate; 11 | 12 | /*! \brief The Broadcast class represents a Scratch broadcast. */ 13 | class LIBSCRATCHCPP_EXPORT Broadcast : public Entity 14 | { 15 | public: 16 | Broadcast(const std::string &id, const std::string &name, bool isBackdropBroadcast = false); 17 | Broadcast(const Broadcast &) = delete; 18 | 19 | const std::string &name() const; 20 | void setName(const std::string &newName); 21 | 22 | bool isBackdropBroadcast() const; 23 | 24 | private: 25 | spimpl::unique_impl_ptr impl; 26 | }; 27 | 28 | } // namespace libscratchcpp 29 | -------------------------------------------------------------------------------- /include/scratchcpp/comment.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "entity.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class Block; 11 | class CommentPrivate; 12 | 13 | /*! \brief The Comment class represents a comment in the code area. */ 14 | class LIBSCRATCHCPP_EXPORT Comment : public Entity 15 | { 16 | public: 17 | Comment(const std::string &id, double x = 0, double y = 0); 18 | Comment(const Comment &) = delete; 19 | 20 | const std::string &blockId() const; 21 | void setBlockId(const std::string id); 22 | 23 | Block *block() const; 24 | void setBlock(Block *block); 25 | 26 | double x() const; 27 | void setX(double x); 28 | 29 | double y() const; 30 | void setY(double y); 31 | 32 | double width() const; 33 | void setWidth(double width); 34 | 35 | double height() const; 36 | void setHeight(double height); 37 | 38 | bool minimized() const; 39 | void setMinimized(bool minimized); 40 | 41 | const std::string &text() const; 42 | void setText(const std::string &text); 43 | 44 | private: 45 | spimpl::unique_impl_ptr impl; 46 | }; 47 | 48 | } // namespace libscratchcpp 49 | -------------------------------------------------------------------------------- /include/scratchcpp/compilerconstant.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "compilervalue.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class CompilerConstantPrivate; 11 | 12 | /*! \brief The CompilerConstant class represents a constant value in compiled code. */ 13 | class LIBSCRATCHCPP_EXPORT CompilerConstant : public virtual CompilerValue 14 | { 15 | public: 16 | CompilerConstant(Compiler::StaticType type, const Value &value); 17 | CompilerConstant(const CompilerConstant &) = delete; 18 | 19 | bool isConst() const override final { return true; }; 20 | 21 | const Value &value() const; 22 | 23 | private: 24 | spimpl::unique_impl_ptr impl; 25 | }; 26 | 27 | } // namespace libscratchcpp 28 | -------------------------------------------------------------------------------- /include/scratchcpp/compilercontext.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "spimpl.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class IEngine; 12 | class Target; 13 | class CompilerContextPrivate; 14 | 15 | /*! \brief The CompilerContext represents a context for a specific target which is used with the Compiler class. */ 16 | class LIBSCRATCHCPP_EXPORT CompilerContext 17 | { 18 | public: 19 | CompilerContext(IEngine *engine, Target *target); 20 | CompilerContext(const CompilerContext &) = delete; 21 | virtual ~CompilerContext() { } 22 | 23 | IEngine *engine() const; 24 | Target *target() const; 25 | 26 | /*! 27 | * Optimizes compiled scripts ahead of time. 28 | * \see Compiler#preoptimize() 29 | */ 30 | virtual void preoptimize() { } 31 | 32 | private: 33 | spimpl::unique_impl_ptr impl; 34 | }; 35 | 36 | } // namespace libscratchcpp 37 | -------------------------------------------------------------------------------- /include/scratchcpp/compilerlocalvariable.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "compiler.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class CompilerLocalVariablePrivate; 11 | 12 | /*! \brief The CompilerLocalVariable class represents a statically typed local variable in compiled code. */ 13 | class LIBSCRATCHCPP_EXPORT CompilerLocalVariable 14 | { 15 | public: 16 | CompilerLocalVariable(CompilerValue *ptr); 17 | CompilerLocalVariable(const CompilerLocalVariable &) = delete; 18 | 19 | CompilerValue *ptr() const; 20 | Compiler::StaticType type() const; 21 | 22 | private: 23 | spimpl::unique_impl_ptr impl; 24 | }; 25 | 26 | } // namespace libscratchcpp 27 | -------------------------------------------------------------------------------- /include/scratchcpp/compilervalue.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "compiler.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class CompilerValuePrivate; 11 | 12 | /*! \brief The CompilerValue class represents a local value in compiled code. */ 13 | class LIBSCRATCHCPP_EXPORT CompilerValue 14 | { 15 | public: 16 | CompilerValue(Compiler::StaticType type); 17 | CompilerValue(const CompilerValue &) = delete; 18 | virtual ~CompilerValue() { } 19 | 20 | Compiler::StaticType type() const; 21 | void setType(Compiler::StaticType type); 22 | 23 | virtual bool isConst() const { return false; }; 24 | 25 | private: 26 | spimpl::unique_impl_ptr impl; 27 | }; 28 | 29 | } // namespace libscratchcpp 30 | -------------------------------------------------------------------------------- /include/scratchcpp/costume.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "spimpl.h" 6 | 7 | #include "asset.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Broadcast; 13 | class CostumePrivate; 14 | 15 | /*! \brief The Costume class represents a Scratch costume. */ 16 | class LIBSCRATCHCPP_EXPORT Costume : public Asset 17 | { 18 | public: 19 | Costume(const std::string &name, const std::string &id, const std::string &format); 20 | Costume(const Costume &) = delete; 21 | 22 | double bitmapResolution() const; 23 | void setBitmapResolution(double newBitmapResolution); 24 | 25 | int rotationCenterX() const; 26 | void setRotationCenterX(int newRotationCenterX); 27 | 28 | int rotationCenterY() const; 29 | void setRotationCenterY(int newRotationCenterY); 30 | 31 | Broadcast *broadcast(); 32 | 33 | private: 34 | spimpl::unique_impl_ptr impl; 35 | }; 36 | 37 | } // namespace libscratchcpp 38 | -------------------------------------------------------------------------------- /include/scratchcpp/drawable.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "signal.h" 7 | #include "spimpl.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class IEngine; 13 | 14 | class DrawablePrivate; 15 | 16 | /*! \brief The Drawable class is the base class of rendered elements (stage, sprites, text bubbles). */ 17 | class LIBSCRATCHCPP_EXPORT Drawable 18 | { 19 | public: 20 | Drawable(); 21 | Drawable(const Drawable &) = delete; 22 | 23 | /*! Returns true if this Drawable is a Target. */ 24 | virtual bool isTarget() const { return false; } 25 | 26 | /*! Returns true if this Drawable is a TextBubble. */ 27 | virtual bool isTextBubble() const { return false; } 28 | 29 | int layerOrder() const; 30 | virtual void setLayerOrder(int newLayerOrder); 31 | sigslot::signal &layerOrderChanged() const; 32 | 33 | IEngine *engine() const; 34 | virtual void setEngine(IEngine *engine); 35 | 36 | private: 37 | spimpl::unique_impl_ptr impl; 38 | }; 39 | 40 | } // namespace libscratchcpp 41 | -------------------------------------------------------------------------------- /include/scratchcpp/entity.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "global.h" 8 | #include "spimpl.h" 9 | 10 | namespace libscratchcpp 11 | { 12 | 13 | class EntityPrivate; 14 | 15 | /*! \brief The Entity class is the base class of everything that is identified by an ID (Target, Variable, List, etc.). */ 16 | class LIBSCRATCHCPP_EXPORT Entity 17 | { 18 | public: 19 | Entity(const std::string &id); 20 | Entity(const Entity &) = delete; 21 | 22 | virtual ~Entity() { } 23 | 24 | const std::string &id() const; 25 | 26 | void setId(const std::string &newId); 27 | 28 | private: 29 | spimpl::unique_impl_ptr impl; 30 | }; 31 | 32 | } // namespace libscratchcpp 33 | -------------------------------------------------------------------------------- /include/scratchcpp/executioncontext.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "spimpl.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class Thread; 12 | class IEngine; 13 | class Promise; 14 | class IStackTimer; 15 | class IRandomGenerator; 16 | class ExecutionContextPrivate; 17 | 18 | /*! \brief The ExecutionContext represents the execution context of a target (can be a clone) with variables, lists, etc. */ 19 | class LIBSCRATCHCPP_EXPORT ExecutionContext 20 | { 21 | public: 22 | ExecutionContext(Thread *thread); 23 | ExecutionContext(const ExecutionContext &) = delete; 24 | virtual ~ExecutionContext() { } 25 | 26 | Thread *thread() const; 27 | IEngine *engine() const; 28 | 29 | std::shared_ptr promise() const; 30 | void setPromise(std::shared_ptr promise); 31 | 32 | IStackTimer *stackTimer() const; 33 | void setStackTimer(IStackTimer *newStackTimer); 34 | 35 | IRandomGenerator *rng() const; 36 | void setRng(IRandomGenerator *newRng); 37 | 38 | private: 39 | spimpl::unique_impl_ptr impl; 40 | }; 41 | 42 | } // namespace libscratchcpp 43 | -------------------------------------------------------------------------------- /include/scratchcpp/field.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | #include "global.h" 9 | #include "spimpl.h" 10 | 11 | namespace libscratchcpp 12 | { 13 | 14 | class Entity; 15 | class Value; 16 | class FieldPrivate; 17 | 18 | /*! \brief The Field class represents a Scratch block field. */ 19 | class LIBSCRATCHCPP_EXPORT Field 20 | { 21 | public: 22 | Field(const std::string &name, const Value &value, std::shared_ptr valuePtr = nullptr); 23 | Field(const std::string &name, const Value &value, const std::string &valueId); 24 | Field(const std::string &name, const Value &value, const char *valueId); 25 | Field(const Field &) = delete; 26 | 27 | const std::string &name() const; 28 | 29 | int fieldId() const; 30 | void setFieldId(int newFieldId); 31 | 32 | const Value &value() const; 33 | 34 | std::shared_ptr valuePtr() const; 35 | void setValuePtr(const std::shared_ptr &newValuePtr); 36 | 37 | const std::string &valueId() const; 38 | 39 | int specialValueId() const; 40 | void setSpecialValueId(int newSpecialValueId); 41 | 42 | private: 43 | spimpl::unique_impl_ptr impl; 44 | }; 45 | 46 | } // namespace libscratchcpp 47 | -------------------------------------------------------------------------------- /include/scratchcpp/iextension.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "value_functions.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IEngine; 11 | 12 | /*! 13 | * \brief The IExtension class is an interface for extensions. 14 | * 15 | * \see Extensions 16 | */ 17 | class LIBSCRATCHCPP_EXPORT IExtension 18 | { 19 | public: 20 | virtual ~IExtension() { } 21 | 22 | /*! Returns the name of the extension. */ 23 | virtual std::string name() const = 0; 24 | 25 | /*! Returns the description of the extension. */ 26 | virtual std::string description() const = 0; 27 | 28 | /*! Returns the block color of the extension. */ 29 | virtual Rgb color() const = 0; 30 | 31 | /*! Override this method to register blocks. */ 32 | virtual void registerBlocks(IEngine *engine) = 0; 33 | 34 | /*! This method is called when a project is loaded. */ 35 | virtual void onInit(IEngine *engine) { } 36 | }; 37 | 38 | } // namespace libscratchcpp 39 | -------------------------------------------------------------------------------- /include/scratchcpp/igraphicseffect.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "global.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | /*! \brief The IGraphicsEffects class is an interface for custom graphics effects. */ 13 | class LIBSCRATCHCPP_EXPORT IGraphicsEffect 14 | { 15 | public: 16 | virtual ~IGraphicsEffect() { } 17 | 18 | /*! Returns the name of the graphics effect. */ 19 | virtual std::string name() const = 0; 20 | 21 | /*! Returns the clamped value of the graphic effect. */ 22 | virtual double clamp(double value) const = 0; 23 | }; 24 | 25 | } // namespace libscratchcpp 26 | -------------------------------------------------------------------------------- /include/scratchcpp/imonitorhandler.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class Monitor; 11 | class Value; 12 | 13 | class LIBSCRATCHCPP_EXPORT IMonitorHandler 14 | { 15 | public: 16 | virtual ~IMonitorHandler() { } 17 | 18 | virtual void init(Monitor *monitor) = 0; 19 | 20 | virtual void onValueChanged(const Value &value) = 0; 21 | virtual void onXChanged(int x) = 0; 22 | virtual void onYChanged(int y) = 0; 23 | virtual void onVisibleChanged(bool visible) = 0; 24 | }; 25 | 26 | } // namespace libscratchcpp 27 | -------------------------------------------------------------------------------- /include/scratchcpp/irandomgenerator.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | /*! \brief The IRandomGenerator interface represents a random number generator that can be received e. g. from an ExecutionContext. */ 11 | class LIBSCRATCHCPP_EXPORT IRandomGenerator 12 | { 13 | public: 14 | virtual ~IRandomGenerator() { } 15 | 16 | /*! Returns a random integer in the given range (inclusive). */ 17 | virtual long randint(long start, long end) const = 0; 18 | 19 | /*! Returns a random double in the given range (inclusive). */ 20 | virtual double randintDouble(double start, double end) const = 0; 21 | 22 | /*! Returns a random integer in the given range (inclusive) except the given integer. */ 23 | virtual long randintExcept(long start, long end, long except) const = 0; 24 | }; 25 | 26 | } // namespace libscratchcpp 27 | -------------------------------------------------------------------------------- /include/scratchcpp/istacktimer.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | /*! 11 | * \brief The IStackTimer interface represents a timer that can be used by blocks. 12 | * 13 | * You can get a stack timer using ExecutionContext#stackTimer(). 14 | */ 15 | class LIBSCRATCHCPP_EXPORT IStackTimer 16 | { 17 | public: 18 | virtual ~IStackTimer() { } 19 | 20 | /*! Starts the timer. */ 21 | virtual void start(double seconds) = 0; 22 | 23 | /*! Stops the timer. */ 24 | virtual void stop() = 0; 25 | 26 | /*! Returns true if the timer has been stopped using stop() or wasn't used at all. */ 27 | virtual bool stopped() const = 0; 28 | 29 | /*! Returns true if the timer has elapsed. */ 30 | virtual bool elapsed() const = 0; 31 | 32 | /*! Returns the elapsed time in seconds. */ 33 | virtual double elapsedTime() const = 0; 34 | }; 35 | 36 | } // namespace libscratchcpp 37 | -------------------------------------------------------------------------------- /include/scratchcpp/itimer.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | /*! 9 | * \brief The ITimer interface represents a timer of a Scratch project. 10 | * 11 | * You can get a project timer using Engine#timer(). 12 | */ 13 | class ITimer 14 | { 15 | public: 16 | virtual ~ITimer() { } 17 | 18 | /*! Returns the time since last reset in seconds. */ 19 | virtual double value() const = 0; 20 | 21 | /*! Resets the timer. */ 22 | virtual void reset() = 0; 23 | }; 24 | 25 | } // namespace libscratchcpp 26 | -------------------------------------------------------------------------------- /include/scratchcpp/keyevent.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "spimpl.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class KeyEventPrivate; 12 | 13 | /*! \brief The KeyEvent class represents a Scratch key event. */ 14 | class LIBSCRATCHCPP_EXPORT KeyEvent 15 | { 16 | public: 17 | enum class Type 18 | { 19 | Any, 20 | Space, 21 | Left, 22 | Up, 23 | Right, 24 | Down, 25 | Enter 26 | }; 27 | 28 | KeyEvent(Type type = Type::Any); 29 | KeyEvent(const std::string &name); 30 | 31 | Type type() const; 32 | const std::string &name() const; 33 | 34 | friend bool operator==(const KeyEvent &ev1, const KeyEvent &ev2) { return ev1.name() == ev2.name(); } 35 | 36 | private: 37 | spimpl::impl_ptr impl; 38 | }; 39 | 40 | } // namespace libscratchcpp 41 | -------------------------------------------------------------------------------- /include/scratchcpp/project.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include "spimpl.h" 8 | 9 | #include "global.h" 10 | #include "signal.h" 11 | 12 | namespace libscratchcpp 13 | { 14 | 15 | class ProjectPrivate; 16 | 17 | class IEngine; 18 | 19 | /*! 20 | * \brief The Project class provides API for reading and running Scratch projects. 21 | * 22 | * \note Loading online projects is supported if the LIBSCRATCHCPP_NETWORK_SUPPORT option is set, just use setFileName("some URL") 23 | */ 24 | class LIBSCRATCHCPP_EXPORT Project 25 | { 26 | public: 27 | Project(); 28 | Project(const std::string &fileName); 29 | Project(const Project &) = delete; 30 | 31 | bool load(); 32 | void stopLoading(); 33 | 34 | void start(); 35 | void run(); 36 | void runEventLoop(); 37 | 38 | const std::string &fileName() const; 39 | void setFileName(const std::string &newFileName); 40 | 41 | std::shared_ptr engine() const; 42 | 43 | sigslot::signal &downloadProgressChanged(); 44 | 45 | private: 46 | spimpl::unique_impl_ptr impl; 47 | }; 48 | 49 | } // namespace libscratchcpp 50 | -------------------------------------------------------------------------------- /include/scratchcpp/promise.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "spimpl.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class PromisePrivate; 12 | 13 | /*! \brief The Promise class represents the eventual completion of an asynchronous operation. */ 14 | class LIBSCRATCHCPP_EXPORT Promise 15 | { 16 | public: 17 | Promise(); 18 | Promise(const Promise &) = delete; 19 | 20 | bool isResolved() const; 21 | void resolve(); 22 | 23 | private: 24 | spimpl::unique_impl_ptr impl; 25 | }; 26 | 27 | } // namespace libscratchcpp 28 | -------------------------------------------------------------------------------- /include/scratchcpp/rect.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "spimpl.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class RectPrivate; 12 | 13 | /*! The Rect class represents a rectangle. */ 14 | class LIBSCRATCHCPP_EXPORT Rect 15 | { 16 | public: 17 | Rect(double left, double top, double right, double bottom); 18 | Rect(); 19 | 20 | double left() const; 21 | void setLeft(double left); 22 | 23 | double top() const; 24 | void setTop(double top); 25 | 26 | double right() const; 27 | void setRight(double right); 28 | 29 | double bottom() const; 30 | void setBottom(double bottom); 31 | 32 | double width() const; 33 | double height() const; 34 | 35 | void clamp(double left, double top, double right, double bottom); 36 | void snapToInt(); 37 | 38 | bool intersects(const Rect &rect) const; 39 | bool contains(double x, double y) const; 40 | 41 | static void intersected(const Rect &a, const Rect &b, Rect &dst); 42 | static void united(const Rect &a, const Rect &b, Rect &dst); 43 | 44 | private: 45 | spimpl::impl_ptr impl; 46 | }; 47 | 48 | } // namespace libscratchcpp 49 | -------------------------------------------------------------------------------- /include/scratchcpp/script.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | #include "global.h" 9 | #include "spimpl.h" 10 | 11 | namespace libscratchcpp 12 | { 13 | 14 | class Target; 15 | class Block; 16 | class IEngine; 17 | class ExecutableCode; 18 | class Thread; 19 | class ScriptPrivate; 20 | 21 | /*! \brief The Script class represents a compiled Scratch script. */ 22 | class LIBSCRATCHCPP_EXPORT Script 23 | { 24 | public: 25 | Script(Target *target, Block *topBlock, IEngine *engine); 26 | Script(const Script &) = delete; 27 | 28 | Target *target() const; 29 | Block *topBlock() const; 30 | 31 | ExecutableCode *code() const; 32 | void setCode(std::shared_ptr code); 33 | 34 | ExecutableCode *hatPredicateCode() const; 35 | void setHatPredicateCode(std::shared_ptr code); 36 | 37 | bool runHatPredicate(Target *target); 38 | 39 | std::shared_ptr start(); 40 | std::shared_ptr start(Target *target); 41 | 42 | private: 43 | spimpl::unique_impl_ptr impl; 44 | }; 45 | 46 | } // namespace libscratchcpp 47 | -------------------------------------------------------------------------------- /include/scratchcpp/string_pool.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct StringPtr; 11 | 12 | extern "C" 13 | { 14 | LIBSCRATCHCPP_EXPORT StringPtr *string_pool_new(bool internal = false); 15 | LIBSCRATCHCPP_EXPORT void string_pool_free(StringPtr *str); 16 | } 17 | 18 | } // namespace libscratchcpp 19 | -------------------------------------------------------------------------------- /include/scratchcpp/stringptr.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "global.h" 6 | #include "string_functions.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | extern "C" 12 | { 13 | /*! \brief The StringPtr struct holds a string data pointer and string size */ 14 | struct LIBSCRATCHCPP_EXPORT StringPtr 15 | { 16 | // NOTE: Constructors and destructors only work in C++ code and are not supposed to be used in LLVM IR 17 | StringPtr() = default; 18 | StringPtr(const std::string &str) { string_assign_cstring(this, str.c_str()); } 19 | StringPtr(const StringPtr &) = delete; 20 | 21 | ~StringPtr() 22 | { 23 | if (data && allocatedSize > 0) 24 | free(data); 25 | } 26 | 27 | // NOTE: Any changes must also be done in the LLVM code builder! 28 | char16_t *data = nullptr; 29 | size_t size = 0; 30 | size_t allocatedSize = 0; 31 | }; 32 | } 33 | 34 | } // namespace libscratchcpp 35 | -------------------------------------------------------------------------------- /include/scratchcpp/textbubble.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "drawable.h" 6 | #include "signal.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class Thread; 12 | class TextBubblePrivate; 13 | 14 | /*! \brief The TextBubble class represents a text bubble created using say or think block. */ 15 | class LIBSCRATCHCPP_EXPORT TextBubble : public Drawable 16 | { 17 | public: 18 | enum class Type 19 | { 20 | Say, 21 | Think 22 | }; 23 | 24 | TextBubble(); 25 | TextBubble(const TextBubble &) = delete; 26 | 27 | bool isTextBubble() const override final; 28 | 29 | Type type() const; 30 | virtual void setType(Type type); 31 | sigslot::signal &typeChanged() const; 32 | 33 | const std::string &text() const; 34 | virtual void setText(const std::string &text); 35 | virtual void setText(const std::string &text, Thread *owner); 36 | sigslot::signal &textChanged() const; 37 | 38 | Thread *owner() const; 39 | 40 | private: 41 | spimpl::unique_impl_ptr impl; 42 | }; 43 | 44 | } // namespace libscratchcpp 45 | -------------------------------------------------------------------------------- /include/scratchcpp/thread.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "valuedata.h" 6 | #include "spimpl.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class Target; 12 | class Promise; 13 | class IEngine; 14 | class Script; 15 | class ThreadPrivate; 16 | 17 | /*! \brief The Thread class represents a running Scratch script. */ 18 | class LIBSCRATCHCPP_EXPORT Thread 19 | { 20 | public: 21 | Thread(Target *target, IEngine *engine, Script *script); 22 | Thread(const Thread &) = delete; 23 | ~Thread(); 24 | 25 | Target *target() const; 26 | IEngine *engine() const; 27 | Script *script() const; 28 | 29 | void run(); 30 | ValueData runReporter(); 31 | bool runPredicate(); 32 | void kill(); 33 | void reset(); 34 | 35 | bool isFinished() const; 36 | 37 | std::shared_ptr promise() const; 38 | void setPromise(std::shared_ptr promise); 39 | 40 | private: 41 | spimpl::unique_impl_ptr impl; 42 | }; 43 | 44 | } // namespace libscratchcpp 45 | -------------------------------------------------------------------------------- /include/scratchcpp/valuedata.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "global.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | struct StringPtr; 13 | 14 | enum class LIBSCRATCHCPP_EXPORT ValueType 15 | { 16 | Number = 0, 17 | Bool = 1, 18 | String = 2, 19 | Pointer = 3 20 | }; 21 | 22 | extern "C" 23 | { 24 | /*! \brief The ValueData struct holds the data of Value. It's used in compiled Scratch code for better performance. */ 25 | struct LIBSCRATCHCPP_EXPORT ValueData 26 | { 27 | // NOTE: Any changes must also be done in the LLVM code builder! 28 | union 29 | { 30 | double numberValue; 31 | bool boolValue; 32 | StringPtr *stringValue; 33 | const void *pointerValue; 34 | }; 35 | 36 | ValueType type; 37 | }; 38 | } 39 | 40 | } // namespace libscratchcpp 41 | -------------------------------------------------------------------------------- /include/scratchcpp/variable.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Target; 13 | class Monitor; 14 | class VariablePrivate; 15 | 16 | /*! \brief The Variable class represents a Scratch variable. */ 17 | class LIBSCRATCHCPP_EXPORT Variable : public Entity 18 | { 19 | public: 20 | Variable(const std::string &id, const std::string &name, const Value &value = Value(), bool isCloudVariable = false); 21 | Variable(const Variable &) = delete; 22 | 23 | const std::string &name() const; 24 | 25 | const Value &value() const; 26 | 27 | Value *valuePtr(); 28 | 29 | void setValue(const Value &value); 30 | 31 | bool isCloudVariable() const; 32 | void setIsCloudVariable(bool isCloudVariable); 33 | 34 | Target *target() const; 35 | void setTarget(Target *target); 36 | 37 | Monitor *monitor() const; 38 | void setMonitor(Monitor *monitor); 39 | 40 | std::shared_ptr clone(); 41 | 42 | private: 43 | spimpl::unique_impl_ptr impl; 44 | }; 45 | 46 | } // namespace libscratchcpp 47 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(scratchcpp 2 | PRIVATE 3 | project.cpp 4 | project_p.cpp 5 | project_p.h 6 | scratchconfiguration.cpp 7 | scratchconfiguration_p.cpp 8 | scratchconfiguration_p.h 9 | rect.cpp 10 | rect_p.cpp 11 | rect_p.h 12 | ) 13 | 14 | add_subdirectory(blocks) 15 | add_subdirectory(engine) 16 | add_subdirectory(internal) 17 | add_subdirectory(scratch) 18 | add_subdirectory(audio) 19 | add_subdirectory(test) 20 | -------------------------------------------------------------------------------- /src/audio/audioinput.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "audioinput.h" 4 | 5 | #ifdef LIBSCRATCHCPP_AUDIO_SUPPORT 6 | #include "internal/audioloudness.h" 7 | #else 8 | #include "internal/audioloudnessstub.h" 9 | #endif 10 | 11 | using namespace libscratchcpp; 12 | 13 | static std::shared_ptr INSTANCE = std::make_shared(); 14 | 15 | AudioInput::AudioInput() 16 | { 17 | } 18 | 19 | std::shared_ptr AudioInput::instance() 20 | { 21 | return INSTANCE; 22 | } 23 | 24 | std::shared_ptr AudioInput::audioLoudness() const 25 | { 26 | if (!m_audioLoudness) { 27 | #ifdef LIBSCRATCHCPP_AUDIO_SUPPORT 28 | m_audioLoudness = std::make_shared(); 29 | #else 30 | m_audioLoudness = std::make_shared(); 31 | #endif 32 | } 33 | 34 | return m_audioLoudness; 35 | } 36 | -------------------------------------------------------------------------------- /src/audio/audioinput.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "iaudioinput.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class AudioInput : public IAudioInput 13 | { 14 | public: 15 | AudioInput(); 16 | 17 | static std::shared_ptr instance(); 18 | 19 | std::shared_ptr audioLoudness() const override; 20 | 21 | private: 22 | mutable std::shared_ptr m_audioLoudness; 23 | }; 24 | 25 | } // namespace libscratchcpp 26 | -------------------------------------------------------------------------------- /src/audio/audiooutput.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "audiooutput.h" 4 | 5 | #ifdef LIBSCRATCHCPP_AUDIO_SUPPORT 6 | #include "internal/audioplayer.h" 7 | #else 8 | #include "internal/audioplayerstub.h" 9 | #endif 10 | 11 | using namespace libscratchcpp; 12 | 13 | static std::shared_ptr INSTANCE = std::make_shared(); 14 | 15 | AudioOutput::AudioOutput() 16 | { 17 | } 18 | 19 | std::shared_ptr AudioOutput::instance() 20 | { 21 | return INSTANCE; 22 | } 23 | 24 | std::shared_ptr AudioOutput::createAudioPlayer() const 25 | { 26 | #ifdef LIBSCRATCHCPP_AUDIO_SUPPORT 27 | return std::make_shared(); 28 | #else 29 | return std::make_shared(); 30 | #endif 31 | } 32 | -------------------------------------------------------------------------------- /src/audio/audiooutput.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "iaudiooutput.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class AudioOutput : public IAudioOutput 11 | { 12 | public: 13 | AudioOutput(); 14 | 15 | static std::shared_ptr instance(); 16 | 17 | std::shared_ptr createAudioPlayer() const override; 18 | }; 19 | 20 | } // namespace libscratchcpp 21 | -------------------------------------------------------------------------------- /src/audio/iaudioengine.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IAudioEngine 11 | { 12 | public: 13 | virtual ~IAudioEngine() { } 14 | 15 | static IAudioEngine *instance(); 16 | 17 | virtual float volume() const = 0; 18 | virtual void setVolume(float volume) = 0; 19 | }; 20 | 21 | } // namespace libscratchcpp 22 | -------------------------------------------------------------------------------- /src/audio/iaudioinput.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IAudioLoudness; 11 | 12 | class IAudioInput 13 | { 14 | 15 | public: 16 | virtual ~IAudioInput() { } 17 | 18 | virtual std::shared_ptr audioLoudness() const = 0; 19 | }; 20 | 21 | } // namespace libscratchcpp 22 | -------------------------------------------------------------------------------- /src/audio/iaudioloudness.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | class IAudioLoudness 9 | { 10 | public: 11 | virtual ~IAudioLoudness() { } 12 | 13 | virtual int getLoudness() const = 0; 14 | }; 15 | 16 | } // namespace libscratchcpp 17 | -------------------------------------------------------------------------------- /src/audio/iaudiooutput.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IAudioPlayer; 11 | 12 | class IAudioOutput 13 | { 14 | public: 15 | virtual ~IAudioOutput() { } 16 | 17 | virtual std::shared_ptr createAudioPlayer() const = 0; 18 | }; 19 | 20 | } // namespace libscratchcpp 21 | -------------------------------------------------------------------------------- /src/audio/iaudioplayer.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | class IAudioPlayer 9 | { 10 | public: 11 | virtual ~IAudioPlayer() { } 12 | 13 | virtual bool load(unsigned int size, const void *data, unsigned long sampleRate) = 0; 14 | virtual bool loadCopy(IAudioPlayer *player) = 0; 15 | 16 | virtual float volume() const = 0; 17 | virtual void setVolume(float volume) = 0; 18 | 19 | virtual float pitch() const = 0; 20 | virtual void setPitch(float pitch) = 0; 21 | 22 | virtual float pan() const = 0; 23 | virtual void setPan(float pan) = 0; 24 | 25 | virtual bool isLoaded() const = 0; 26 | 27 | virtual void start() = 0; 28 | virtual void stop() = 0; 29 | 30 | virtual bool isPlaying() const = 0; 31 | }; 32 | 33 | } // namespace libscratchcpp 34 | -------------------------------------------------------------------------------- /src/audio/internal/audioengine.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "../iaudioengine.h" 8 | 9 | struct ma_engine; 10 | 11 | namespace libscratchcpp 12 | { 13 | 14 | // This is a singleton which initializes and uninitializes the miniaudio engine 15 | class AudioEngine : public IAudioEngine 16 | { 17 | public: 18 | AudioEngine(); 19 | ~AudioEngine(); 20 | 21 | friend class IAudioEngine; 22 | 23 | static ma_engine *engine(); 24 | static bool initialized(); 25 | 26 | float volume() const override; 27 | void setVolume(float volume) override; 28 | 29 | private: 30 | void init(); 31 | 32 | ma_engine *m_engine = nullptr; 33 | bool m_initialized = false; 34 | float m_volume = 1.0f; 35 | }; 36 | 37 | } // namespace libscratchcpp 38 | -------------------------------------------------------------------------------- /src/audio/internal/audioenginestub.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "audioenginestub.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | static AudioEngineStub INSTANCE; 8 | 9 | IAudioEngine *IAudioEngine::instance() 10 | { 11 | return &INSTANCE; 12 | } 13 | 14 | AudioEngineStub::AudioEngineStub() 15 | { 16 | } 17 | 18 | float AudioEngineStub::volume() const 19 | { 20 | return m_volume; 21 | } 22 | 23 | void AudioEngineStub::setVolume(float volume) 24 | { 25 | m_volume = volume; 26 | } 27 | -------------------------------------------------------------------------------- /src/audio/internal/audioenginestub.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "../iaudioengine.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class AudioEngineStub : public IAudioEngine 11 | { 12 | public: 13 | friend class IAudioEngine; 14 | AudioEngineStub(); 15 | 16 | float volume() const override; 17 | void setVolume(float volume) override; 18 | 19 | private: 20 | float m_volume = 1.0f; 21 | }; 22 | 23 | } // namespace libscratchcpp 24 | -------------------------------------------------------------------------------- /src/audio/internal/audioloudness.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "../iaudioloudness.h" 6 | 7 | struct ma_device; 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class AudioLoudness : public IAudioLoudness 13 | { 14 | public: 15 | AudioLoudness(); 16 | ~AudioLoudness(); 17 | 18 | int getLoudness() const override; 19 | 20 | private: 21 | ma_device *m_device = nullptr; 22 | }; 23 | 24 | } // namespace libscratchcpp 25 | -------------------------------------------------------------------------------- /src/audio/internal/audioloudnessstub.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "audioloudnessstub.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | AudioLoudnessStub::AudioLoudnessStub() 8 | { 9 | } 10 | 11 | int AudioLoudnessStub::getLoudness() const 12 | { 13 | return -1; 14 | } 15 | -------------------------------------------------------------------------------- /src/audio/internal/audioloudnessstub.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "../iaudioloudness.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class AudioLoudnessStub : public IAudioLoudness 11 | { 12 | public: 13 | AudioLoudnessStub(); 14 | 15 | int getLoudness() const override; 16 | }; 17 | 18 | } // namespace libscratchcpp 19 | -------------------------------------------------------------------------------- /src/audio/internal/audioplayer.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "../iaudioplayer.h" 6 | 7 | struct ma_decoder; 8 | struct ma_sound; 9 | 10 | namespace libscratchcpp 11 | { 12 | 13 | class AudioPlayer : public IAudioPlayer 14 | { 15 | public: 16 | AudioPlayer(); 17 | ~AudioPlayer(); 18 | 19 | bool load(unsigned int size, const void *data, unsigned long sampleRate) override; 20 | bool loadCopy(IAudioPlayer *player) override; 21 | 22 | float volume() const override; 23 | void setVolume(float volume) override; 24 | 25 | float pitch() const override; 26 | void setPitch(float pitch) override; 27 | 28 | float pan() const override; 29 | void setPan(float pan) override; 30 | 31 | bool isLoaded() const override; 32 | 33 | void start() override; 34 | void stop() override; 35 | 36 | bool isPlaying() const override; 37 | 38 | private: 39 | ma_decoder *m_decoder = nullptr; 40 | ma_sound *m_sound; 41 | bool m_loaded = false; 42 | bool m_copy = false; 43 | bool m_started = false; 44 | float m_volume = 1; 45 | float m_pitch = 1; 46 | float m_pan = 0; 47 | }; 48 | 49 | } // namespace libscratchcpp 50 | -------------------------------------------------------------------------------- /src/audio/internal/audioplayerstub.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "audioplayerstub.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | AudioPlayerStub::AudioPlayerStub() 8 | { 9 | } 10 | 11 | bool AudioPlayerStub::load(unsigned int size, const void *data, unsigned long sampleRate) 12 | { 13 | return true; 14 | } 15 | 16 | bool AudioPlayerStub::loadCopy(IAudioPlayer *player) 17 | { 18 | return true; 19 | } 20 | 21 | float AudioPlayerStub::volume() const 22 | { 23 | return m_volume; 24 | } 25 | 26 | void AudioPlayerStub::setVolume(float volume) 27 | { 28 | m_volume = volume; 29 | } 30 | 31 | float AudioPlayerStub::pitch() const 32 | { 33 | return m_pitch; 34 | } 35 | 36 | void AudioPlayerStub::setPitch(float pitch) 37 | { 38 | m_pitch = pitch; 39 | } 40 | 41 | float AudioPlayerStub::pan() const 42 | { 43 | return m_pan; 44 | } 45 | 46 | void AudioPlayerStub::setPan(float pan) 47 | { 48 | m_pan = pan; 49 | } 50 | 51 | bool AudioPlayerStub::isLoaded() const 52 | { 53 | return true; 54 | } 55 | 56 | void AudioPlayerStub::start() 57 | { 58 | } 59 | 60 | void AudioPlayerStub::stop() 61 | { 62 | } 63 | 64 | bool AudioPlayerStub::isPlaying() const 65 | { 66 | return false; 67 | } 68 | -------------------------------------------------------------------------------- /src/audio/internal/audioplayerstub.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "../iaudioplayer.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class AudioPlayerStub : public IAudioPlayer 11 | { 12 | public: 13 | AudioPlayerStub(); 14 | 15 | bool load(unsigned int size, const void *data, unsigned long sampleRate) override; 16 | bool loadCopy(IAudioPlayer *player) override; 17 | 18 | float volume() const override; 19 | void setVolume(float volume) override; 20 | 21 | float pitch() const override; 22 | void setPitch(float pitch) override; 23 | 24 | float pan() const override; 25 | void setPan(float pan) override; 26 | 27 | bool isLoaded() const override; 28 | 29 | void start() override; 30 | void stop() override; 31 | 32 | bool isPlaying() const override; 33 | 34 | private: 35 | float m_volume = 1; 36 | float m_pitch = 1; 37 | float m_pan = 0; 38 | }; 39 | 40 | } // namespace libscratchcpp 41 | -------------------------------------------------------------------------------- /src/blocks/blocks.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class IExtension; 12 | 13 | class Blocks 14 | { 15 | public: 16 | static const std::vector> &extensions(); 17 | 18 | private: 19 | Blocks(); 20 | void registerExtensions(); 21 | 22 | static Blocks m_instance; // use static initialization 23 | std::vector> m_extensions; 24 | }; 25 | 26 | } // namespace libscratchcpp 27 | -------------------------------------------------------------------------------- /src/blocks/customblocks.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class CustomBlocks : public IExtension 11 | { 12 | public: 13 | std::string name() const override; 14 | std::string description() const override; 15 | Rgb color() const override; 16 | 17 | void registerBlocks(IEngine *engine) override; 18 | 19 | private: 20 | static CompilerValue *compileCall(Compiler *compiler); 21 | static CompilerValue *compileArgument(Compiler *compiler); 22 | }; 23 | 24 | } // namespace libscratchcpp 25 | -------------------------------------------------------------------------------- /src/blocks/sensingblocks.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "sensingblocks.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | std::string SensingBlocks::name() const 8 | { 9 | return "Sensing"; 10 | } 11 | 12 | std::string SensingBlocks::description() const 13 | { 14 | return name() + " blocks"; 15 | } 16 | 17 | Rgb SensingBlocks::color() const 18 | { 19 | return rgb(92, 177, 214); 20 | } 21 | 22 | void SensingBlocks::registerBlocks(IEngine *engine) 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /src/blocks/sensingblocks.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class SensingBlocks : public IExtension 11 | { 12 | public: 13 | std::string name() const override; 14 | std::string description() const override; 15 | Rgb color() const override; 16 | 17 | void registerBlocks(IEngine *engine) override; 18 | }; 19 | 20 | } // namespace libscratchcpp 21 | -------------------------------------------------------------------------------- /src/blocks/soundblocks.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IAudioOutput; 11 | 12 | class SoundBlocks : public IExtension 13 | { 14 | public: 15 | std::string name() const override; 16 | std::string description() const override; 17 | Rgb color() const override; 18 | 19 | void registerBlocks(IEngine *engine) override; 20 | void onInit(IEngine *engine) override; 21 | 22 | private: 23 | static CompilerValue *compilePlay(Compiler *compiler); 24 | static CompilerValue *compilePlayUntilDone(Compiler *compiler); 25 | static CompilerValue *compileStopAllSounds(Compiler *compiler); 26 | static CompilerValue *compileSetEffectTo(Compiler *compiler); 27 | static CompilerValue *compileChangeEffectBy(Compiler *compiler); 28 | static CompilerValue *compileClearEffects(Compiler *compiler); 29 | static CompilerValue *compileChangeVolumeBy(Compiler *compiler); 30 | static CompilerValue *compileSetVolumeTo(Compiler *compiler); 31 | static CompilerValue *compileVolume(Compiler *compiler); 32 | }; 33 | 34 | } // namespace libscratchcpp 35 | -------------------------------------------------------------------------------- /src/blocks/variableblocks.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class VariableBlocks : public IExtension 11 | { 12 | public: 13 | std::string name() const override; 14 | std::string description() const override; 15 | Rgb color() const override; 16 | 17 | void registerBlocks(IEngine *engine) override; 18 | 19 | private: 20 | static CompilerValue *compileVariable(Compiler *compiler); 21 | static CompilerValue *compileSetVariableTo(Compiler *compiler); 22 | static CompilerValue *compileChangeVariableBy(Compiler *compiler); 23 | 24 | static const std::string &variableMonitorName(Block *block); 25 | static void changeVariableMonitorValue(Block *block, const Value &newValue); 26 | }; 27 | 28 | } // namespace libscratchcpp 29 | -------------------------------------------------------------------------------- /src/engine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(scratchcpp 2 | PRIVATE 3 | compiler.cpp 4 | compiler_p.cpp 5 | compiler_p.h 6 | compilercontext.cpp 7 | compilercontext_p.cpp 8 | compilercontext_p.h 9 | compilervalue.cpp 10 | compilervalue_p.cpp 11 | compilervalue_p.h 12 | compilerconstant.cpp 13 | compilerconstant_p.cpp 14 | compilerconstant_p.h 15 | compilerlocalvariable.cpp 16 | compilerlocalvariable_p.cpp 17 | compilerlocalvariable_p.h 18 | executioncontext.cpp 19 | executioncontext_p.cpp 20 | executioncontext_p.h 21 | promise.cpp 22 | promise_p.cpp 23 | promise_p.h 24 | script.cpp 25 | script_p.cpp 26 | script_p.h 27 | thread.cpp 28 | thread_p.cpp 29 | thread_p.h 30 | internal/engine.cpp 31 | internal/engine.h 32 | internal/icodebuilder.h 33 | internal/icodebuilderfactory.h 34 | internal/codebuilderfactory.cpp 35 | internal/codebuilderfactory.h 36 | internal/clock.cpp 37 | internal/clock.h 38 | internal/iclock.h 39 | internal/timer.cpp 40 | internal/timer.h 41 | internal/stacktimer.cpp 42 | internal/stacktimer.h 43 | internal/randomgenerator.h 44 | internal/randomgenerator.cpp 45 | ) 46 | 47 | add_subdirectory(internal/llvm) 48 | -------------------------------------------------------------------------------- /src/engine/compilerconstant.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "compilerconstant_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs CompilerConstant. */ 10 | CompilerConstant::CompilerConstant(Compiler::StaticType type, const Value &value) : 11 | CompilerValue(type), 12 | impl(spimpl::make_unique_impl(value)) 13 | { 14 | } 15 | 16 | /*! Returns the constant value. */ 17 | const Value &CompilerConstant::value() const 18 | { 19 | return impl->value; 20 | } 21 | -------------------------------------------------------------------------------- /src/engine/compilerconstant_p.cpp: -------------------------------------------------------------------------------- 1 | #include "compilerconstant_p.h" 2 | 3 | using namespace libscratchcpp; 4 | 5 | CompilerConstantPrivate::CompilerConstantPrivate(const Value &value) : 6 | value(value) 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/engine/compilerconstant_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct CompilerConstantPrivate 11 | { 12 | CompilerConstantPrivate(const Value &value); 13 | 14 | Value value; 15 | }; 16 | 17 | } // namespace libscratchcpp 18 | -------------------------------------------------------------------------------- /src/engine/compilercontext.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "compilercontext_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs CompilerContext. */ 10 | CompilerContext::CompilerContext(IEngine *engine, Target *target) : 11 | impl(spimpl::make_unique_impl(engine, target)) 12 | { 13 | } 14 | 15 | /*! Returns the engine of the project. */ 16 | IEngine *CompilerContext::engine() const 17 | { 18 | return impl->engine; 19 | } 20 | 21 | /*! Returns the target of this context. */ 22 | Target *CompilerContext::target() const 23 | { 24 | return impl->target; 25 | } 26 | -------------------------------------------------------------------------------- /src/engine/compilercontext_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "compilercontext_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | CompilerContextPrivate::CompilerContextPrivate(IEngine *engine, Target *target) : 8 | engine(engine), 9 | target(target) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /src/engine/compilercontext_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | class IEngine; 9 | class Target; 10 | 11 | struct CompilerContextPrivate 12 | { 13 | CompilerContextPrivate(IEngine *engine, Target *target); 14 | 15 | IEngine *engine = nullptr; 16 | Target *target = nullptr; 17 | }; 18 | 19 | } // namespace libscratchcpp 20 | -------------------------------------------------------------------------------- /src/engine/compilerlocalvariable.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | #include 5 | 6 | #include "compilerlocalvariable_p.h" 7 | 8 | using namespace libscratchcpp; 9 | 10 | CompilerLocalVariable::CompilerLocalVariable(CompilerValue *ptr) : 11 | impl(spimpl::make_unique_impl(ptr)) 12 | { 13 | } 14 | 15 | CompilerValue *CompilerLocalVariable::ptr() const 16 | { 17 | return impl->ptr; 18 | } 19 | 20 | Compiler::StaticType CompilerLocalVariable::type() const 21 | { 22 | return impl->ptr->type(); 23 | } 24 | -------------------------------------------------------------------------------- /src/engine/compilerlocalvariable_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "compilerlocalvariable_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | CompilerLocalVariablePrivate::CompilerLocalVariablePrivate(CompilerValue *ptr) : 10 | ptr(ptr) 11 | { 12 | assert(ptr); 13 | } 14 | -------------------------------------------------------------------------------- /src/engine/compilerlocalvariable_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | class CompilerValue; 9 | 10 | struct CompilerLocalVariablePrivate 11 | { 12 | CompilerLocalVariablePrivate(CompilerValue *ptr); 13 | CompilerLocalVariablePrivate(CompilerLocalVariablePrivate &) = delete; 14 | 15 | CompilerValue *ptr = nullptr; 16 | }; 17 | 18 | } // namespace libscratchcpp 19 | -------------------------------------------------------------------------------- /src/engine/compilervalue.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "compilervalue_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs CompilerValue. */ 10 | CompilerValue::CompilerValue(Compiler::StaticType type) : 11 | impl(spimpl::make_unique_impl(type)) 12 | { 13 | } 14 | 15 | /*! Returns the type of this value. */ 16 | Compiler::StaticType CompilerValue::type() const 17 | { 18 | return impl->type; 19 | } 20 | 21 | /*! Sets the type of this value. */ 22 | void CompilerValue::setType(Compiler::StaticType type) 23 | { 24 | impl->type = type; 25 | } 26 | -------------------------------------------------------------------------------- /src/engine/compilervalue_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "compilervalue_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | CompilerValuePrivate::CompilerValuePrivate(Compiler::StaticType type) : 8 | type(type) 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /src/engine/compilervalue_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct CompilerValuePrivate 11 | { 12 | CompilerValuePrivate(Compiler::StaticType type); 13 | 14 | Compiler::StaticType type = Compiler::StaticType::Unknown; 15 | }; 16 | 17 | } // namespace libscratchcpp 18 | -------------------------------------------------------------------------------- /src/engine/executioncontext_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "executioncontext_p.h" 4 | #include "internal/randomgenerator.h" 5 | 6 | using namespace libscratchcpp; 7 | 8 | ExecutionContextPrivate::ExecutionContextPrivate(Thread *thread) : 9 | thread(thread), 10 | defaultStackTimer(std::make_unique()), 11 | stackTimer(defaultStackTimer.get()), 12 | rng(RandomGenerator::instance().get()) 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/engine/executioncontext_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "internal/stacktimer.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Thread; 13 | class Promise; 14 | class IRandomGenerator; 15 | 16 | struct ExecutionContextPrivate 17 | { 18 | ExecutionContextPrivate(Thread *thread); 19 | 20 | Thread *thread = nullptr; 21 | std::shared_ptr promise; 22 | std::unique_ptr defaultStackTimer; 23 | IStackTimer *stackTimer = nullptr; 24 | IRandomGenerator *rng = nullptr; 25 | }; 26 | 27 | } // namespace libscratchcpp 28 | -------------------------------------------------------------------------------- /src/engine/internal/clock.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "clock.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | std::shared_ptr Clock::m_instance = std::make_shared(); 10 | 11 | Clock::Clock() 12 | { 13 | } 14 | 15 | std::shared_ptr Clock::instance() 16 | { 17 | return m_instance; 18 | } 19 | 20 | std::chrono::steady_clock::time_point Clock::currentSteadyTime() const 21 | { 22 | return std::chrono::steady_clock::now(); 23 | } 24 | 25 | std::chrono::system_clock::time_point Clock::currentSystemTime() const 26 | { 27 | return std::chrono::system_clock::now(); 28 | } 29 | 30 | void Clock::sleep(const std::chrono::milliseconds &time) const 31 | { 32 | std::this_thread::sleep_for(time); 33 | } 34 | -------------------------------------------------------------------------------- /src/engine/internal/clock.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include "iclock.h" 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class Clock : public IClock 12 | { 13 | public: 14 | Clock(); 15 | Clock(const Clock &) = delete; 16 | 17 | static std::shared_ptr instance(); 18 | 19 | std::chrono::steady_clock::time_point currentSteadyTime() const override; 20 | std::chrono::system_clock::time_point currentSystemTime() const override; 21 | 22 | void sleep(const std::chrono::milliseconds &time) const override; 23 | 24 | private: 25 | static std::shared_ptr m_instance; 26 | }; 27 | 28 | } // namespace libscratchcpp 29 | -------------------------------------------------------------------------------- /src/engine/internal/codebuilderfactory.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "codebuilderfactory.h" 4 | #include "llvm/llvmcodebuilder.h" 5 | #include "llvm/llvmcompilercontext.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | std::shared_ptr CodeBuilderFactory::m_instance = std::make_shared(); 10 | 11 | std::shared_ptr CodeBuilderFactory::instance() 12 | { 13 | return m_instance; 14 | } 15 | 16 | std::shared_ptr CodeBuilderFactory::create(CompilerContext *ctx, BlockPrototype *procedurePrototype, Compiler::CodeType codeType) const 17 | { 18 | assert(dynamic_cast(ctx)); 19 | return std::make_shared(static_cast(ctx), procedurePrototype, codeType); 20 | } 21 | 22 | std::shared_ptr CodeBuilderFactory::createCtx(IEngine *engine, Target *target) const 23 | { 24 | auto ptr = std::make_shared(engine, target); 25 | return ptr; 26 | } 27 | -------------------------------------------------------------------------------- /src/engine/internal/codebuilderfactory.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "icodebuilderfactory.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class CodeBuilderFactory : public ICodeBuilderFactory 11 | { 12 | public: 13 | static std::shared_ptr instance(); 14 | std::shared_ptr create(CompilerContext *ctx, BlockPrototype *procedurePrototype, Compiler::CodeType codeType) const override; 15 | std::shared_ptr createCtx(IEngine *engine, Target *target) const override; 16 | 17 | private: 18 | static std::shared_ptr m_instance; 19 | }; 20 | 21 | } // namespace libscratchcpp 22 | -------------------------------------------------------------------------------- /src/engine/internal/iclock.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IClock 11 | { 12 | public: 13 | virtual ~IClock() { } 14 | 15 | virtual std::chrono::steady_clock::time_point currentSteadyTime() const = 0; 16 | virtual std::chrono::system_clock::time_point currentSystemTime() const = 0; 17 | 18 | virtual void sleep(const std::chrono::milliseconds &time) const = 0; 19 | }; 20 | 21 | } // namespace libscratchcpp 22 | -------------------------------------------------------------------------------- /src/engine/internal/icodebuilderfactory.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class ICodeBuilder; 12 | 13 | class ICodeBuilderFactory 14 | { 15 | public: 16 | virtual ~ICodeBuilderFactory() { } 17 | 18 | virtual std::shared_ptr create(CompilerContext *ctx, BlockPrototype *procedurePrototype = nullptr, Compiler::CodeType codeType = Compiler::CodeType::Script) const = 0; 19 | virtual std::shared_ptr createCtx(IEngine *engine, Target *target) const = 0; 20 | }; 21 | 22 | } // namespace libscratchcpp 23 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(scratchcpp 2 | PRIVATE 3 | llvmcodebuilder.cpp 4 | llvmcodebuilder.h 5 | llvmregister.h 6 | llvmconstantregister.h 7 | llvminstruction.h 8 | llvmifstatement.h 9 | llvmloop.h 10 | llvmcoroutine.cpp 11 | llvmcoroutine.h 12 | llvmvariableptr.h 13 | llvmlistptr.h 14 | llvmprocedure.h 15 | llvmtypes.cpp 16 | llvmtypes.h 17 | llvmfunctions.cpp 18 | llvmloopscope.h 19 | llvmcompilercontext.cpp 20 | llvmcompilercontext.h 21 | llvmexecutablecode.cpp 22 | llvmexecutablecode.h 23 | llvmexecutioncontext.cpp 24 | llvmexecutioncontext.h 25 | ) 26 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmconstantregister.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include "llvmregister.h" 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | struct LLVMConstantRegister 13 | : public CompilerConstant 14 | , public LLVMRegister 15 | { 16 | LLVMConstantRegister(Compiler::StaticType type, const Value &value) : 17 | CompilerValue(type), 18 | CompilerConstant(type, value), 19 | LLVMRegister(type) 20 | { 21 | } 22 | 23 | const Value &constValue() const override final { return CompilerConstant::value(); } 24 | }; 25 | 26 | } // namespace libscratchcpp 27 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmcoroutine.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class LLVMCoroutine 11 | { 12 | public: 13 | LLVMCoroutine(llvm::Module *module, llvm::IRBuilder<> *builder, llvm::Function *func); 14 | LLVMCoroutine(const LLVMCoroutine &) = delete; 15 | 16 | llvm::Value *handle() const; 17 | 18 | llvm::BasicBlock *suspendBlock() const; 19 | llvm::BasicBlock *cleanupBlock() const; 20 | llvm::BasicBlock *freeMemRetBlock() const; 21 | 22 | llvm::Value *didSuspendVar() const; 23 | 24 | void createSuspend(); 25 | llvm::Value *createResume(llvm::Function *function, llvm::Value *coroHandle); 26 | void end(); 27 | 28 | private: 29 | llvm::Module *m_module = nullptr; 30 | llvm::IRBuilder<> *m_builder = nullptr; 31 | llvm::Function *m_function = nullptr; 32 | llvm::Value *m_handle = nullptr; 33 | llvm::BasicBlock *m_suspendBlock = nullptr; 34 | llvm::BasicBlock *m_cleanupBlock = nullptr; 35 | llvm::BasicBlock *m_freeMemRetBlock = nullptr; 36 | llvm::Value *m_didSuspendVar = nullptr; 37 | }; 38 | 39 | } // namespace libscratchcpp 40 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmexecutioncontext.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "llvmexecutioncontext.h" 4 | #include "llvmcompilercontext.h" 5 | 6 | using namespace libscratchcpp; 7 | 8 | LLVMExecutionContext::LLVMExecutionContext(LLVMCompilerContext *compilerCtx, Thread *thread) : 9 | ExecutionContext(thread), 10 | m_compilerCtx(compilerCtx) 11 | { 12 | } 13 | 14 | LLVMExecutionContext::~LLVMExecutionContext() 15 | { 16 | if (m_coroutineHandle) { 17 | if (m_compilerCtx) { 18 | m_compilerCtx->destroyCoroutine(m_coroutineHandle); 19 | m_coroutineHandle = nullptr; 20 | } else 21 | assert(false); 22 | } 23 | } 24 | 25 | void *LLVMExecutionContext::coroutineHandle() const 26 | { 27 | return m_coroutineHandle; 28 | } 29 | 30 | void LLVMExecutionContext::setCoroutineHandle(void *newCoroutineHandle) 31 | { 32 | m_coroutineHandle = newCoroutineHandle; 33 | } 34 | 35 | bool LLVMExecutionContext::finished() const 36 | { 37 | return m_finished; 38 | } 39 | 40 | void LLVMExecutionContext::setFinished(bool newFinished) 41 | { 42 | m_finished = newFinished; 43 | } 44 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmexecutioncontext.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class LLVMCompilerContext; 11 | 12 | class LLVMExecutionContext : public ExecutionContext 13 | { 14 | public: 15 | LLVMExecutionContext(LLVMCompilerContext *compilerCtx, Thread *thread); 16 | ~LLVMExecutionContext(); 17 | 18 | void *coroutineHandle() const; 19 | void setCoroutineHandle(void *newCoroutineHandle); 20 | 21 | bool finished() const; 22 | void setFinished(bool newFinished); 23 | 24 | private: 25 | LLVMCompilerContext *m_compilerCtx = nullptr; 26 | void *m_coroutineHandle = nullptr; 27 | bool m_finished = false; 28 | }; 29 | 30 | } // namespace libscratchcpp 31 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmfunctions.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | extern "C" 11 | { 12 | double llvm_random(ExecutionContext *ctx, ValueData *from, ValueData *to) 13 | { 14 | return value_isInt(from) && value_isInt(to) ? ctx->rng()->randint(value_toLong(from), value_toLong(to)) : ctx->rng()->randintDouble(value_toDouble(from), value_toDouble(to)); 15 | } 16 | 17 | double llvm_random_double(ExecutionContext *ctx, double from, double to) 18 | { 19 | return value_doubleIsInt(from) && value_doubleIsInt(to) ? ctx->rng()->randint(from, to) : ctx->rng()->randintDouble(from, to); 20 | } 21 | 22 | double llvm_random_long(ExecutionContext *ctx, long from, long to) 23 | { 24 | return ctx->rng()->randint(from, to); 25 | } 26 | 27 | double llvm_random_bool(ExecutionContext *ctx, bool from, bool to) 28 | { 29 | return ctx->rng()->randint(from, to); 30 | } 31 | } 32 | 33 | } // namespace libscratchcpp 34 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmifstatement.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace llvm 6 | { 7 | 8 | class Value; 9 | class BasicBlock; 10 | 11 | } // namespace llvm 12 | 13 | namespace libscratchcpp 14 | { 15 | 16 | struct LLVMIfStatement 17 | { 18 | llvm::Value *condition = nullptr; 19 | llvm::BasicBlock *beforeIf = nullptr; 20 | llvm::BasicBlock *body = nullptr; 21 | llvm::BasicBlock *elseBranch = nullptr; 22 | llvm::BasicBlock *afterIf = nullptr; 23 | }; 24 | 25 | } // namespace libscratchcpp 26 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmlistptr.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace llvm 9 | { 10 | 11 | class Value; 12 | 13 | } 14 | 15 | namespace libscratchcpp 16 | { 17 | 18 | class LLVMLoopScope; 19 | class LLVMInstruction; 20 | 21 | struct LLVMListPtr 22 | { 23 | llvm::Value *ptr = nullptr; 24 | llvm::Value *dataPtr = nullptr; 25 | llvm::Value *sizePtr = nullptr; 26 | llvm::Value *allocatedSizePtr = nullptr; 27 | llvm::Value *dataPtrDirty = nullptr; 28 | Compiler::StaticType type = Compiler::StaticType::Unknown; 29 | 30 | // Used in build phase to check the type safety of lists in loops 31 | std::unordered_map>> loopListWrites; // loop scope, write instructions 32 | }; 33 | 34 | } // namespace libscratchcpp 35 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmloop.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace llvm 6 | { 7 | 8 | class Value; 9 | class BasicBlock; 10 | 11 | } // namespace llvm 12 | 13 | namespace libscratchcpp 14 | { 15 | 16 | struct LLVMLoop 17 | { 18 | bool isRepeatLoop = false; 19 | llvm::Value *index = nullptr; 20 | llvm::BasicBlock *conditionBranch = nullptr; 21 | llvm::BasicBlock *afterLoop = nullptr; 22 | }; 23 | 24 | } // namespace libscratchcpp 25 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmloopscope.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | struct LLVMLoopScope 12 | { 13 | bool containsYield = false; 14 | LLVMLoopScope *parentScope = nullptr; 15 | std::vector childScopes; 16 | }; 17 | 18 | } // namespace libscratchcpp 19 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmprocedure.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | struct LLVMProcedure 9 | { 10 | // TODO: Implement procedures 11 | bool warp = false; 12 | }; 13 | 14 | } // namespace libscratchcpp 15 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmregister.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace llvm 9 | { 10 | 11 | class Value; 12 | 13 | } 14 | 15 | namespace libscratchcpp 16 | { 17 | 18 | class LLVMInstruction; 19 | 20 | struct LLVMRegister : public virtual CompilerValue 21 | { 22 | LLVMRegister(Compiler::StaticType type) : 23 | CompilerValue(type) 24 | { 25 | } 26 | 27 | virtual const Value &constValue() const 28 | { 29 | static const Value null = Value(); 30 | return null; 31 | } 32 | 33 | llvm::Value *value = nullptr; 34 | bool isRawValue = false; 35 | std::shared_ptr instruction; 36 | }; 37 | 38 | } // namespace libscratchcpp 39 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmtypes.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "llvmtypes.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | llvm::StructType *LLVMTypes::createValueDataType(llvm::IRBuilder<> *builder) 10 | { 11 | llvm::LLVMContext &ctx = builder->getContext(); 12 | 13 | // Create the ValueData struct 14 | llvm::Type *unionType = builder->getInt64Ty(); // 64 bits is the largest size 15 | 16 | llvm::Type *valueType = llvm::Type::getInt32Ty(ctx); // Assuming ValueType is a 32-bit enum 17 | llvm::Type *padding = llvm::Type::getInt32Ty(ctx); // Padding for alignment 18 | 19 | llvm::StructType *ret = llvm::StructType::create(ctx, "ValueData"); 20 | ret->setBody({ unionType, valueType, padding }); 21 | 22 | return ret; 23 | } 24 | 25 | llvm::StructType *LLVMTypes::createStringPtrType(llvm::IRBuilder<> *builder) 26 | { 27 | llvm::LLVMContext &ctx = builder->getContext(); 28 | 29 | // Create the StringPtr struct 30 | llvm::PointerType *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(ctx), 0); 31 | llvm::Type *sizeType = llvm::Type::getInt64Ty(ctx); 32 | llvm::StructType *ret = llvm::StructType::create(ctx, "StringPtr"); 33 | ret->setBody({ pointerType, sizeType, sizeType }); 34 | 35 | return ret; 36 | } 37 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmtypes.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace llvm 8 | { 9 | 10 | class StructValue; 11 | 12 | } 13 | 14 | namespace libscratchcpp 15 | { 16 | 17 | class LLVMTypes 18 | { 19 | public: 20 | static llvm::StructType *createValueDataType(llvm::IRBuilder<> *builder); 21 | static llvm::StructType *createStringPtrType(llvm::IRBuilder<> *builder); 22 | }; 23 | 24 | } // namespace libscratchcpp 25 | -------------------------------------------------------------------------------- /src/engine/internal/llvm/llvmvariableptr.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace llvm 9 | { 10 | 11 | class Value; 12 | 13 | } 14 | 15 | namespace libscratchcpp 16 | { 17 | 18 | class LLVMLoopScope; 19 | class LLVMInstruction; 20 | 21 | struct LLVMVariablePtr 22 | { 23 | llvm::Value *stackPtr = nullptr; 24 | llvm::Value *heapPtr = nullptr; 25 | Compiler::StaticType type = Compiler::StaticType::Unknown; 26 | bool onStack = false; 27 | bool changed = false; 28 | 29 | // Used in build phase to check the type safety of variables in loops 30 | std::unordered_map>> loopVariableWrites; // loop scope, write instructions 31 | }; 32 | 33 | } // namespace libscratchcpp 34 | -------------------------------------------------------------------------------- /src/engine/internal/randomgenerator.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class RandomGenerator : public IRandomGenerator 13 | { 14 | public: 15 | RandomGenerator(); 16 | RandomGenerator(const RandomGenerator &) = delete; 17 | 18 | static std::shared_ptr instance(); 19 | 20 | long randint(long start, long end) const override; 21 | double randintDouble(double start, double end) const override; 22 | long randintExcept(long start, long end, long except) const override; 23 | 24 | private: 25 | static std::shared_ptr m_instance; 26 | std::random_device m_device; 27 | std::unique_ptr m_generator; 28 | }; 29 | 30 | } // namespace libscratchcpp 31 | -------------------------------------------------------------------------------- /src/engine/internal/stacktimer.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | #include 5 | 6 | #include "stacktimer.h" 7 | #include "clock.h" 8 | 9 | using namespace libscratchcpp; 10 | 11 | StackTimer::StackTimer() 12 | { 13 | m_clock = Clock::instance().get(); 14 | } 15 | 16 | StackTimer::StackTimer(IClock *clock) : 17 | m_clock(clock) 18 | { 19 | assert(clock); 20 | } 21 | 22 | void StackTimer::start(double seconds) 23 | { 24 | m_startTime = m_clock->currentSteadyTime(); 25 | m_timeLimit = seconds * 1000; 26 | m_stopped = false; 27 | } 28 | 29 | void StackTimer::stop() 30 | { 31 | m_stopped = true; 32 | } 33 | 34 | bool StackTimer::stopped() const 35 | { 36 | return m_stopped; 37 | } 38 | 39 | bool StackTimer::elapsed() const 40 | { 41 | if (m_stopped) 42 | return false; 43 | 44 | return std::chrono::duration_cast(m_clock->currentSteadyTime() - m_startTime).count() >= m_timeLimit; 45 | } 46 | 47 | double StackTimer::elapsedTime() const 48 | { 49 | if (m_stopped) 50 | return 0; 51 | 52 | return std::chrono::duration_cast(m_clock->currentSteadyTime() - m_startTime).count() / 1000.0; 53 | } 54 | -------------------------------------------------------------------------------- /src/engine/internal/stacktimer.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class IClock; 12 | 13 | class StackTimer : public IStackTimer 14 | { 15 | public: 16 | StackTimer(); 17 | StackTimer(IClock *clock); 18 | StackTimer(const StackTimer &) = delete; 19 | 20 | void start(double seconds) override; 21 | void stop() override; 22 | 23 | bool stopped() const override; 24 | bool elapsed() const override; 25 | double elapsedTime() const override; 26 | 27 | private: 28 | std::chrono::steady_clock::time_point m_startTime; 29 | bool m_stopped = true; 30 | long m_timeLimit = 0; 31 | IClock *m_clock = nullptr; 32 | }; 33 | 34 | } // namespace libscratchcpp 35 | -------------------------------------------------------------------------------- /src/engine/internal/timer.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "timer.h" 6 | #include "clock.h" 7 | 8 | using namespace libscratchcpp; 9 | 10 | Timer::Timer() 11 | { 12 | m_clock = Clock::instance().get(); 13 | resetTimer(); 14 | } 15 | 16 | Timer::Timer(IClock *clock) : 17 | m_clock(clock) 18 | { 19 | assert(clock); 20 | resetTimer(); 21 | } 22 | 23 | double Timer::value() const 24 | { 25 | return std::chrono::duration_cast(m_clock->currentSteadyTime() - m_startTime).count() / 1000.0; 26 | } 27 | 28 | void Timer::reset() 29 | { 30 | resetTimer(); 31 | } 32 | 33 | // Required to avoid calling the virtual method from the constructors 34 | void Timer::resetTimer() 35 | { 36 | m_startTime = m_clock->currentSteadyTime(); 37 | } 38 | -------------------------------------------------------------------------------- /src/engine/internal/timer.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class IClock; 12 | 13 | class Timer : public ITimer 14 | { 15 | public: 16 | Timer(); 17 | Timer(IClock *clock); 18 | Timer(const Timer &) = delete; 19 | 20 | double value() const override; 21 | void reset() override; 22 | 23 | private: 24 | void resetTimer(); 25 | 26 | std::chrono::steady_clock::time_point m_startTime; 27 | IClock *m_clock = nullptr; 28 | }; 29 | 30 | } // namespace libscratchcpp 31 | -------------------------------------------------------------------------------- /src/engine/promise.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "promise_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs Promise. */ 10 | Promise::Promise() : 11 | impl(spimpl::make_unique_impl()) 12 | { 13 | } 14 | 15 | /*! Returns true if the promise is resolved. */ 16 | bool Promise::isResolved() const 17 | { 18 | return impl->isResolved; 19 | } 20 | 21 | /*! Marks the promise as resolved. */ 22 | void Promise::resolve() 23 | { 24 | impl->isResolved = true; 25 | } 26 | -------------------------------------------------------------------------------- /src/engine/promise_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "promise_p.h" 4 | 5 | using namespace libscratchcpp; 6 | -------------------------------------------------------------------------------- /src/engine/promise_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | struct PromisePrivate 9 | { 10 | bool isResolved = false; 11 | }; 12 | 13 | } // namespace libscratchcpp 14 | -------------------------------------------------------------------------------- /src/engine/script_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "script_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | ScriptPrivate::ScriptPrivate(Target *target, Block *topBlock, IEngine *engine) : 8 | target(target), 9 | topBlock(topBlock), 10 | engine(engine) 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/engine/script_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Target; 13 | class Block; 14 | class IEngine; 15 | class ExecutableCode; 16 | class Variable; 17 | class List; 18 | 19 | struct ScriptPrivate 20 | { 21 | ScriptPrivate(Target *target, Block *topBlock, IEngine *engine); 22 | ScriptPrivate(const ScriptPrivate &) = delete; 23 | 24 | std::shared_ptr code; 25 | std::shared_ptr hatPredicateCode; 26 | 27 | Target *target = nullptr; 28 | Block *topBlock = nullptr; 29 | IEngine *engine = nullptr; 30 | }; 31 | 32 | } // namespace libscratchcpp 33 | -------------------------------------------------------------------------------- /src/engine/thread_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "thread_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | ThreadPrivate::ThreadPrivate(Target *target, IEngine *engine, Script *script) : 8 | target(target), 9 | engine(engine), 10 | script(script) 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/engine/thread_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class Target; 11 | class IEngine; 12 | class Script; 13 | class ExecutableCode; 14 | class ExecutionContext; 15 | 16 | struct ThreadPrivate 17 | { 18 | ThreadPrivate(Target *target, IEngine *engine, Script *script); 19 | 20 | Target *target = nullptr; 21 | IEngine *engine = nullptr; 22 | Script *script = nullptr; 23 | ExecutableCode *code = nullptr; 24 | ExecutableCode *hatPredicateCode = nullptr; 25 | std::shared_ptr executionContext; 26 | std::shared_ptr hatPredicateExecutionContext; 27 | }; 28 | 29 | } // namespace libscratchcpp 30 | -------------------------------------------------------------------------------- /src/internal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(scratchcpp 2 | PRIVATE 3 | iprojectreader.h 4 | scratch3reader.cpp 5 | scratch3reader.h 6 | reader_common.h 7 | zipreader.cpp 8 | zipreader.h 9 | projecturl.cpp 10 | projecturl.h 11 | idownloader.h 12 | idownloaderfactory.h 13 | iprojectdownloader.h 14 | iprojectdownloaderfactory.h 15 | projectdownloaderfactory.cpp 16 | projectdownloaderfactory.h 17 | ) 18 | 19 | if (LIBSCRATCHCPP_NETWORK_SUPPORT) 20 | target_sources(scratchcpp 21 | PRIVATE 22 | downloader.cpp 23 | downloader.h 24 | downloaderfactory.cpp 25 | downloaderfactory.h 26 | projectdownloader.cpp 27 | projectdownloader.h 28 | ) 29 | else() 30 | target_sources(scratchcpp 31 | PRIVATE 32 | projectdownloaderstub.cpp 33 | projectdownloaderstub.h 34 | ) 35 | endif() 36 | -------------------------------------------------------------------------------- /src/internal/downloader.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "downloader.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | Downloader::Downloader() 10 | { 11 | m_session.SetTimeout(cpr::Timeout(5000)); 12 | } 13 | 14 | bool Downloader::download(const std::string &url) 15 | { 16 | m_session.SetUrl(cpr::Url(url)); 17 | m_response = m_session.Get(); 18 | 19 | if (m_response.status_code != 200) { 20 | std::cerr << "download error: " << m_response.error.message << std::endl; 21 | 22 | if (m_response.status_code != 0) 23 | std::cerr << "code: " << m_response.status_code << std::endl; 24 | 25 | std::cerr << "URL: " << url << std::endl; 26 | return false; 27 | } 28 | 29 | return true; 30 | } 31 | 32 | const std::string &Downloader::text() const 33 | { 34 | return m_response.text; 35 | } 36 | -------------------------------------------------------------------------------- /src/internal/downloader.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | #include "idownloader.h" 9 | 10 | namespace libscratchcpp 11 | { 12 | 13 | class Downloader : public IDownloader 14 | { 15 | public: 16 | Downloader(); 17 | 18 | bool download(const std::string &url) override; 19 | const std::string &text() const override; 20 | 21 | private: 22 | cpr::Session m_session; 23 | cpr::Response m_response; 24 | }; 25 | 26 | } // namespace libscratchcpp 27 | -------------------------------------------------------------------------------- /src/internal/downloaderfactory.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "downloaderfactory.h" 4 | #include "downloader.h" 5 | 6 | using namespace libscratchcpp; 7 | 8 | std::shared_ptr DownloaderFactory::m_instance = std::make_shared(); 9 | 10 | DownloaderFactory::DownloaderFactory() 11 | { 12 | } 13 | 14 | std::shared_ptr DownloaderFactory::instance() 15 | { 16 | return m_instance; 17 | } 18 | 19 | std::shared_ptr DownloaderFactory::create() const 20 | { 21 | return std::make_shared(); 22 | } 23 | -------------------------------------------------------------------------------- /src/internal/downloaderfactory.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "idownloaderfactory.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class DownloaderFactory : public IDownloaderFactory 11 | { 12 | public: 13 | DownloaderFactory(); 14 | 15 | static std::shared_ptr instance(); 16 | std::shared_ptr create() const override; 17 | 18 | private: 19 | static std::shared_ptr m_instance; 20 | }; 21 | 22 | } // namespace libscratchcpp 23 | -------------------------------------------------------------------------------- /src/internal/idownloader.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IDownloader 11 | { 12 | public: 13 | virtual ~IDownloader() { } 14 | 15 | virtual bool download(const std::string &url) = 0; 16 | virtual const std::string &text() const = 0; 17 | }; 18 | 19 | } // namespace libscratchcpp 20 | -------------------------------------------------------------------------------- /src/internal/idownloaderfactory.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IDownloader; 11 | 12 | class IDownloaderFactory 13 | { 14 | public: 15 | virtual ~IDownloaderFactory() { } 16 | 17 | virtual std::shared_ptr create() const = 0; 18 | }; 19 | 20 | } // namespace libscratchcpp 21 | -------------------------------------------------------------------------------- /src/internal/iprojectdownloader.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace libscratchcpp 11 | { 12 | 13 | class IProjectDownloader 14 | { 15 | public: 16 | virtual ~IProjectDownloader() { } 17 | 18 | virtual bool downloadJson(const std::string &projectId) = 0; 19 | virtual bool downloadAssets(const std::vector &assetIds) = 0; 20 | virtual void cancel() = 0; 21 | 22 | virtual sigslot::signal &downloadProgressChanged() = 0; 23 | 24 | virtual const std::string &json() const = 0; 25 | virtual const std::vector &assets() const = 0; 26 | virtual unsigned int downloadedAssetCount() const = 0; 27 | }; 28 | 29 | } // namespace libscratchcpp 30 | -------------------------------------------------------------------------------- /src/internal/iprojectdownloaderfactory.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IProjectDownloader; 11 | 12 | class IProjectDownloaderFactory 13 | { 14 | public: 15 | virtual ~IProjectDownloaderFactory() { } 16 | 17 | virtual std::shared_ptr create() const = 0; 18 | }; 19 | 20 | } // namespace libscratchcpp 21 | -------------------------------------------------------------------------------- /src/internal/projectdownloaderfactory.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "projectdownloaderfactory.h" 4 | #ifdef LIBSCRATCHCPP_NETWORK_SUPPORT 5 | #include "projectdownloader.h" 6 | #else 7 | #include "projectdownloaderstub.h" 8 | #endif 9 | 10 | using namespace libscratchcpp; 11 | 12 | std::shared_ptr ProjectDownloaderFactory::m_instance = std::make_shared(); 13 | 14 | ProjectDownloaderFactory::ProjectDownloaderFactory() 15 | { 16 | } 17 | 18 | std::shared_ptr ProjectDownloaderFactory::instance() 19 | { 20 | return m_instance; 21 | } 22 | 23 | std::shared_ptr ProjectDownloaderFactory::create() const 24 | { 25 | #ifdef LIBSCRATCHCPP_NETWORK_SUPPORT 26 | return std::make_shared(); 27 | #else 28 | return std::make_shared(); 29 | #endif 30 | } 31 | -------------------------------------------------------------------------------- /src/internal/projectdownloaderfactory.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "iprojectdownloaderfactory.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class ProjectDownloaderFactory : public IProjectDownloaderFactory 11 | { 12 | public: 13 | ProjectDownloaderFactory(); 14 | 15 | static std::shared_ptr instance(); 16 | std::shared_ptr create() const override; 17 | 18 | private: 19 | static std::shared_ptr m_instance; 20 | }; 21 | 22 | } // namespace libscratchcpp 23 | -------------------------------------------------------------------------------- /src/internal/projectdownloaderstub.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "projectdownloaderstub.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | ProjectDownloaderStub::ProjectDownloaderStub() 8 | { 9 | } 10 | 11 | bool ProjectDownloaderStub::downloadJson(const std::string &) 12 | { 13 | return false; 14 | } 15 | 16 | bool ProjectDownloaderStub::downloadAssets(const std::vector &) 17 | { 18 | return false; 19 | } 20 | 21 | void ProjectDownloaderStub::cancel() 22 | { 23 | } 24 | 25 | sigslot::signal &ProjectDownloaderStub::downloadProgressChanged() 26 | { 27 | return m_downloadProgressChanged; 28 | } 29 | 30 | const std::string &ProjectDownloaderStub::json() const 31 | { 32 | static const std::string empty; 33 | return empty; 34 | } 35 | 36 | const std::vector &ProjectDownloaderStub::assets() const 37 | { 38 | static const std::vector empty; 39 | return empty; 40 | } 41 | 42 | unsigned int ProjectDownloaderStub::downloadedAssetCount() const 43 | { 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/internal/projectdownloaderstub.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "iprojectdownloader.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class ProjectDownloaderStub : public IProjectDownloader 11 | { 12 | public: 13 | ProjectDownloaderStub(); 14 | 15 | bool downloadJson(const std::string &) override; 16 | bool downloadAssets(const std::vector &) override; 17 | void cancel() override; 18 | 19 | sigslot::signal &downloadProgressChanged() override; 20 | 21 | const std::string &json() const override; 22 | const std::vector &assets() const override; 23 | unsigned int downloadedAssetCount() const override; 24 | 25 | private: 26 | sigslot::signal m_downloadProgressChanged; 27 | }; 28 | 29 | } // namespace libscratchcpp 30 | -------------------------------------------------------------------------------- /src/internal/projecturl.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class ProjectUrl 11 | { 12 | public: 13 | ProjectUrl(const std::string &url); 14 | 15 | bool isProjectUrl() const; 16 | const std::string &projectId() const; 17 | 18 | private: 19 | bool m_isProjectUrl = false; 20 | std::string m_projectId; 21 | }; 22 | 23 | } // namespace libscratchcpp 24 | -------------------------------------------------------------------------------- /src/internal/reader_common.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | Value jsonToValue(nlohmann::json value) 13 | { 14 | if (value.is_string()) 15 | return value.get(); 16 | else if (value.is_boolean()) 17 | return value.get(); 18 | else if (value.is_number_integer() || value.is_number_unsigned()) 19 | return value.get(); 20 | else if (value.is_number_float()) 21 | return value.get(); 22 | else { 23 | assert(!value.is_number()); 24 | return value.dump(); 25 | } 26 | } 27 | 28 | } // namespace libscratchcpp 29 | -------------------------------------------------------------------------------- /src/internal/scratch3reader.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include "iprojectreader.h" 6 | #include 7 | 8 | #include "zipreader.h" 9 | 10 | namespace libscratchcpp 11 | { 12 | 13 | class Scratch3Reader : public IProjectReader 14 | { 15 | public: 16 | bool load() override; 17 | bool loadData(const std::string &data) override; 18 | bool isValid() override; 19 | void clear() override; 20 | const std::vector> &targets() const override; 21 | const std::vector> &broadcasts() const override; 22 | const std::vector> &monitors() const override; 23 | const std::vector &extensions() const override; 24 | const std::string &userAgent() const override; 25 | 26 | private: 27 | void read(); 28 | std::unique_ptr m_zipReader; 29 | nlohmann::json m_json = ""; 30 | std::vector> m_targets; 31 | std::vector> m_broadcasts; 32 | std::vector> m_monitors; 33 | std::vector m_extensions; 34 | std::string m_userAgent; 35 | }; 36 | 37 | } // namespace libscratchcpp 38 | -------------------------------------------------------------------------------- /src/internal/zipreader.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "zipreader.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | ZipReader::ZipReader(const std::string &fileName) : 8 | m_fileName(fileName) 9 | { 10 | } 11 | 12 | ZipReader::ZipReader(const char *fileName) : 13 | ZipReader(std::string(fileName)) 14 | { 15 | } 16 | 17 | ZipReader::~ZipReader() 18 | { 19 | close(); 20 | } 21 | 22 | bool ZipReader::open() 23 | { 24 | m_zip = zip_open(m_fileName.c_str(), 0, 'r'); 25 | return m_zip; 26 | } 27 | 28 | void ZipReader::close() 29 | { 30 | if (m_zip) 31 | zip_close(m_zip); 32 | 33 | m_zip = nullptr; 34 | } 35 | 36 | size_t ZipReader::readFile(const std::string &fileName, void **buf) 37 | { 38 | if (!m_zip) { 39 | *buf = nullptr; 40 | return 0; 41 | } 42 | 43 | size_t bufsize = 0; 44 | zip_entry_open(m_zip, fileName.c_str()); 45 | zip_entry_read(m_zip, buf, &bufsize); 46 | zip_entry_close(m_zip); 47 | 48 | return bufsize; 49 | } 50 | 51 | void ZipReader::readFileToString(const std::string &fileName, std::string &dst) 52 | { 53 | void *buf = nullptr; 54 | size_t bufsize = readFile(fileName, &buf); 55 | 56 | if (buf) { 57 | dst.assign(reinterpret_cast(buf), bufsize); 58 | free(buf); 59 | } else 60 | dst = ""; 61 | } 62 | -------------------------------------------------------------------------------- /src/internal/zipreader.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class ZipReader 12 | { 13 | public: 14 | ZipReader(const std::string &fileName); 15 | ZipReader(const char *fileName); 16 | ZipReader(const ZipReader &) = delete; 17 | ~ZipReader(); 18 | 19 | bool open(); 20 | void close(); 21 | 22 | size_t readFile(const std::string &fileName, void **buf); 23 | void readFileToString(const std::string &fileName, std::string &dst); 24 | 25 | private: 26 | std::string m_fileName; 27 | struct zip_t *m_zip = nullptr; 28 | }; 29 | 30 | } // namespace libscratchcpp 31 | -------------------------------------------------------------------------------- /src/project_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class IEngine; 12 | class IProjectReader; 13 | class IProjectDownloaderFactory; 14 | class IProjectDownloader; 15 | 16 | struct ProjectPrivate 17 | { 18 | ProjectPrivate(); 19 | ProjectPrivate(const std::string &fileName); 20 | ProjectPrivate(const ProjectPrivate &) = delete; 21 | 22 | bool load(); 23 | bool tryLoad(IProjectReader *reader); 24 | void loadingAborted(); 25 | 26 | void start(); 27 | void run(); 28 | void runEventLoop(); 29 | 30 | sigslot::signal &downloadProgressChanged(); 31 | 32 | std::string fileName; 33 | std::atomic stopLoading = false; 34 | std::shared_ptr engine = nullptr; 35 | 36 | static IProjectDownloaderFactory *downloaderFactory; 37 | std::shared_ptr downloader; 38 | }; 39 | 40 | }; // namespace libscratchcpp 41 | -------------------------------------------------------------------------------- /src/rect_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "rect_p.h" 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | RectPrivate::RectPrivate(double left, double top, double right, double bottom) : 9 | left(left), 10 | top(top), 11 | right(right), 12 | bottom(bottom) 13 | { 14 | } 15 | 16 | RectPrivate::RectPrivate() 17 | { 18 | } 19 | 20 | } // namespace libscratchcpp 21 | -------------------------------------------------------------------------------- /src/rect_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | struct RectPrivate 9 | { 10 | RectPrivate(double left, double top, double right, double bottom); 11 | RectPrivate(); 12 | 13 | double left = 0; 14 | double top = 0; 15 | double right = 0; 16 | double bottom = 0; 17 | }; 18 | 19 | } // namespace libscratchcpp 20 | -------------------------------------------------------------------------------- /src/scratch/asset_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "asset_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | AssetPrivate::AssetPrivate(const std::string &name, const std::string &format) : 8 | name(name), 9 | dataFormat(format) 10 | { 11 | } 12 | 13 | void AssetPrivate::updateFileName(const std::string &id) 14 | { 15 | // NOTE: fileName depends on id and dataFormat 16 | fileName = id + "." + dataFormat; 17 | } 18 | -------------------------------------------------------------------------------- /src/scratch/asset_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class Target; 11 | 12 | struct AssetPrivate 13 | { 14 | AssetPrivate(const std::string &name, const std::string &format); 15 | AssetPrivate(const AssetPrivate &) = delete; 16 | 17 | void updateFileName(const std::string &id); 18 | 19 | std::string name; 20 | std::string dataFormat; 21 | std::string fileName; 22 | void *data = nullptr; 23 | unsigned int dataSize = 0; 24 | bool dataCloned = false; 25 | Target *target = nullptr; 26 | }; 27 | 28 | } // namespace libscratchcpp 29 | -------------------------------------------------------------------------------- /src/scratch/block_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "block_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | BlockPrivate::BlockPrivate(const std::string &opcode, bool isMonitorBlock) : 8 | opcode(opcode), 9 | isMonitorBlock(isMonitorBlock) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /src/scratch/blockprototype_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "blockprototype_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | BlockPrototypePrivate::BlockPrototypePrivate() 8 | { 9 | } 10 | 11 | BlockPrototypePrivate::BlockPrototypePrivate(const std::string &procCode) 12 | { 13 | setProcCode(procCode); 14 | } 15 | 16 | void BlockPrototypePrivate::setProcCode(const std::string &newProcCode) 17 | { 18 | procCode = newProcCode; 19 | argumentDefaults.clear(); 20 | argumentTypes.clear(); 21 | bool arg = false; 22 | 23 | for (auto c : procCode) { 24 | if (c == '%') 25 | arg = true; 26 | else if (arg) { 27 | arg = false; 28 | switch (c) { 29 | case 's': 30 | case 'n': 31 | argumentDefaults.push_back(""); 32 | argumentTypes.push_back(BlockPrototype::ArgType::StringNum); 33 | break; 34 | 35 | case 'b': 36 | argumentDefaults.push_back(false); 37 | argumentTypes.push_back(BlockPrototype::ArgType::Bool); 38 | break; 39 | 40 | default: 41 | break; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/scratch/blockprototype_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct BlockPrototypePrivate 11 | { 12 | BlockPrototypePrivate(); 13 | BlockPrototypePrivate(const std::string &procCode); 14 | 15 | void setProcCode(const std::string &newProcCode); 16 | 17 | std::string procCode; 18 | std::vector argumentIds; 19 | std::vector argumentNames; 20 | std::vector argumentDefaults; 21 | std::vector argumentTypes; 22 | bool warp = false; 23 | }; 24 | 25 | } // namespace libscratchcpp 26 | -------------------------------------------------------------------------------- /src/scratch/broadcast.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "broadcast_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs Broadcast. */ 10 | Broadcast::Broadcast(const std::string &id, const std::string &name, bool isBackdropBroadcast) : 11 | Entity(id), 12 | impl(spimpl::make_unique_impl(name, isBackdropBroadcast)) 13 | { 14 | } 15 | 16 | /*! Returns the name of the broadcast. */ 17 | const std::string &Broadcast::name() const 18 | { 19 | return impl->name; 20 | } 21 | 22 | /*! Sets the name of the broadcast. */ 23 | void Broadcast::setName(const std::string &newName) 24 | { 25 | impl->name = newName; 26 | } 27 | 28 | /*! Returns true if this broadcast belongs to a backdrop. */ 29 | bool Broadcast::isBackdropBroadcast() const 30 | { 31 | return impl->isBackdropBroadcast; 32 | } 33 | -------------------------------------------------------------------------------- /src/scratch/broadcast_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "broadcast_p.h" 4 | 5 | namespace libscratchcpp 6 | { 7 | 8 | BroadcastPrivate::BroadcastPrivate(const std::string &name, bool isBackdropBroadcast) : 9 | name(name), 10 | isBackdropBroadcast(isBackdropBroadcast) 11 | { 12 | } 13 | 14 | } // namespace libscratchcpp 15 | -------------------------------------------------------------------------------- /src/scratch/broadcast_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct BroadcastPrivate 11 | { 12 | BroadcastPrivate(const std::string &name, bool isBackdropBroadcast); 13 | BroadcastPrivate(const BroadcastPrivate &) = delete; 14 | 15 | std::string name; 16 | bool isBackdropBroadcast = false; 17 | }; 18 | 19 | } // namespace libscratchcpp 20 | -------------------------------------------------------------------------------- /src/scratch/comment_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "comment_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | CommentPrivate::CommentPrivate(double x, double y) : 8 | x(x), 9 | y(y) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /src/scratch/comment_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class Block; 12 | 13 | struct CommentPrivate 14 | { 15 | CommentPrivate(double x, double y); 16 | CommentPrivate(const CommentPrivate &) = delete; 17 | 18 | std::string blockId; 19 | Block *block = nullptr; 20 | double x = 0; 21 | double y = 0; 22 | double width = 200; 23 | double height = 200; 24 | bool minimized = false; 25 | std::string text; 26 | }; 27 | 28 | } // namespace libscratchcpp 29 | -------------------------------------------------------------------------------- /src/scratch/costume_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "costume_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | CostumePrivate::CostumePrivate() : 8 | broadcast("", "", true) 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /src/scratch/costume_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | struct CostumePrivate 12 | { 13 | CostumePrivate(); 14 | CostumePrivate(const CostumePrivate &) = delete; 15 | 16 | double oldBitmapResolution = 1; 17 | double bitmapResolution = 1; 18 | int rotationCenterX = 0; 19 | int rotationCenterY = 0; 20 | Broadcast broadcast; 21 | }; 22 | 23 | } // namespace libscratchcpp 24 | -------------------------------------------------------------------------------- /src/scratch/drawable.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "drawable_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs Drawable. */ 10 | Drawable::Drawable() : 11 | impl(spimpl::make_unique_impl()) 12 | { 13 | } 14 | 15 | /*! Returns the layer number. */ 16 | int Drawable::layerOrder() const 17 | { 18 | return impl->layerOrder; 19 | } 20 | 21 | /*! Sets the layer number. */ 22 | void Drawable::setLayerOrder(int newLayerOrder) 23 | { 24 | impl->layerOrder = newLayerOrder; 25 | impl->layerOrderChanged(newLayerOrder); 26 | } 27 | 28 | /*! Emits when the layer number changes. */ 29 | sigslot::signal &Drawable::layerOrderChanged() const 30 | { 31 | return impl->layerOrderChanged; 32 | } 33 | 34 | /*! Returns the engine. */ 35 | IEngine *Drawable::engine() const 36 | { 37 | return impl->engine; 38 | } 39 | 40 | /*! Sets the engine. */ 41 | void Drawable::setEngine(IEngine *engine) 42 | { 43 | impl->engine = engine; 44 | } 45 | -------------------------------------------------------------------------------- /src/scratch/drawable_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "drawable_p.h" 4 | 5 | using namespace libscratchcpp; 6 | -------------------------------------------------------------------------------- /src/scratch/drawable_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class IEngine; 11 | 12 | struct DrawablePrivate 13 | { 14 | int layerOrder = 0; 15 | IEngine *engine = nullptr; 16 | mutable sigslot::signal layerOrderChanged; 17 | }; 18 | 19 | } // namespace libscratchcpp 20 | -------------------------------------------------------------------------------- /src/scratch/entity.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "entity_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | /*! Constructs Entity. */ 10 | Entity::Entity(const std::string &id) : 11 | impl(spimpl::make_unique_impl(id)) 12 | { 13 | } 14 | 15 | /*! Returns the ID. */ 16 | const std::string &Entity::id() const 17 | { 18 | return impl->id; 19 | } 20 | 21 | /*! Sets the ID. */ 22 | void Entity::setId(const std::string &newId) 23 | { 24 | impl->id = newId; 25 | } 26 | -------------------------------------------------------------------------------- /src/scratch/entity_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "entity_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | EntityPrivate::EntityPrivate(const std::string &id) : 8 | id(id) 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /src/scratch/entity_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct EntityPrivate 11 | { 12 | EntityPrivate(const std::string &id); 13 | 14 | std::string id; 15 | }; 16 | 17 | } // namespace libscratchcpp 18 | -------------------------------------------------------------------------------- /src/scratch/field_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "field_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | FieldPrivate::FieldPrivate(const std::string &name, const Value &value, std::shared_ptr valuePtr) : 10 | name(name), 11 | value(value), 12 | valuePtr(valuePtr) 13 | { 14 | if (valuePtr) 15 | valueId = valuePtr->id(); 16 | } 17 | 18 | FieldPrivate::FieldPrivate(const std::string &name, const Value &value, const std::string &valueId) : 19 | name(name), 20 | value(value), 21 | valueId(valueId) 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /src/scratch/field_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Entity; 13 | 14 | struct FieldPrivate 15 | { 16 | FieldPrivate(const std::string &name, const Value &value, std::shared_ptr valuePtr = nullptr); 17 | FieldPrivate(const std::string &name, const Value &value, const std::string &valueId); 18 | 19 | std::string name; 20 | int fieldId = -1; 21 | Value value; 22 | std::shared_ptr valuePtr = nullptr; 23 | std::string valueId; 24 | int specialValueId = -1; 25 | }; 26 | 27 | } // namespace libscratchcpp 28 | -------------------------------------------------------------------------------- /src/scratch/input_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "input_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | InputPrivate::InputPrivate(const std::string &name, Input::Type type) : 8 | name(name), 9 | type(type) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /src/scratch/input_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | struct InputPrivate 12 | { 13 | InputPrivate(const std::string &name, Input::Type type); 14 | InputPrivate(const InputValue &) = delete; 15 | 16 | std::string name; 17 | int inputId = -1; 18 | Input::Type type; 19 | InputValue primaryValue; 20 | InputValue secondaryValue; 21 | }; 22 | 23 | } // namespace libscratchcpp 24 | -------------------------------------------------------------------------------- /src/scratch/inputvalue_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "inputvalue_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | InputValuePrivate::InputValuePrivate() 8 | { 9 | } 10 | 11 | InputValuePrivate::InputValuePrivate(InputValue::Type type) : 12 | type(type) 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/scratch/inputvalue_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | struct InputValuePrivate 11 | { 12 | InputValuePrivate(); 13 | InputValuePrivate(InputValue::Type type); 14 | 15 | InputValue::Type type; 16 | Value value; 17 | Block *valueBlock = nullptr; 18 | std::string valueBlockId; 19 | std::shared_ptr valuePtr = nullptr; 20 | std::string valueId; 21 | }; 22 | 23 | } // namespace libscratchcpp 24 | -------------------------------------------------------------------------------- /src/scratch/keyevent.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "keyevent_p.h" 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | /*! Constructs KeyEvent. */ 11 | KeyEvent::KeyEvent(Type type) : 12 | impl(spimpl::make_impl(type)) 13 | { 14 | } 15 | 16 | /*! Constructs KeyEvent from a key name. */ 17 | KeyEvent::KeyEvent(const std::string &name) : 18 | impl(spimpl::make_impl(name)) 19 | { 20 | } 21 | 22 | /*! Returns the type of the key. */ 23 | KeyEvent::Type KeyEvent::type() const 24 | { 25 | return impl->type; 26 | } 27 | 28 | /*! Returns the name of the key. */ 29 | const std::string &KeyEvent::name() const 30 | { 31 | return impl->name; 32 | } 33 | 34 | } // namespace libscratchcpp 35 | -------------------------------------------------------------------------------- /src/scratch/keyevent_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | struct KeyEventPrivate 12 | { 13 | KeyEventPrivate(KeyEvent::Type type); 14 | KeyEventPrivate(const std::string &name); 15 | 16 | void convertNameToLowercase(); 17 | 18 | KeyEvent::Type type = KeyEvent::Type::Any; 19 | std::string name; 20 | }; 21 | 22 | } // namespace libscratchcpp 23 | -------------------------------------------------------------------------------- /src/scratch/list_functions.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "list_functions.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | extern "C" 10 | { 11 | void list_clear(List *list) 12 | { 13 | list->clear(); 14 | } 15 | 16 | void list_remove(List *list, size_t index) 17 | { 18 | list->removeAt(index); 19 | } 20 | 21 | ValueData *list_append_empty(List *list) 22 | { 23 | return &list->appendEmpty(); 24 | } 25 | 26 | ValueData *list_insert_empty(List *list, size_t index) 27 | { 28 | return &list->insertEmpty(index); 29 | } 30 | 31 | ValueData *list_get_item(List *list, size_t index) 32 | { 33 | return &list->operator[](index); 34 | } 35 | 36 | ValueData *list_data(List *list) 37 | { 38 | return list->data(); 39 | } 40 | 41 | size_t *list_size_ptr(List *list) 42 | { 43 | return list->sizePtr(); 44 | } 45 | 46 | const size_t *list_alloc_size_ptr(List *list) 47 | { 48 | return list->allocatedSizePtr(); 49 | } 50 | 51 | size_t list_size(List *list) 52 | { 53 | return list->size(); 54 | } 55 | 56 | StringPtr *list_to_string(List *list) 57 | { 58 | return list->toStringPtr(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/scratch/list_functions.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | namespace libscratchcpp 8 | { 9 | 10 | class List; 11 | struct ValueData; 12 | struct StringPtr; 13 | 14 | extern "C" 15 | { 16 | void list_clear(List *list); 17 | void list_remove(List *list, size_t index); 18 | 19 | ValueData *list_append_empty(List *list); 20 | ValueData *list_insert_empty(List *list, size_t index); 21 | 22 | ValueData *list_get_item(List *list, size_t index); 23 | ValueData *list_data(List *list); 24 | size_t *list_size_ptr(List *list); 25 | const size_t *list_alloc_size_ptr(List *list); 26 | size_t list_size(List *list); 27 | 28 | StringPtr *list_to_string(List *list); 29 | } 30 | 31 | } // namespace libscratchcpp 32 | -------------------------------------------------------------------------------- /src/scratch/list_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include "list_p.h" 4 | 5 | using namespace libscratchcpp; 6 | 7 | ListPrivate::ListPrivate(const std::string &name) : 8 | name(name) 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /src/scratch/list_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace libscratchcpp 10 | { 11 | 12 | class Target; 13 | class Monitor; 14 | 15 | struct ListPrivate 16 | { 17 | ListPrivate(const std::string &name); 18 | 19 | std::string name; 20 | Target *target = nullptr; 21 | Monitor *monitor = nullptr; 22 | veque::veque data; 23 | }; 24 | 25 | } // namespace libscratchcpp 26 | -------------------------------------------------------------------------------- /src/scratch/monitor_p.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #include 4 | 5 | #include "monitor_p.h" 6 | 7 | using namespace libscratchcpp; 8 | 9 | IRandomGenerator *MonitorPrivate::rng = nullptr; 10 | 11 | MonitorPrivate::MonitorPrivate(const std::string &opcode) : 12 | block(std::make_shared("", opcode, true)) 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/scratch/monitor_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace libscratchcpp 9 | { 10 | 11 | class Block; 12 | class IRandomGenerator; 13 | 14 | struct MonitorPrivate 15 | { 16 | MonitorPrivate(const std::string &opcode); 17 | MonitorPrivate(const MonitorPrivate &) = delete; 18 | 19 | IMonitorHandler *iface = nullptr; 20 | std::string name; 21 | Monitor::Mode mode = Monitor::Mode::Default; 22 | std::shared_ptr