From 9dc67e35158935ed4364bff86bcf551e50b4cec8 Mon Sep 17 00:00:00 2001 From: philter Date: Fri, 28 Jun 2024 21:33:34 +0000 Subject: [PATCH] Remove files to unblock downstream iOS push Diffs= cf89553e9 Remove files to unblock downstream iOS push (#7500) 1adf3dbf4 disable fallback font during artboard rendering (#7480) 6f29a9c0c Miscellaneous Layout UX Fixes (#7491) 09ccc9ebb Add yoga to thumbnail generator build (#7494) aa390d5dc change how viewmodel instances target their viewmodel (#7468) e66e242c6 Xxxx databinding add boolean (#7456) 9cd8759a0 Xxxx data binding data context (#7454) 31f5ee5c4 Animation for Layouts (#7426) a4439ee42 Renames for Yoga and libjpeg (#7446) 97578005c Update LayoutComponentStyle bitfields to be compatible with older C++ versions (#7436) 75823467d databinding (#7341) ef9ef9fd1 Ios golden test (#7413) Co-authored-by: Jonathon Copeland Co-authored-by: Philip Chung --- .rive_head | 2 +- .rive_renderer | 2 +- Rive.xcworkspace/contents.xcworkspacedata | 3 + Source/Renderer/RenderContextManager.mm | 31 +- Source/Renderer/include/RenderContext.h | 6 +- Source/Renderer/include/rive_renderer_view.hh | 6 + Source/Renderer/rive_renderer_view.mm | 18 +- Source/RiveViewModel.swift | 8 +- exportOptions.plist | 18 + golden_test_app/golden-test-app-Info.plist | 8 + .../golden_test_app.xcodeproj/project.pbxproj | 420 ++++++++++++++++++ .../golden_test_app/AppDelegate.swift | 38 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 63 +++ .../Assets.xcassets/Contents.json | 6 + .../golden_test_app/ContentView.swift | 17 + .../Preview Assets.xcassets/Contents.json | 6 + .../RiveRendererTestViews.swift | 37 ++ .../golden_test_app/SceneDelegate.swift | 53 +++ .../golden_test_app/SingleDrawRiveView.swift | 154 +++++++ .../golden_test_app.entitlements | 5 + submodules/rive-cpp | 2 +- 22 files changed, 896 insertions(+), 18 deletions(-) create mode 100644 exportOptions.plist create mode 100644 golden_test_app/golden-test-app-Info.plist create mode 100644 golden_test_app/golden_test_app.xcodeproj/project.pbxproj create mode 100644 golden_test_app/golden_test_app/AppDelegate.swift create mode 100644 golden_test_app/golden_test_app/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 golden_test_app/golden_test_app/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 golden_test_app/golden_test_app/Assets.xcassets/Contents.json create mode 100644 golden_test_app/golden_test_app/ContentView.swift create mode 100644 golden_test_app/golden_test_app/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 golden_test_app/golden_test_app/RiveRendererTestViews.swift create mode 100644 golden_test_app/golden_test_app/SceneDelegate.swift create mode 100644 golden_test_app/golden_test_app/SingleDrawRiveView.swift create mode 100644 golden_test_app/golden_test_app/golden_test_app.entitlements diff --git a/.rive_head b/.rive_head index 2cdb2c0..155cddb 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -7e1b3027d5ea97c7950b8f5951b0b44f33413987 +cf89553e95f98df048b139a1cb06ea5e9f589393 diff --git a/.rive_renderer b/.rive_renderer index fc30043..bdc9bdb 100644 --- a/.rive_renderer +++ b/.rive_renderer @@ -1 +1 @@ -c7606bc0c6c2a1ec8ec3e4b349768f601daa405a +872ff90624ad780e24cc40f2c61c638d4905be3c diff --git a/Rive.xcworkspace/contents.xcworkspacedata b/Rive.xcworkspace/contents.xcworkspacedata index b3c0103..38d1abe 100644 --- a/Rive.xcworkspace/contents.xcworkspacedata +++ b/Rive.xcworkspace/contents.xcworkspacedata @@ -1,6 +1,9 @@ + + diff --git a/Source/Renderer/RenderContextManager.mm b/Source/Renderer/RenderContextManager.mm index f8822fb..22da66c 100644 --- a/Source/Renderer/RenderContextManager.mm +++ b/Source/Renderer/RenderContextManager.mm @@ -21,7 +21,7 @@ return nil; } -- (void)endFrame +- (void)endFrame:(MTKView*)view withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; {} @end @@ -49,7 +49,6 @@ @interface SkiaContext : RenderContext - (rive::Factory*)factory; - (rive::Renderer*)beginFrame:(MTKView*)view; -- (void)endFrame; @end @implementation SkiaContext @@ -148,7 +147,7 @@ static sk_sp mtk_view_to_sk_surface(MTKView* mtkView, GrDirectContext return _renderer.get(); } -- (void)endFrame +- (void)endFrame:(MTKView*)view withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; { if (_sksurface != nullptr) { @@ -156,6 +155,14 @@ static sk_sp mtk_view_to_sk_surface(MTKView* mtkView, GrDirectContext } _sksurface = nullptr; _renderer = nullptr; + + id commandBuffer = [self.metalQueue commandBuffer]; + [commandBuffer presentDrawable:view.currentDrawable]; + if (completionHandler) + { + [commandBuffer addCompletedHandler:completionHandler]; + } + [commandBuffer commit]; } @end @@ -170,7 +177,6 @@ static sk_sp mtk_view_to_sk_surface(MTKView* mtkView, GrDirectContext @interface RiveRendererContext : RenderContext - (rive::Renderer*)beginFrame:(MTKView*)view; -- (void)endFrame; @end @implementation RiveRendererContext @@ -289,13 +295,19 @@ static std::unique_ptr make_pls_context_native(id flushCommandBuffer = [self.metalQueue commandBuffer]; _plsContext->flush({ .renderTarget = _renderTarget.get(), .externalCommandBuffer = (__bridge void*)flushCommandBuffer, }); + + [flushCommandBuffer presentDrawable:view.currentDrawable]; + if (completionHandler) + { + [flushCommandBuffer addCompletedHandler:completionHandler]; + } [flushCommandBuffer commit]; } @@ -305,7 +317,6 @@ static std::unique_ptr make_pls_context_native(id +NS_ASSUME_NONNULL_BEGIN + @interface RiveRendererView : MTKView + - (instancetype)initWithFrame:(CGRect)frameRect; - (void)alignWithRect:(CGRect)rect contentRect:(CGRect)contentRect @@ -15,9 +18,12 @@ - (void)transform:(float)xx xy:(float)xy yx:(float)yx yy:(float)yy tx:(float)tx ty:(float)ty; - (void)drawWithArtboard:(RiveArtboard*)artboard; - (void)drawRive:(CGRect)rect size:(CGSize)size; +- (void)drawInRect:(CGRect)rect withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; - (bool)isPaused; - (CGPoint)artboardLocationFromTouchLocation:(CGPoint)touchLocation inArtboard:(CGRect)artboardRect fit:(RiveFit)fit alignment:(RiveAlignment)alignment; + +NS_ASSUME_NONNULL_END @end diff --git a/Source/Renderer/rive_renderer_view.mm b/Source/Renderer/rive_renderer_view.mm index c0dc1ad..20c83b3 100644 --- a/Source/Renderer/rive_renderer_view.mm +++ b/Source/Renderer/rive_renderer_view.mm @@ -71,6 +71,7 @@ [self setColorPixelFormat:MTLPixelFormatBGRA8Unorm]; [self setFramebufferOnly:_renderContext.framebufferOnly]; [self setSampleCount:1]; + return self; } @@ -104,6 +105,7 @@ [self setColorPixelFormat:MTLPixelFormatBGRA8Unorm]; [self setFramebufferOnly:_renderContext.framebufferOnly]; [self setSampleCount:1]; + return value; } @@ -161,9 +163,8 @@ return true; } -- (void)drawRect:(CGRect)rect +- (void)drawInRect:(CGRect)rect withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler { - [super drawRect:rect]; if (![[self currentDrawable] texture]) { return; @@ -176,17 +177,22 @@ [self drawRive:rect size:self.drawableSize]; _renderer->restore(); } - [_renderContext endFrame]; + [_renderContext endFrame:self withCompletion:completionHandler]; + _renderer = nil; - id commandBuffer = [_renderContext.metalQueue commandBuffer]; - [commandBuffer presentDrawable:[self currentDrawable]]; - [commandBuffer commit]; bool paused = [self isPaused]; [self setEnableSetNeedsDisplay:paused]; [self setPaused:paused]; } +- (void)drawRect:(CGRect)rect +{ + [super drawRect:rect]; + + [self drawInRect:rect withCompletion:NULL]; +} + - (rive::Fit)riveFit:(RiveFit)fit { rive::Fit riveFit; diff --git a/Source/RiveViewModel.swift b/Source/RiveViewModel.swift index 759eee9..75ba2e2 100644 --- a/Source/RiveViewModel.swift +++ b/Source/RiveViewModel.swift @@ -38,7 +38,7 @@ import Combine /// } /// } /// ``` -@objc open class RiveViewModel: NSObject, ObservableObject, RiveFileDelegate, RiveStateMachineDelegate, RivePlayerDelegate { +@objc open class RiveViewModel: NSObject, ObservableObject, RiveFileDelegate, RiveStateMachineDelegate, RivePlayerDelegate{ // TODO: could be a weak ref, need to look at this in more detail. open private(set) var riveView: RiveView? private var defaultModel: RiveModelBuffer! @@ -180,6 +180,7 @@ import Combine didSet { riveView?.fit = fit } } + open var alignment: RiveAlignment = .center { didSet { riveView?.alignment = alignment } } @@ -427,6 +428,11 @@ import Combine return view } + open func setRiveView(view:RiveView) + { + registerView(view) + } + /// Gives updated layout values to the provided `RiveView`. This is called in /// the process of re-displaying `RiveViewRepresentable`. /// - Parameter view: the `RiveView` that will be updated diff --git a/exportOptions.plist b/exportOptions.plist new file mode 100644 index 0000000..1b94ba3 --- /dev/null +++ b/exportOptions.plist @@ -0,0 +1,18 @@ + + + + + destination + export + manageAppVersionAndBuildNumber + + method + debugging + signingStyle + automatic + stripSwiftSymbols + + uploadSymbols + + + \ No newline at end of file diff --git a/golden_test_app/golden-test-app-Info.plist b/golden_test_app/golden-test-app-Info.plist new file mode 100644 index 0000000..ff579a6 --- /dev/null +++ b/golden_test_app/golden-test-app-Info.plist @@ -0,0 +1,8 @@ + + + + + UIFileSharingEnabled + + + diff --git a/golden_test_app/golden_test_app.xcodeproj/project.pbxproj b/golden_test_app/golden_test_app.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8b7fa61 --- /dev/null +++ b/golden_test_app/golden_test_app.xcodeproj/project.pbxproj @@ -0,0 +1,420 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 3E1500942BF7E017004A721C /* SingleDrawRiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E1500932BF7E017004A721C /* SingleDrawRiveView.swift */; }; + 3E3DB3532BF5449D000EAA9E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E3DB3522BF5449D000EAA9E /* ContentView.swift */; }; + 3E3DB3552BF5449D000EAA9E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3E3DB3542BF5449D000EAA9E /* Assets.xcassets */; }; + 3E3DB3592BF5449D000EAA9E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3E3DB3582BF5449D000EAA9E /* Preview Assets.xcassets */; }; + 3E409FE52BF6B481002DD778 /* RiveRendererTestViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E409FE42BF6B481002DD778 /* RiveRendererTestViews.swift */; }; + 3E8204502C13F37400D9BEA1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E82044F2C13F37400D9BEA1 /* AppDelegate.swift */; }; + 3E8204522C13F38200D9BEA1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E8204512C13F38200D9BEA1 /* SceneDelegate.swift */; }; + 3EF6A8C32BF6911300CAC54A /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EF6A8C22BF6911300CAC54A /* RiveRuntime.framework */; }; + 3EF6A8C42BF6911300CAC54A /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3EF6A8C22BF6911300CAC54A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 3EF6A8C52BF6911300CAC54A /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3EF6A8C42BF6911300CAC54A /* RiveRuntime.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 3E1500932BF7E017004A721C /* SingleDrawRiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleDrawRiveView.swift; sourceTree = ""; }; + 3E3DB34D2BF5449D000EAA9E /* golden_test_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = golden_test_app.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3E3DB3522BF5449D000EAA9E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 3E3DB3542BF5449D000EAA9E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 3E3DB3562BF5449D000EAA9E /* golden_test_app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = golden_test_app.entitlements; sourceTree = ""; }; + 3E3DB3582BF5449D000EAA9E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 3E409FE42BF6B481002DD778 /* RiveRendererTestViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveRendererTestViews.swift; sourceTree = ""; }; + 3E7419B02C01ADA9000EA71B /* golden-test-app-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "golden-test-app-Info.plist"; sourceTree = SOURCE_ROOT; }; + 3E82044F2C13F37400D9BEA1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 3E8204512C13F38200D9BEA1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 3EF6A8C22BF6911300CAC54A /* RiveRuntime.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RiveRuntime.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3E3DB34A2BF5449D000EAA9E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3EF6A8C32BF6911300CAC54A /* RiveRuntime.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3E3DB3442BF5449D000EAA9E = { + isa = PBXGroup; + children = ( + 3E3DB34F2BF5449D000EAA9E /* golden_test_app */, + 3E3DB34E2BF5449D000EAA9E /* Products */, + 3EF6A8C12BF6911300CAC54A /* Frameworks */, + ); + sourceTree = ""; + }; + 3E3DB34E2BF5449D000EAA9E /* Products */ = { + isa = PBXGroup; + children = ( + 3E3DB34D2BF5449D000EAA9E /* golden_test_app.app */, + ); + name = Products; + sourceTree = ""; + }; + 3E3DB34F2BF5449D000EAA9E /* golden_test_app */ = { + isa = PBXGroup; + children = ( + 3E82044B2C13969D00D9BEA1 /* raws */, + 3E7419B02C01ADA9000EA71B /* golden-test-app-Info.plist */, + 3E409FE42BF6B481002DD778 /* RiveRendererTestViews.swift */, + 3E3DB3522BF5449D000EAA9E /* ContentView.swift */, + 3E3DB3542BF5449D000EAA9E /* Assets.xcassets */, + 3E3DB3562BF5449D000EAA9E /* golden_test_app.entitlements */, + 3E3DB3572BF5449D000EAA9E /* Preview Content */, + 3E1500932BF7E017004A721C /* SingleDrawRiveView.swift */, + 3E82044F2C13F37400D9BEA1 /* AppDelegate.swift */, + 3E8204512C13F38200D9BEA1 /* SceneDelegate.swift */, + ); + path = golden_test_app; + sourceTree = ""; + }; + 3E3DB3572BF5449D000EAA9E /* Preview Content */ = { + isa = PBXGroup; + children = ( + 3E3DB3582BF5449D000EAA9E /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 3E82044B2C13969D00D9BEA1 /* raws */ = { + isa = PBXGroup; + children = ( + ); + path = raws; + sourceTree = ""; + }; + 3EF6A8C12BF6911300CAC54A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3EF6A8C22BF6911300CAC54A /* RiveRuntime.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 3E3DB34C2BF5449D000EAA9E /* golden_test_app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3E3DB35C2BF5449D000EAA9E /* Build configuration list for PBXNativeTarget "golden_test_app" */; + buildPhases = ( + 3E3DB3492BF5449D000EAA9E /* Sources */, + 3E3DB34A2BF5449D000EAA9E /* Frameworks */, + 3E3DB34B2BF5449D000EAA9E /* Resources */, + 3EF6A8C52BF6911300CAC54A /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = golden_test_app; + productName = golden_test_app; + productReference = 3E3DB34D2BF5449D000EAA9E /* golden_test_app.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3E3DB3452BF5449D000EAA9E /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1540; + TargetAttributes = { + 3E3DB34C2BF5449D000EAA9E = { + CreatedOnToolsVersion = 15.4; + }; + }; + }; + buildConfigurationList = 3E3DB3482BF5449D000EAA9E /* Build configuration list for PBXProject "golden_test_app" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 3E3DB3442BF5449D000EAA9E; + productRefGroup = 3E3DB34E2BF5449D000EAA9E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3E3DB34C2BF5449D000EAA9E /* golden_test_app */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3E3DB34B2BF5449D000EAA9E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3E3DB3592BF5449D000EAA9E /* Preview Assets.xcassets in Resources */, + 3E3DB3552BF5449D000EAA9E /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3E3DB3492BF5449D000EAA9E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3E1500942BF7E017004A721C /* SingleDrawRiveView.swift in Sources */, + 3E409FE52BF6B481002DD778 /* RiveRendererTestViews.swift in Sources */, + 3E3DB3532BF5449D000EAA9E /* ContentView.swift in Sources */, + 3E8204502C13F37400D9BEA1 /* AppDelegate.swift in Sources */, + 3E8204522C13F38200D9BEA1 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 3E3DB35A2BF5449D000EAA9E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 3E3DB35B2BF5449D000EAA9E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + 3E3DB35D2BF5449D000EAA9E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = golden_test_app/golden_test_app.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"golden_test_app/Preview Content\""; + DEVELOPMENT_TEAM = NJ3JMFUNS9; + ENABLE_HARDENED_RUNTIME = NO; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "golden-test-app-Info.plist"; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Write access for testing images"; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 14; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 14.3; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "rive.app.golden-test-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 3E3DB35E2BF5449D000EAA9E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = golden_test_app/golden_test_app.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"golden_test_app/Preview Content\""; + DEVELOPMENT_TEAM = NJ3JMFUNS9; + ENABLE_HARDENED_RUNTIME = NO; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "golden-test-app-Info.plist"; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Write access for testing images"; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 14; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 14.3; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "rive.app.golden-test-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3E3DB3482BF5449D000EAA9E /* Build configuration list for PBXProject "golden_test_app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3E3DB35A2BF5449D000EAA9E /* Debug */, + 3E3DB35B2BF5449D000EAA9E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3E3DB35C2BF5449D000EAA9E /* Build configuration list for PBXNativeTarget "golden_test_app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3E3DB35D2BF5449D000EAA9E /* Debug */, + 3E3DB35E2BF5449D000EAA9E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3E3DB3452BF5449D000EAA9E /* Project object */; +} diff --git a/golden_test_app/golden_test_app/AppDelegate.swift b/golden_test_app/golden_test_app/AppDelegate.swift new file mode 100644 index 0000000..a87884b --- /dev/null +++ b/golden_test_app/golden_test_app/AppDelegate.swift @@ -0,0 +1,38 @@ +// +// AppDelegate.swift +// golden_test_app +// +// Created by Jonathon Copeland on 6/7/24. +// + +import Foundation + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + let sceneConfig = UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + sceneConfig.delegateClass = SceneDelegate.self + return sceneConfig + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} diff --git a/golden_test_app/golden_test_app/Assets.xcassets/AccentColor.colorset/Contents.json b/golden_test_app/golden_test_app/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/golden_test_app/golden_test_app/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/golden_test_app/golden_test_app/Assets.xcassets/AppIcon.appiconset/Contents.json b/golden_test_app/golden_test_app/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..532cd72 --- /dev/null +++ b/golden_test_app/golden_test_app/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,63 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/golden_test_app/golden_test_app/Assets.xcassets/Contents.json b/golden_test_app/golden_test_app/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/golden_test_app/golden_test_app/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/golden_test_app/golden_test_app/ContentView.swift b/golden_test_app/golden_test_app/ContentView.swift new file mode 100644 index 0000000..79b6cf9 --- /dev/null +++ b/golden_test_app/golden_test_app/ContentView.swift @@ -0,0 +1,17 @@ +// +// ContentView.swift +// golden_test_app +// +// Created by Jonathon Copeland on 5/15/24. +// + +import SwiftUI +import RiveRuntime + +struct ContentView: View { + var body: some View { +// RiveViewRepresentable(viewModel: RiveViewModel(fileName: "dwarf")) + GoldenTestViewRepresentable() + .frame(width: 860, height: 540, alignment: .center) + } +} diff --git a/golden_test_app/golden_test_app/Preview Content/Preview Assets.xcassets/Contents.json b/golden_test_app/golden_test_app/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/golden_test_app/golden_test_app/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/golden_test_app/golden_test_app/RiveRendererTestViews.swift b/golden_test_app/golden_test_app/RiveRendererTestViews.swift new file mode 100644 index 0000000..8026a5c --- /dev/null +++ b/golden_test_app/golden_test_app/RiveRendererTestViews.swift @@ -0,0 +1,37 @@ +// +// RiveRendererTestViews.swift +// golden_test_app +// +// Created by Jonathon Copeland on 5/16/24. +// + +import SwiftUI +import RiveRuntime + +//struct FontTestView: View { +// @StateObject private var riveModel = RiveViewModel(fileName: "text") +// @Environment(\.dismiss) var dismiss +// +// var body: some View { +// SingleDrawViewRepresentable(viewModel: riveModel, dismissAction: dismiss) +// .frame(width: 860, height:540) +// } +//} +// +//struct MeshTestView: View { +// @StateObject private var riveModel = RiveViewModel(fileName: "dwarf") +// @Environment(\.dismiss) var dismiss +// var body: some View { +// SingleDrawViewRepresentable(viewModel: riveModel, dismissAction: dismiss) +// .frame(width: 860, height:540) +// } +//} +// +//struct VectorTestView: View { +// @StateObject private var riveModel = RiveViewModel(fileName: "vector") +// @Environment(\.dismiss) var dismiss +// var body: some View { +// SingleDrawViewRepresentable(viewModel: riveModel, dismissAction: dismiss) +// .frame(width: 860, height:540) +// } +//} diff --git a/golden_test_app/golden_test_app/SceneDelegate.swift b/golden_test_app/golden_test_app/SceneDelegate.swift new file mode 100644 index 0000000..b65ddad --- /dev/null +++ b/golden_test_app/golden_test_app/SceneDelegate.swift @@ -0,0 +1,53 @@ +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let windowScene = (scene as? UIWindowScene) else { return } + + // Create a window and put our SwiftUI view into it + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: ContentView()) + self.window = window + + // Show the window + window.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} diff --git a/golden_test_app/golden_test_app/SingleDrawRiveView.swift b/golden_test_app/golden_test_app/SingleDrawRiveView.swift new file mode 100644 index 0000000..faccb7e --- /dev/null +++ b/golden_test_app/golden_test_app/SingleDrawRiveView.swift @@ -0,0 +1,154 @@ +// +// SingleDrawRiveView.swift +// golden_test_app +// +// Created by Jonathon Copeland on 5/17/24. +// + +import UIKit +import SwiftUI +import RiveRuntime +import Foundation +import UniformTypeIdentifiers +import MobileCoreServices + +struct GoldenTestViewRepresentable : UIViewRepresentable { + + public init() { + } + + func makeUIView(context: Context) -> SingleDrawRiveView { + return SingleDrawRiveView() + } + + func updateUIView(_ uiView: SingleDrawRiveView, context: Context) { + + } + + public static func dismantleUIView(_ view: SingleDrawRiveView, coordinator: Coordinator) { + } + + /// Constructs a coordinator for managing updating state + public func makeCoordinator() -> Coordinator { + return Coordinator() + } + + public class Coordinator: NSObject { + + } +} + +open class SingleDrawRiveView: RiveView { + + var currentModelIndex = -1 + let modelsToRun = [/*"vector","dwarf", "text"*/] + var viewModel: RiveViewModel? + var canRender = 1 + var texture: MTLTexture?; + + public override init() { + super.init() + self.framebufferOnly = false + self.autoResizeDrawable = false + self.drawableSize = CGSizeMake(860, 540) + self.deleteLocalCache() + self.updateToNextRiveModel() + } + + public required init(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + open override func draw(in rect: CGRect, withCompletion completionHandler: MTLCommandBufferHandler? = nil) { + super.draw(in: rect){ commandBuffer in + DispatchQueue.main.async { + commandBuffer .waitUntilCompleted() + guard let texture = self.texture else { + return + } + + self.saveTexturePNG(texture: texture) + } + } + } + + open override func draw(_ rect: CGRect) { + + guard canRender > 0 else{ + return; + } + + texture = self.currentDrawable?.texture + + super.draw(rect) + + canRender -= 1; + } + + func saveTexturePNG(texture:MTLTexture){ + let options = [CIImageOption.colorSpace: CGColorSpaceCreateDeviceRGB(), + CIContextOption.outputColorSpace: true, + CIContextOption.useSoftwareRenderer: false] as! [CIImageOption : Any] + guard let ciimage = CIImage(mtlTexture: texture, options: options) else { + print("CIImage not created") + return + } + let flipped = ciimage.transformed(by: CGAffineTransform(scaleX: 1, y: -1)) + guard let cgImage = CIContext().createCGImage(flipped, + from: flipped.extent, + format: CIFormat.RGBA8, + colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!) else { + print("CGImage not created") + return + } + + guard let baseUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { + return + } + + let urlString = baseUrl.absoluteString + modelsToRun[currentModelIndex] + ".png" + guard let url = URL(string: urlString) else { + return + } + + guard let destination = CGImageDestinationCreateWithURL(url as CFURL, kUTTypePNG as CFString, 1, nil) else { + return + } + + CGImageDestinationAddImage(destination, cgImage, nil) + + if (CGImageDestinationFinalize(destination) == false){ + print("Failed to save \(url.absoluteString)" ) + } + + self.updateToNextRiveModel() + } + + func deleteLocalCache(){ + + guard let baseUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { + return + } + + for filename in self.modelsToRun { + let urlString = baseUrl.absoluteString + filename + ".png" + guard let url = URL(string: urlString) else { + continue + } + + let fs = FileManager.default + if(fs.fileExists(atPath: url.absoluteString)){ + try? fs.removeItem(at: url) + } + } + } + + func updateToNextRiveModel(){ + self.currentModelIndex += 1 + if self.currentModelIndex < self.modelsToRun.count{ + self.viewModel = RiveViewModel(fileName:self.modelsToRun[self.currentModelIndex], autoPlay: false) + try! self.setModel(self.viewModel!.riveModel!) + self.canRender = 1 + } + } +} diff --git a/golden_test_app/golden_test_app/golden_test_app.entitlements b/golden_test_app/golden_test_app/golden_test_app.entitlements new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/golden_test_app/golden_test_app/golden_test_app.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/submodules/rive-cpp b/submodules/rive-cpp index e1e125a..b9ff2f4 160000 --- a/submodules/rive-cpp +++ b/submodules/rive-cpp @@ -1 +1 @@ -Subproject commit e1e125a6595100e4cdc14def85c97d463bde23ef +Subproject commit b9ff2f46d709334d506ec4a769520b153908b014