diff --git a/.rive_head b/.rive_head index 30c2abb5..7106762c 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -c7d125c7d4efe1233c16c2a95fb7b637b746b010 +cef9bd8cddeb94916281002fa2491777b1642eff diff --git a/Example-iOS/Assets/empty_animation_state.riv b/Example-iOS/Assets/empty_animation_state.riv new file mode 100644 index 00000000..a8db3986 Binary files /dev/null and b/Example-iOS/Assets/empty_animation_state.riv differ diff --git a/RiveRuntime.xcodeproj/project.pbxproj b/RiveRuntime.xcodeproj/project.pbxproj index b1987d8d..5f20d9fb 100644 --- a/RiveRuntime.xcodeproj/project.pbxproj +++ b/RiveRuntime.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ 04BE5430264D1F4100427B39 /* LayerState.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BE542F264D1F4100427B39 /* LayerState.h */; settings = {ATTRIBUTES = (Public, ); }; }; 04BE5434264D267900427B39 /* LayerState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04BE5431264D243D00427B39 /* LayerState.mm */; }; 04BE5436264D2A7500427B39 /* RivePrivateHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BE5435264D2A7500427B39 /* RivePrivateHeaders.h */; }; + 04ED72F1299C114000E8DE53 /* RiveViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04ED72F0299C114000E8DE53 /* RiveViewModelTest.swift */; }; + 04ED72F3299C115100E8DE53 /* empty_animation_state.riv in Resources */ = {isa = PBXBuildFile; fileRef = 04ED72F2299C115100E8DE53 /* empty_animation_state.riv */; }; 274175FD286DB9CE000A60D1 /* cg_skia_factory.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 274175FB286DB9CE000A60D1 /* cg_skia_factory.hpp */; }; 274175FE286DB9CE000A60D1 /* cg_skia_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 274175FC286DB9CE000A60D1 /* cg_skia_factory.cpp */; }; 2A7079352726277C00C035A1 /* rive_renderer_view.hh in Headers */ = {isa = PBXBuildFile; fileRef = 2A7079342726277C00C035A1 /* rive_renderer_view.hh */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -109,6 +111,8 @@ 04BE542F264D1F4100427B39 /* LayerState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayerState.h; sourceTree = ""; }; 04BE5431264D243D00427B39 /* LayerState.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LayerState.mm; sourceTree = ""; }; 04BE5435264D2A7500427B39 /* RivePrivateHeaders.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RivePrivateHeaders.h; sourceTree = ""; }; + 04ED72F0299C114000E8DE53 /* RiveViewModelTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RiveViewModelTest.swift; sourceTree = ""; }; + 04ED72F2299C115100E8DE53 /* empty_animation_state.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = empty_animation_state.riv; sourceTree = ""; }; 274175FB286DB9CE000A60D1 /* cg_skia_factory.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cg_skia_factory.hpp; sourceTree = ""; }; 274175FC286DB9CE000A60D1 /* cg_skia_factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cg_skia_factory.cpp; sourceTree = ""; }; 2A7079342726277C00C035A1 /* rive_renderer_view.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = rive_renderer_view.hh; sourceTree = ""; }; @@ -177,6 +181,7 @@ 04BE5419264A823000427B39 /* animationconfigurations.riv */, 04BE53FC2649403600427B39 /* flux_capacitor.riv */, 04BE54012649403600427B39 /* junk.riv */, + 04ED72F2299C115100E8DE53 /* empty_animation_state.riv */, 04BE53FF2649403600427B39 /* multiple_animations.riv */, 04BE54022649403600427B39 /* multiple_state_machines.riv */, 04BE54002649403600427B39 /* multipleartboards.riv */, @@ -265,6 +270,7 @@ 04BE541D264AC7A600427B39 /* RiveArtboardLoadTest.mm */, 04BE541F264ACFC200427B39 /* RiveStateMachineLoadTest.mm */, 04BE5421264AD97C00427B39 /* RiveStateMachineConfigurationTest.mm */, + 04ED72F0299C114000E8DE53 /* RiveViewModelTest.swift */, 04BE5426264C02AA00427B39 /* StateMachineInstanceTest.mm */, 04BE542C264C1A3300427B39 /* RiveDelegatesTest.swift */, C38BB5F528762B720039E385 /* RiveStateMachineTest.swift */, @@ -397,6 +403,7 @@ 04BE54082649403600427B39 /* flux_capacitor.riv in Resources */, 04BE54052649403600427B39 /* noartboard.riv in Resources */, 04BE540B2649403600427B39 /* multiple_animations.riv in Resources */, + 04ED72F3299C115100E8DE53 /* empty_animation_state.riv in Resources */, 04BE54062649403600427B39 /* off_road_car_blog.riv in Resources */, 04BE540C2649403600427B39 /* multipleartboards.riv in Resources */, 04BE540D2649403600427B39 /* junk.riv in Resources */, @@ -441,6 +448,7 @@ 04BE541E264AC7A600427B39 /* RiveArtboardLoadTest.mm in Sources */, 04BE542D264C1A3300427B39 /* RiveDelegatesTest.swift in Sources */, 04BE5422264AD97C00427B39 /* RiveStateMachineConfigurationTest.mm in Sources */, + 04ED72F1299C114000E8DE53 /* RiveViewModelTest.swift in Sources */, 04BE541C264A90D600427B39 /* RiveAnimationLoadTest.mm in Sources */, C9C73EE024FC478900EF9516 /* RiveRuntimeTests.mm in Sources */, 04BE5413264943BB00427B39 /* util.mm in Sources */, diff --git a/Source/Renderer/LayerState.mm b/Source/Renderer/LayerState.mm index fd566ff9..33c0f966 100644 --- a/Source/Renderer/LayerState.mm +++ b/Source/Renderer/LayerState.mm @@ -88,8 +88,12 @@ @implementation RiveAnimationState - (NSString*)name { auto inst = [self rive_layer_state]; - auto str = ((const rive::AnimationState*)inst)->animation()->name(); - return [NSString stringWithCString:str.c_str() encoding:[NSString defaultCStringEncoding]]; + auto animation = ((const rive::AnimationState*)inst)->animation(); + + if (animation == nil){ + return [NSString stringWithCString:"Unknown" encoding:[NSString defaultCStringEncoding]]; + } + return [NSString stringWithCString:animation->name().c_str() encoding:[NSString defaultCStringEncoding]]; } @end diff --git a/Tests/Assets/empty_animation_state.riv b/Tests/Assets/empty_animation_state.riv new file mode 100644 index 00000000..a8db3986 Binary files /dev/null and b/Tests/Assets/empty_animation_state.riv differ diff --git a/Tests/RiveViewModelTest.swift b/Tests/RiveViewModelTest.swift new file mode 100644 index 00000000..cafe0e64 --- /dev/null +++ b/Tests/RiveViewModelTest.swift @@ -0,0 +1,25 @@ +// +// RiveViewModelTest.swift +// RiveRuntimeTests +// +// Created by Maxwell Talbot on 14/02/2023. +// Copyright © 2023 Rive. All rights reserved. +// + +import XCTest +import RiveRuntime + +class RiveViewModelTest: XCTestCase { + + // This test reproduces a previous production error + // Having an Animation state without an animation caused advancing a state machine past it + // to fail + func testLoadFileWithEmptyAnimationState() throws { + let file = try RiveFile(testfileName: "empty_animation_state") + let model = RiveModel(riveFile: file) + let viewModel = RiveViewModel(model, autoPlay: false) + let view = viewModel.createRiveView() + + view.advance(delta: 0.1) + } +}