diff --git a/.gitignore b/.gitignore index 94017b1b..45d41876 100644 --- a/.gitignore +++ b/.gitignore @@ -91,4 +91,6 @@ dependencies/windows/cache # Local development setup compile_commands.json -tests/unit_tests/dependencies \ No newline at end of file +# running tests results in this +tests/unit_tests/dependencies +tests/unit_tests/default.profraw diff --git a/.rive_head b/.rive_head index dd1b41eb..c3d30c24 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f359c918e0135e8c432f7ba3068fff7dbba0ac07 +9d8a7e81fa467fc85614952f4566af060e1d43f7 diff --git a/dev/defs/animation/linear_animation.json b/dev/defs/animation/linear_animation.json index 068f5b55..2205cc08 100644 --- a/dev/defs/animation/linear_animation.json +++ b/dev/defs/animation/linear_animation.json @@ -4,7 +4,7 @@ "int": 31, "string": "linearanimation" }, - "extends": "animation/animation.json", + "extends": "animation/linear_animation_resolver.json", "properties": { "fps": { "type": "uint", diff --git a/dev/defs/animation/linear_animation_resolver.json b/dev/defs/animation/linear_animation_resolver.json new file mode 100644 index 00000000..9681b681 --- /dev/null +++ b/dev/defs/animation/linear_animation_resolver.json @@ -0,0 +1,10 @@ +{ + "name": "LinearAnimationResolver", + "key": { + "int": 550, + "string": "linearanimationresolver" + }, + "abstract": true, + "runtime": false, + "extends": "animation/animation.json" +} \ No newline at end of file diff --git a/dev/defs/animation/nested_linear_animation.json b/dev/defs/animation/nested_linear_animation.json index 23846e45..da468405 100644 --- a/dev/defs/animation/nested_linear_animation.json +++ b/dev/defs/animation/nested_linear_animation.json @@ -6,7 +6,6 @@ }, "abstract": true, "extends": "nested_animation.json", - "generic": "animation/linear_animation.json", "properties": { "mix": { "type": "double", diff --git a/dev/defs/animation/nested_state_machine.json b/dev/defs/animation/nested_state_machine.json index 19825150..6597f7ab 100644 --- a/dev/defs/animation/nested_state_machine.json +++ b/dev/defs/animation/nested_state_machine.json @@ -5,5 +5,5 @@ "string": "nestedStateMachine" }, "extends": "nested_animation.json", - "generic": "animation/state_machine.json" + "generic": "animation/state_machine_resolver.json" } \ No newline at end of file diff --git a/dev/defs/animation/state_machine.json b/dev/defs/animation/state_machine.json index fa97a25f..6a804772 100644 --- a/dev/defs/animation/state_machine.json +++ b/dev/defs/animation/state_machine.json @@ -4,7 +4,7 @@ "int": 53, "string": "statemachine" }, - "extends": "animation/animation.json", + "extends": "animation/state_machine_resolver.json", "properties": { "editingLayerId": { "type": "Id", diff --git a/dev/defs/animation/state_machine_resolver.json b/dev/defs/animation/state_machine_resolver.json new file mode 100644 index 00000000..51bb72ef --- /dev/null +++ b/dev/defs/animation/state_machine_resolver.json @@ -0,0 +1,10 @@ +{ + "name": "StateMachineResolver", + "key": { + "int": 551, + "string": "statemachineresolver" + }, + "abstract": true, + "runtime": false, + "extends": "animation/animation.json" +} \ No newline at end of file diff --git a/include/rive/animation/nested_input.hpp b/include/rive/animation/nested_input.hpp index fe75467c..a5d5c105 100644 --- a/include/rive/animation/nested_input.hpp +++ b/include/rive/animation/nested_input.hpp @@ -29,6 +29,10 @@ public: { StateMachineInstance* smInstance = parent->as()->stateMachineInstance(); + if (smInstance == nullptr) + { + return nullptr; + } auto inputInstance = smInstance->input(this->inputId()); return inputInstance; } diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index aaf4db76..9bc63836 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -1428,17 +1428,21 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { if (animation->is()) { - auto notifier = - animation->as()->stateMachineInstance(); - notifier->setNestedArtboard(nestedArtboard); - notifier->addNestedEventListener(this); + if (auto notifier = animation->as() + ->stateMachineInstance()) + { + notifier->setNestedArtboard(nestedArtboard); + notifier->addNestedEventListener(this); + } } else if (animation->is()) { - auto notifier = - animation->as()->animationInstance(); - notifier->setNestedArtboard(nestedArtboard); - notifier->addNestedEventListener(this); + if (auto notifier = animation->as() + ->animationInstance()) + { + notifier->setNestedArtboard(nestedArtboard); + notifier->addNestedEventListener(this); + } } } } diff --git a/tests/unit_tests/assets/custom_image_name.riv b/tests/unit_tests/assets/custom_image_name.riv new file mode 100644 index 00000000..3fdf961a Binary files /dev/null and b/tests/unit_tests/assets/custom_image_name.riv differ diff --git a/tests/unit_tests/assets/double_library_with_image.riv b/tests/unit_tests/assets/double_library_with_image.riv new file mode 100644 index 00000000..a084c450 Binary files /dev/null and b/tests/unit_tests/assets/double_library_with_image.riv differ diff --git a/tests/unit_tests/assets/library.riv b/tests/unit_tests/assets/library.riv new file mode 100644 index 00000000..a2b38d98 Binary files /dev/null and b/tests/unit_tests/assets/library.riv differ diff --git a/tests/unit_tests/assets/library_export_animation_test.riv b/tests/unit_tests/assets/library_export_animation_test.riv new file mode 100644 index 00000000..2ff71147 Binary files /dev/null and b/tests/unit_tests/assets/library_export_animation_test.riv differ diff --git a/tests/unit_tests/assets/library_export_state_machine_test.riv b/tests/unit_tests/assets/library_export_state_machine_test.riv new file mode 100644 index 00000000..bc7bcaff Binary files /dev/null and b/tests/unit_tests/assets/library_export_state_machine_test.riv differ diff --git a/tests/unit_tests/assets/library_export_test.riv b/tests/unit_tests/assets/library_export_test.riv new file mode 100644 index 00000000..fbb3effc Binary files /dev/null and b/tests/unit_tests/assets/library_export_test.riv differ diff --git a/tests/unit_tests/assets/library_export_with_smi.riv b/tests/unit_tests/assets/library_export_with_smi.riv new file mode 100644 index 00000000..1f09afe8 Binary files /dev/null and b/tests/unit_tests/assets/library_export_with_smi.riv differ diff --git a/tests/unit_tests/assets/library_with_image.riv b/tests/unit_tests/assets/library_with_image.riv new file mode 100644 index 00000000..dbf32c73 Binary files /dev/null and b/tests/unit_tests/assets/library_with_image.riv differ diff --git a/tests/unit_tests/assets/library_with_text_and_image.riv b/tests/unit_tests/assets/library_with_text_and_image.riv new file mode 100644 index 00000000..ea4bfd3d Binary files /dev/null and b/tests/unit_tests/assets/library_with_text_and_image.riv differ diff --git a/tests/unit_tests/assets/smi_test.riv b/tests/unit_tests/assets/smi_test.riv new file mode 100644 index 00000000..d2708ea6 Binary files /dev/null and b/tests/unit_tests/assets/smi_test.riv differ diff --git a/tests/unit_tests/runtime/library_asset_test.cpp b/tests/unit_tests/runtime/library_asset_test.cpp new file mode 100644 index 00000000..8649f9c0 --- /dev/null +++ b/tests/unit_tests/runtime/library_asset_test.cpp @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rive_file_reader.hpp" +#include +#include + +TEST_CASE("File with library artboard loads", "[libraries]") +{ + // created by test in rive_core. + auto file = ReadRiveFile("assets/library_export_test.riv"); + + auto nestedArtboard = + file->artboard()->find("The nested artboard"); + REQUIRE(nestedArtboard != nullptr); + REQUIRE(nestedArtboard->name() == "The nested artboard"); + REQUIRE(nestedArtboard->x() == 1); + REQUIRE(nestedArtboard->y() == 2); + REQUIRE(nestedArtboard->artboardId() == -1); + + // time to find the library asset somewhere + auto assets = file->assets(); + REQUIRE(assets.size() == 0); + // todo assert nested artboard structure +} + +TEST_CASE("File with library animation loads", "[libraries]") +{ + // created by test in rive_core. + auto file = ReadRiveFile("assets/library_export_animation_test.riv"); + + auto nestedArtboard = + file->artboard()->find("The nested artboard"); + REQUIRE(nestedArtboard != nullptr); + REQUIRE(nestedArtboard->name() == "The nested artboard"); + REQUIRE(nestedArtboard->x() == 1); + REQUIRE(nestedArtboard->y() == 2); + REQUIRE(nestedArtboard->artboardId() == -1); + + auto nestedSimpleAnimation = + file->artboard()->find(""); + REQUIRE(nestedSimpleAnimation != nullptr); + REQUIRE(nestedSimpleAnimation->name() == ""); + REQUIRE(nestedSimpleAnimation->isPlaying() == true); + // // TODO: figure out what the id should be? + REQUIRE(nestedSimpleAnimation->animationId() == -1); + + // // time to find the library asset somewhere + auto assets = file->assets(); + REQUIRE(assets.size() == 0); + + REQUIRE(nestedArtboard->nestedAnimations().size() == 1); + // todo assert nested artboard has animation structure +} + +TEST_CASE("File with library state machine loads", "[libraries]") +{ + // created by test in rive_core. + auto file = ReadRiveFile("assets/library_export_state_machine_test.riv"); + + auto nestedArtboard = + file->artboard()->find("The nested artboard"); + REQUIRE(nestedArtboard != nullptr); + REQUIRE(nestedArtboard->name() == "The nested artboard"); + REQUIRE(nestedArtboard->x() == 1); + REQUIRE(nestedArtboard->y() == 2); + REQUIRE(nestedArtboard->artboardId() == -1); + + auto nestedSimpleAnimation = + file->artboard()->find(""); + REQUIRE(nestedSimpleAnimation != nullptr); + REQUIRE(nestedSimpleAnimation->name() == ""); + REQUIRE(nestedSimpleAnimation->animationId() == -1); + + // time to find the library asset somewhere + // make sure its loaded? + auto assets = file->assets(); + REQUIRE(assets.size() == 0); + + REQUIRE(nestedArtboard->nestedAnimations().size() == 1); + // todo assert nested artboard has state machine structure +} + +// TODO reinstate, but right now we're missing fonts locally, need to get +// backend to uat to recreate this test. we are literally just loading files +// here. TEST_CASE("File with library", "[libraries]") +// { +// TODO: create this file in the editor tests. +// auto file = ReadRiveFile("assets/library_with_text_and_image.riv"); + +// // library, image and text +// auto assets = file->assets(); +// REQUIRE(assets.size() == 3); +// auto libraryAsset = assets[0]; +// REQUIRE(libraryAsset->is()); +// REQUIRE(libraryAsset->name() == "library - Version 1"); + +// auto fontAsset = assets[1]; +// REQUIRE(fontAsset->is()); +// REQUIRE(fontAsset->name() == "Inter"); + +// auto imageAsset = assets[2]; +// REQUIRE(imageAsset->is()); +// REQUIRE(imageAsset->name() == "tree"); + +// // library, image and text +// auto libraryAssets = +// static_cast(libraryAsset)->riveFile()->assets(); +// REQUIRE(libraryAssets.size() == 2); + +// auto librayFontAsset = libraryAssets[0]; +// REQUIRE(librayFontAsset->is()); +// REQUIRE(librayFontAsset->name() == "Inter"); + +// auto libraryImageAsset = libraryAssets[1]; +// REQUIRE(libraryImageAsset->is()); +// REQUIRE(libraryImageAsset->name() == "tree"); +// } + +// we are literally just loading files here. +TEST_CASE("File with library including image", "[libraries]") +{ + // TODO: create this file in the editor tests. + auto file = ReadRiveFile("assets/library_with_image.riv"); + + // library, image and text + auto assets = file->assets(); + REQUIRE(assets.size() == 0); + // TODO: asset image +} + +TEST_CASE("File with multiple libraries including image", "[libraries]") +{ + // TODO: create this file in the editor tests. + auto file = ReadRiveFile("assets/double_library_with_image.riv"); + + // library, image and text + auto assets = file->assets(); + REQUIRE(assets.size() == 0); + // TODO: asset multiple images +} diff --git a/tests/unit_tests/runtime/library_state_machine_input_test.cpp b/tests/unit_tests/runtime/library_state_machine_input_test.cpp new file mode 100644 index 00000000..33eb7123 --- /dev/null +++ b/tests/unit_tests/runtime/library_state_machine_input_test.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rive_file_reader.hpp" +#include +#include + +TEST_CASE("File with library state machine inputs loads", "[state_machine]") +{ + // created by test in rive_core. + auto file = ReadRiveFile("assets/library_export_with_smi.riv"); + + auto nestedArtboard = + file->artboard()->find("The nested artboard"); + REQUIRE(nestedArtboard != nullptr); + REQUIRE(nestedArtboard->name() == "The nested artboard"); + REQUIRE(nestedArtboard->x() == 1); + REQUIRE(nestedArtboard->y() == 2); + REQUIRE(nestedArtboard->artboardId() == -1); + + auto nestedSimpleAnimation = + file->artboard()->find(""); + REQUIRE(nestedSimpleAnimation != nullptr); + REQUIRE(nestedSimpleAnimation->name() == ""); + REQUIRE(nestedSimpleAnimation->animationId() == -1); + + auto nestedTrigger = file->artboard()->find(""); + REQUIRE(nestedTrigger != nullptr); + REQUIRE(nestedTrigger->name() == ""); + REQUIRE(nestedTrigger->inputId() == -1); + + auto nestedBool = file->artboard()->find(""); + REQUIRE(nestedBool != nullptr); + REQUIRE(nestedBool->name() == ""); + REQUIRE(nestedBool->inputId() == -1); + + auto nestedNumber = file->artboard()->find(""); + REQUIRE(nestedNumber != nullptr); + REQUIRE(nestedNumber->name() == ""); + REQUIRE(nestedNumber->inputId() == -1); + + // time to find the library asset somewhere + // make sure its loaded? + auto assets = file->assets(); + REQUIRE(assets.size() == 0); + + // todo assert state machine input structure holds up! +} diff --git a/tests/unit_tests/runtime/state_machine_input_test.cpp b/tests/unit_tests/runtime/state_machine_input_test.cpp new file mode 100644 index 00000000..8f971fdf --- /dev/null +++ b/tests/unit_tests/runtime/state_machine_input_test.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rive_file_reader.hpp" +#include +#include + +TEST_CASE("File with state machine inputs loads", "[state_machine]") +{ + // created by test in rive_core. + auto file = ReadRiveFile("assets/smi_test.riv"); + + auto nestedArtboard = file->artboard()->find( + "artboard to nest component"); + REQUIRE(nestedArtboard != nullptr); + REQUIRE(nestedArtboard->x() == 100); + REQUIRE(nestedArtboard->y() == 100); + REQUIRE(nestedArtboard->name() == "artboard to nest component"); + REQUIRE(nestedArtboard->artboardId() == 1); + + auto nestedSimpleAnimation = + file->artboard()->find(""); + REQUIRE(nestedSimpleAnimation != nullptr); + REQUIRE(nestedSimpleAnimation->name() == ""); + REQUIRE(nestedSimpleAnimation->animationId() == 0); + + auto nestedTrigger = file->artboard()->find(""); + REQUIRE(nestedTrigger != nullptr); + REQUIRE(nestedTrigger->name() == ""); + REQUIRE(nestedTrigger->inputId() == 0); + + auto nestedBool = file->artboard()->find(""); + REQUIRE(nestedBool != nullptr); + REQUIRE(nestedBool->name() == ""); + REQUIRE(nestedBool->inputId() == 1); + + auto nestedNumber = file->artboard()->find(""); + REQUIRE(nestedNumber != nullptr); + REQUIRE(nestedNumber->name() == ""); + REQUIRE(nestedNumber->inputId() == 2); +} diff --git a/tests/unit_tests/test.sh b/tests/unit_tests/test.sh index 87d7b59d..75627d57 100755 --- a/tests/unit_tests/test.sh +++ b/tests/unit_tests/test.sh @@ -10,22 +10,36 @@ MINGW*) machine=windows ;; esac CONFIG=debug - -for var in "$@"; do - if [[ $var = "release" ]]; then - CONFIG=release - elif [ "$var" = "memory" ]; then - echo Will perform memory checks... - UTILITY='leaks --atExit --' - shift - elif [ "$var" = "lldb" ]; then - echo Starting debugger... - UTILITY='lldb' - shift - elif [ "$var" = "rebaseline" ]; then - export REBASELINE_SILVERS=true - shift - fi +MATCH= +while [[ $# -gt 0 ]]; do + case $1 in + -m|--match) + MATCH="$2" + shift # past argument + shift # past value + ;; + lldb) + echo Starting debugger... + UTILITY='lldb' + shift # past argument + ;; + memory) + echo Will perform memory checks... + UTILITY='leaks --atExit --' + shift + ;; + release) + CONFIG=release + shift + ;; + rebaseline) + export REBASELINE_SILVERS=true + shift + ;; + *) + shift # past argument + ;; + esac done if [[ ! -f "dependencies/bin/premake5" ]]; then @@ -36,6 +50,9 @@ if [[ ! -f "dependencies/bin/premake5" ]]; then # once a stable one is avaialble that supports it git clone --depth 1 --branch v5.0.0-beta3 https://github.com/premake/premake-core.git pushd premake-core + git pull --tags + git checkout v5.0.0-beta3 + # note, latest premake is not compatible with our fatal warnings... if [[ $LOCAL_ARCH == "arm64" ]]; then PREMAKE_MAKE_ARCH=ARM else @@ -89,7 +106,7 @@ if [[ $machine = "macosx" ]]; then popd rm -fR silvers/tarnished mkdir -p silvers/tarnished - $UTILITY $OUT_DIR/unit_tests + $UTILITY $OUT_DIR/unit_tests "$MATCH" for var in "$@"; do if [[ $var = "coverage" ]]; then xcrun llvm-profdata merge -sparse default.profraw -o default.profdata diff --git a/viewer/build/premake5_viewer.lua b/viewer/build/premake5_viewer.lua index b477fbe3..be3b9a21 100644 --- a/viewer/build/premake5_viewer.lua +++ b/viewer/build/premake5_viewer.lua @@ -7,8 +7,8 @@ rive_tess = '../../tess' rive_skia = '../../skia' skia = dependencies .. '/skia' +dofile(rive .. '/decoders/premake5_v2.lua') if _OPTIONS.renderer == 'tess' then - dofile(rive .. '/decoders/premake5_v2.lua') dofile(path.join(path.getabsolute(rive_tess) .. '/build', 'premake5_tess.lua')) else -- tess renderer includes this @@ -19,9 +19,7 @@ dofile(path.join(path.getabsolute(rive) .. '/cg_renderer', 'premake5.lua')) project('rive_viewer') do - if _OPTIONS.renderer == 'tess' then - dependson('rive_decoders') - end + dependson('rive_decoders') kind('ConsoleApp') defines({ 'WITH_RIVE_TEXT', 'WITH_RIVE_AUDIO', 'WITH_RIVE_LAYOUT', 'YOGA_EXPORT=' }) @@ -29,6 +27,7 @@ do includedirs({ '../include', rive .. '/include', + rive .. '/decoders/include', rive .. '/skia/renderer/include', -- for font backends dependencies, dependencies .. '/sokol', @@ -37,7 +36,7 @@ do yoga, }) - links({ 'rive', 'rive_harfbuzz', 'rive_sheenbidi', 'rive_yoga' }) + links({ 'rive','rive_decoders', 'rive_harfbuzz', 'rive_sheenbidi', 'rive_yoga' }) libdirs({ rive .. '/build/%{cfg.system}/bin/%{cfg.buildcfg}' })