diff --git a/.github/workflows/Package.swift.template b/.github/workflows/Package.swift.template index 623c0d5..fe50445 100644 --- a/.github/workflows/Package.swift.template +++ b/.github/workflows/Package.swift.template @@ -3,7 +3,7 @@ import PackageDescription let package = Package( name: "RiveRuntime", - platforms: [.iOS("14.0"), .macOS("13.1")], + platforms: [.iOS("14.0"), .visionOS("1.0"), .tvOS("16.0"), .macOS("13.1")], products: [ .library( name: "RiveRuntime", diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bf45e7b..802a873 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -88,6 +88,9 @@ jobs: - name: Select Xcode 15.4 run: sudo xcodes select 15.4 + + - name: Install all Xcode platforms + run: xcodebuild -downloadAllPlatforms - name: Build everything (using the cache, we should make an archive of course) run: ./scripts/build.sh all diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 15aa4c5..8a352fe 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,9 +40,23 @@ jobs: - name: Select Xcode 15.4 run: sudo xcodes select 15.4 - - name: Build everything (using the cache, we should make an archive of course) + - name: Build for iOS Simulator (using the cache, we should make an archive of course) run: | ./scripts/build.sh ios_sim release - - name: Testing iOS app - run: ./scripts/test.sh + - name: Test iOS runtime + run: ./scripts/test.sh ios_sim + + - name: Build for visionOS Simulator (using the cache, we should make an archive of course) + run: | + ./scripts/build.sh xrsimulator release + + - name: Test visionOS runtime + run: ./scripts/test.sh xrsimulator + + - name: Build for tvOS Simulator (using the cache, we should make an archive of course) + run: | + ./scripts/build.sh appletvsimulator release + + - name: Test tvOS runtime + run: ./scripts/test.sh appletvsimulator diff --git a/.rive_head b/.rive_head index 4fa06ac..5d21927 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f69757c8dd221c54942fee2e47bae55df8f6dc12 +6f70a0e803b1eaf43374b98cc4fda6e79163667d diff --git a/Example-iOS/Assets/streaming.riv b/Example-iOS/Assets/streaming.riv new file mode 100644 index 0000000..f62d8bd Binary files /dev/null and b/Example-iOS/Assets/streaming.riv differ diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..2e00335 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,11 @@ +{ + "images" : [ + { + "idiom" : "tv" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json new file mode 100644 index 0000000..de59d88 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.imagestacklayer" + }, + { + "filename" : "Middle.imagestacklayer" + }, + { + "filename" : "Back.imagestacklayer" + } + ] +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..2e00335 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,11 @@ +{ + "images" : [ + { + "idiom" : "tv" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..2e00335 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,11 @@ +{ + "images" : [ + { + "idiom" : "tv" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..795cce1 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "tv", + "scale" : "1x" + }, + { + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json new file mode 100644 index 0000000..de59d88 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.imagestacklayer" + }, + { + "filename" : "Middle.imagestacklayer" + }, + { + "filename" : "Back.imagestacklayer" + } + ] +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..795cce1 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "tv", + "scale" : "1x" + }, + { + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..795cce1 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "tv", + "scale" : "1x" + }, + { + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json new file mode 100644 index 0000000..f47ba43 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json @@ -0,0 +1,32 @@ +{ + "assets" : [ + { + "filename" : "App Icon - App Store.imagestack", + "idiom" : "tv", + "role" : "primary-app-icon", + "size" : "1280x768" + }, + { + "filename" : "App Icon.imagestack", + "idiom" : "tv", + "role" : "primary-app-icon", + "size" : "400x240" + }, + { + "filename" : "Top Shelf Image Wide.imageset", + "idiom" : "tv", + "role" : "top-shelf-image-wide", + "size" : "2320x720" + }, + { + "filename" : "Top Shelf Image.imageset", + "idiom" : "tv", + "role" : "top-shelf-image", + "size" : "1920x720" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json new file mode 100644 index 0000000..795cce1 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "tv", + "scale" : "1x" + }, + { + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json new file mode 100644 index 0000000..795cce1 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "tv", + "scale" : "1x" + }, + { + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (tvOS)/ContentView.swift b/Example-iOS/Example (tvOS)/ContentView.swift new file mode 100644 index 0000000..443c7b3 --- /dev/null +++ b/Example-iOS/Example (tvOS)/ContentView.swift @@ -0,0 +1,107 @@ +// +// ContentView.swift +// Example (tvOS) +// +// Created by David Skuza on 10/29/24. +// Copyright © 2024 Rive. All rights reserved. +// + +import SwiftUI +import UIKit +import RiveRuntime + +class ContentViewModel: ObservableObject { + struct State: Equatable { + let first: Bool + let big: Bool + + init(first: Bool = true, big: Bool = true) { + self.first = first + self.big = big + } + } + + private let rive: RiveViewModel + private var state = State() { + didSet { + rive.setInput("Big", value: state.big) + rive.setInput("First", value: state.first) + } + } + + init(rive: RiveViewModel) { + self.rive = rive + } + + func start() { + let upGesture = UITapGestureRecognizer(target: self, action: #selector(up)) + let up = UIPress.PressType.upArrow + upGesture.allowedPressTypes = [NSNumber(integerLiteral: up.rawValue)] + rive.riveView?.addGestureRecognizer(upGesture) + + let downGesture = UITapGestureRecognizer(target: self, action: #selector(down)) + let down = UIPress.PressType.downArrow + downGesture.allowedPressTypes = [NSNumber(integerLiteral: down.rawValue)] + rive.riveView?.addGestureRecognizer(downGesture) + + let leftGesture = UITapGestureRecognizer(target: self, action: #selector(left)) + let left = UIPress.PressType.leftArrow + leftGesture.allowedPressTypes = [NSNumber(integerLiteral: left.rawValue)] + rive.riveView?.addGestureRecognizer(leftGesture) + + let rightGesture = UITapGestureRecognizer(target: self, action: #selector(right)) + let right = UIPress.PressType.rightArrow + rightGesture.allowedPressTypes = [NSNumber(integerLiteral: right.rawValue)] + rive.riveView?.addGestureRecognizer(rightGesture) + } + + @objc func up() { + let newState = State(first: state.first, big: true) + guard newState != state else { return } + state = newState + } + + @objc func down() { + let newState = State(first: state.first, big: false) + guard newState != state else { return } + state = newState + } + + @objc func left() { + let newState = State(first: true, big: state.big) + guard newState != state else { return } + state = newState + + } + + @objc func right() { + let newState = State(first: false, big: state.big) + guard newState != state else { return } + state = newState + } +} + +struct ContentView: View { + @StateObject var rive: RiveViewModel + @StateObject var viewModel: ContentViewModel + + init() { + let rive = RiveViewModel(fileName: "streaming") + _rive = StateObject(wrappedValue: rive) + + let viewModel = ContentViewModel(rive: rive) + _viewModel = StateObject(wrappedValue: viewModel) + } + + var body: some View { + rive + .view() + .onAppear { + viewModel.start() + } + } +} + +#Preview { + ContentView() +} diff --git a/Example-iOS/Example (tvOS)/Example__tvOS_App.swift b/Example-iOS/Example (tvOS)/Example__tvOS_App.swift new file mode 100644 index 0000000..466af92 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Example__tvOS_App.swift @@ -0,0 +1,18 @@ +// +// Example__tvOS_App.swift +// Example (tvOS) +// +// Created by David Skuza on 10/29/24. +// Copyright © 2024 Rive. All rights reserved. +// + +import SwiftUI + +@main +struct Example__tvOS_App: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Example-iOS/Example (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json b/Example-iOS/Example (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Contents.json new file mode 100644 index 0000000..950af4d --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.solidimagestacklayer" + }, + { + "filename" : "Middle.solidimagestacklayer" + }, + { + "filename" : "Back.solidimagestacklayer" + } + ] +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example-iOS/Example (visionOS)/ContentView.swift b/Example-iOS/Example (visionOS)/ContentView.swift new file mode 100644 index 0000000..66caccd --- /dev/null +++ b/Example-iOS/Example (visionOS)/ContentView.swift @@ -0,0 +1,22 @@ +// +// ContentView.swift +// Example (visionOS) +// +// Created by David Skuza on 10/25/24. +// Copyright © 2024 Rive. All rights reserved. +// + +import SwiftUI +import RiveRuntime + +struct ContentView: View { + @StateObject var viewModel = RiveViewModel(fileName: "streaming", fit: .fill) + + var body: some View { + viewModel.view() + } +} + +#Preview(windowStyle: .automatic) { + ContentView() +} diff --git a/Example-iOS/Example (visionOS)/Example__visionOS_App.swift b/Example-iOS/Example (visionOS)/Example__visionOS_App.swift new file mode 100644 index 0000000..01d14a5 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Example__visionOS_App.swift @@ -0,0 +1,18 @@ +// +// Example__visionOS_App.swift +// Example (visionOS) +// +// Created by David Skuza on 10/25/24. +// Copyright © 2024 Rive. All rights reserved. +// + +import SwiftUI + +@main +struct Example__visionOS_App: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Example-iOS/Example (visionOS)/Info.plist b/Example-iOS/Example (visionOS)/Info.plist new file mode 100644 index 0000000..20f75e2 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Info.plist @@ -0,0 +1,15 @@ + + + + + UIApplicationSceneManifest + + UIApplicationPreferredDefaultSceneSessionRole + UIWindowSceneSessionRoleApplication + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + + + diff --git a/Example-iOS/Example (visionOS)/Preview Content/Preview Assets.xcassets/Contents.json b/Example-iOS/Example (visionOS)/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example-iOS/Example (visionOS)/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json new file mode 100644 index 0000000..4a8c74b --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json @@ -0,0 +1,11 @@ +{ + "pathsToIds" : { + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "440DE5B4-E4E4-459B-AABF-9ACE96319272", + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "34C460AE-CA1B-4348-BD05-621ACBDFFE97", + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Untitled Scene.usda" : "03E02005-EFA6-48D6-8A76-05B2822A74E9", + "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "FBD8436F-6B8B-4B82-99B5-995D538B4704", + "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "1CBF3893-ABFD-408C-8B91-045BFD257808", + "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "26DBAE76-5DD8-47B6-A085-1B4ADA111097" + } +} \ No newline at end of file diff --git a/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json new file mode 100644 index 0000000..1d84a75 --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json @@ -0,0 +1,209 @@ +{ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C" : { + "cameraTransform" : [ + 0.9807314, + -1.9820146e-10, + -0.195361, + 0, + -0.10051192, + 0.85749435, + -0.5045798, + 0, + 0.16752096, + 0.51449335, + 0.84097165, + 0, + 0.09084191, + 0.05849296, + 0.13903293, + 1 + ], + "objectMetadataList" : [ + [ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + }, + [ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "Root", + "GridMaterial" + ], + { + "isExpanded" : true, + "isLocked" : false + }, + [ + "0A9B4653-B11E-4D6A-850E-C6FCB621626C", + "Root", + "Sphere" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + }, + "1CBF3893-ABFD-408C-8B91-045BFD257808" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660255, + -0.49999988, + 0, + 0, + 0.49999988, + 0.8660255, + 0, + 0, + 0.27093542, + 0.46927398, + 1 + ], + "objectMetadataList" : [ + + ] + }, + "03E02005-EFA6-48D6-8A76-05B2822A74E9" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660254, + -0.49999994, + 0, + 0, + 0.49999994, + 0.8660254, + 0, + 0, + 0.5981957, + 1.0361054, + 1 + ], + "objectMetadataList" : [ + + ] + }, + "26DBAE76-5DD8-47B6-A085-1B4ADA111097" : { + "cameraTransform" : [ + 1, + 0, + -0, + 0, + -0, + 0.7071069, + -0.7071067, + 0, + 0, + 0.7071067, + 0.7071069, + 0, + 0, + 0.2681068, + 0.26850593, + 1 + ], + "objectMetadataList" : [ + [ + "26DBAE76-5DD8-47B6-A085-1B4ADA111097", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + }, + "34C460AE-CA1B-4348-BD05-621ACBDFFE97" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660255, + -0.49999988, + 0, + 0, + 0.49999988, + 0.8660255, + 0, + 0, + 0.27093542, + 0.46927398, + 1 + ], + "objectMetadataList" : [ + + ] + }, + "440DE5B4-E4E4-459B-AABF-9ACE96319272" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660254, + -0.49999994, + 0, + 0, + 0.49999994, + 0.8660254, + 0, + 0, + 0.5981957, + 1.0361054, + 1 + ], + "objectMetadataList" : [ + [ + "440DE5B4-E4E4-459B-AABF-9ACE96319272", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + }, + "FBD8436F-6B8B-4B82-99B5-995D538B4704" : { + "cameraTransform" : [ + 0.99999994, + 0, + -0, + 0, + -0, + 0.8660254, + -0.49999994, + 0, + 0, + 0.49999994, + 0.8660254, + 0, + 0, + 0.5981957, + 1.0361054, + 1 + ], + "objectMetadataList" : [ + [ + "FBD8436F-6B8B-4B82-99B5-995D538B4704", + "Root" + ], + { + "isExpanded" : true, + "isLocked" : false + } + ] + } +} \ No newline at end of file diff --git a/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata new file mode 100644 index 0000000..6dea95c --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata @@ -0,0 +1,17 @@ +{ + "cameraPresets" : { + + }, + "secondaryToolbarData" : { + "isGridVisible" : true, + "sceneReverbPreset" : -1 + }, + "unitDefaults" : { + "°" : "°", + "kg" : "g", + "m" : "cm", + "m\/s" : "m\/s", + "m\/s²" : "m\/s²", + "s" : "s" + } +} \ No newline at end of file diff --git a/Example-iOS/Packages/RealityKitContent/Package.swift b/Example-iOS/Packages/RealityKitContent/Package.swift new file mode 100644 index 0000000..d043ae1 --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Package.swift @@ -0,0 +1,25 @@ +// swift-tools-version:5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "RealityKitContent", + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "RealityKitContent", + targets: ["RealityKitContent"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "RealityKitContent", + dependencies: []), + ] +) \ No newline at end of file diff --git a/Example-iOS/Packages/RealityKitContent/README.md b/Example-iOS/Packages/RealityKitContent/README.md new file mode 100644 index 0000000..486b575 --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/README.md @@ -0,0 +1,3 @@ +# RealityKitContent + +A description of this package. \ No newline at end of file diff --git a/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda new file mode 100644 index 0000000..b7afd02 --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda @@ -0,0 +1,216 @@ +#usda 1.0 +( + defaultPrim = "Root" + metersPerUnit = 1 + upAxis = "Y" +) + +def Xform "Root" +{ + def Material "GridMaterial" + { + reorder nameChildren = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "DefaultSurfaceShader", "MaterialXPreviewSurface", "Texcoord", "Add", "Multiply", "Fractional", "LineCounts", "Multiply_1", "Separate2", "Separate2_1", "Ifgreater", "Ifgreater_1", "Max", "Background_Color"] + token outputs:mtlx:surface.connect = + token outputs:realitykit:vertex + token outputs:surface + float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (2222, 300.5) + float2 ui:nodegraph:realitykit:subgraphOutputs:size = (182, 89) + int ui:nodegraph:realitykit:subgraphOutputs:stackingOrder = 749 + + def Shader "DefaultSurfaceShader" + { + uniform token info:id = "UsdPreviewSurface" + color3f inputs:diffuseColor = (1, 1, 1) + float inputs:roughness = 0.75 + token outputs:surface + } + + def Shader "MaterialXPreviewSurface" + { + uniform token info:id = "ND_UsdPreviewSurface_surfaceshader" + float inputs:clearcoat + float inputs:clearcoatRoughness + color3f inputs:diffuseColor.connect = + color3f inputs:emissiveColor + float inputs:ior + float inputs:metallic = 0.15 + float3 inputs:normal + float inputs:occlusion + float inputs:opacity + float inputs:opacityThreshold + float inputs:roughness = 0.5 + token outputs:out + float2 ui:nodegraph:node:pos = (1967, 300.5) + float2 ui:nodegraph:node:size = (208, 297) + int ui:nodegraph:node:stackingOrder = 870 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["Advanced"] + } + + def Shader "Texcoord" + { + uniform token info:id = "ND_texcoord_vector2" + float2 outputs:out + float2 ui:nodegraph:node:pos = (94.14453, 35.29297) + float2 ui:nodegraph:node:size = (182, 43) + int ui:nodegraph:node:stackingOrder = 1358 + } + + def Shader "Multiply" + { + uniform token info:id = "ND_multiply_vector2" + float2 inputs:in1.connect = + float2 inputs:in2 = (32, 15) + float2 inputs:in2.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (275.64453, 47.29297) + float2 ui:nodegraph:node:size = (61, 36) + int ui:nodegraph:node:stackingOrder = 1348 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:in2"] + } + + def Shader "Fractional" + { + uniform token info:id = "ND_realitykit_fractional_vector2" + float2 inputs:in.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (440.5, 49.5) + float2 ui:nodegraph:node:size = (155, 99) + int ui:nodegraph:node:stackingOrder = 1345 + } + + def Shader "BaseColor" + { + uniform token info:id = "ND_constant_color3" + color3f inputs:value = (0.89737034, 0.89737034, 0.89737034) ( + colorSpace = "Input - Texture - sRGB - sRGB" + ) + color3f inputs:value.connect = None + color3f outputs:out + float2 ui:nodegraph:node:pos = (1537.5977, 363.07812) + float2 ui:nodegraph:node:size = (150, 43) + int ui:nodegraph:node:stackingOrder = 1353 + } + + def Shader "LineColor" + { + uniform token info:id = "ND_constant_color3" + color3f inputs:value = (0.55945957, 0.55945957, 0.55945957) ( + colorSpace = "Input - Texture - sRGB - sRGB" + ) + color3f inputs:value.connect = None + color3f outputs:out + float2 ui:nodegraph:node:pos = (1536.9844, 287.86328) + float2 ui:nodegraph:node:size = (146, 43) + int ui:nodegraph:node:stackingOrder = 1355 + } + + def Shader "LineWidths" + { + uniform token info:id = "ND_combine2_vector2" + float inputs:in1 = 0.1 + float inputs:in2 = 0.1 + float2 outputs:out + float2 ui:nodegraph:node:pos = (443.64453, 233.79297) + float2 ui:nodegraph:node:size = (151, 43) + int ui:nodegraph:node:stackingOrder = 1361 + } + + def Shader "LineCounts" + { + uniform token info:id = "ND_combine2_vector2" + float inputs:in1 = 24 + float inputs:in2 = 12 + float2 outputs:out + float2 ui:nodegraph:node:pos = (94.14453, 138.29297) + float2 ui:nodegraph:node:size = (153, 43) + int ui:nodegraph:node:stackingOrder = 1359 + } + + def Shader "Remap" + { + uniform token info:id = "ND_remap_color3" + color3f inputs:in.connect = + color3f inputs:inhigh.connect = None + color3f inputs:inlow.connect = None + color3f inputs:outhigh.connect = + color3f inputs:outlow.connect = + color3f outputs:out + float2 ui:nodegraph:node:pos = (1755.5, 300.5) + float2 ui:nodegraph:node:size = (95, 171) + int ui:nodegraph:node:stackingOrder = 1282 + string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:outlow"] + } + + def Shader "Separate2" + { + uniform token info:id = "ND_separate2_vector2" + float2 inputs:in.connect = + float outputs:outx + float outputs:outy + float2 ui:nodegraph:node:pos = (1212.6445, 128.91797) + float2 ui:nodegraph:node:size = (116, 117) + int ui:nodegraph:node:stackingOrder = 1363 + } + + def Shader "Combine3" + { + uniform token info:id = "ND_combine3_color3" + float inputs:in1.connect = + float inputs:in2.connect = + float inputs:in3.connect = + color3f outputs:out + float2 ui:nodegraph:node:pos = (1578.1445, 128.91797) + float2 ui:nodegraph:node:size = (146, 54) + int ui:nodegraph:node:stackingOrder = 1348 + } + + def Shader "Range" + { + uniform token info:id = "ND_range_vector2" + bool inputs:doclamp = 1 + float2 inputs:gamma = (2, 2) + float2 inputs:in.connect = + float2 inputs:inhigh.connect = + float2 inputs:inlow = (0.02, 0.02) + float2 inputs:outhigh + float2 inputs:outlow + float2 outputs:out + float2 ui:nodegraph:node:pos = (990.64453, 128.91797) + float2 ui:nodegraph:node:size = (98, 207) + int ui:nodegraph:node:stackingOrder = 1364 + } + + def Shader "Subtract" + { + uniform token info:id = "ND_subtract_vector2" + float2 inputs:in1.connect = + float2 inputs:in2.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (612.64453, 87.04297) + float2 ui:nodegraph:node:size = (63, 36) + int ui:nodegraph:node:stackingOrder = 1348 + } + + def Shader "Absval" + { + uniform token info:id = "ND_absval_vector2" + float2 inputs:in.connect = + float2 outputs:out + float2 ui:nodegraph:node:pos = (765.64453, 87.04297) + float2 ui:nodegraph:node:size = (123, 43) + int ui:nodegraph:node:stackingOrder = 1348 + } + + def Shader "Min" + { + uniform token info:id = "ND_min_float" + float inputs:in1.connect = + float inputs:in2.connect = + float outputs:out + float2 ui:nodegraph:node:pos = (1388.1445, 128.91797) + float2 ui:nodegraph:node:size = (114, 36) + int ui:nodegraph:node:stackingOrder = 1363 + } + } +} + diff --git a/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda new file mode 100644 index 0000000..4cb070b --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda @@ -0,0 +1,59 @@ +#usda 1.0 +( + defaultPrim = "Root" + metersPerUnit = 1 + upAxis = "Y" +) + +def Xform "Root" +{ + reorder nameChildren = ["GridMaterial", "Sphere"] + rel material:binding = None ( + bindMaterialAs = "weakerThanDescendants" + ) + + def Sphere "Sphere" ( + active = true + prepend apiSchemas = ["MaterialBindingAPI"] + ) + { + rel material:binding = ( + bindMaterialAs = "weakerThanDescendants" + ) + double radius = 0.05 + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + float3 xformOp:translate = (0, 0, 0.0004) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def RealityKitComponent "Collider" + { + uint group = 1 + uniform token info:id = "RealityKit.Collider" + uint mask = 4294967295 + token type = "Default" + + def RealityKitStruct "Shape" + { + float3 extent = (0.2, 0.2, 0.2) + float radius = 0.05 + token shapeType = "Sphere" + } + } + + def RealityKitComponent "InputTarget" + { + uniform token info:id = "RealityKit.InputTarget" + } + } + + def "GridMaterial" ( + active = true + prepend references = @Materials/GridMaterial.usda@ + ) + { + float3 xformOp:scale = (1, 1, 1) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } +} + diff --git a/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift new file mode 100644 index 0000000..5caba4e --- /dev/null +++ b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift @@ -0,0 +1,4 @@ +import Foundation + +/// Bundle for the RealityKitContent project +public let realityKitContentBundle = Bundle.module diff --git a/Example-iOS/RiveExample.xcodeproj/project.pbxproj b/Example-iOS/RiveExample.xcodeproj/project.pbxproj index 7d1408f..de5afdb 100644 --- a/Example-iOS/RiveExample.xcodeproj/project.pbxproj +++ b/Example-iOS/RiveExample.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 55; objects = { /* Begin PBXBuildFile section */ @@ -210,8 +210,8 @@ 049091642BC948AA00F2C12B /* SwiftOutOfBandAudioAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049091622BC948AA00F2C12B /* SwiftOutOfBandAudioAssets.swift */; }; 04C4C83E2646FE410047E614 /* StateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C4C83D2646FE410047E614 /* StateMachine.swift */; }; 04D5B06C266A460C004ACA5B /* nothing.riv in Resources */ = {isa = PBXBuildFile; fileRef = 04D5B069266A460C004ACA5B /* nothing.riv */; }; - 04DB5937266A348C0020A7E8 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; }; - 04DB5938266A348C0020A7E8 /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 04DB5937266A348C0020A7E8 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; platformFilters = (ios, xros, ); }; + 04DB5938266A348C0020A7E8 /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; platformFilters = (ios, xros, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 04E51C362A151A1E0075E473 /* Example__macOS_App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E51C352A151A1E0075E473 /* Example__macOS_App.swift */; }; 04E51C382A151A1E0075E473 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E51C372A151A1E0075E473 /* ContentView.swift */; }; 04E51C3A2A151A1F0075E473 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04E51C392A151A1F0075E473 /* Assets.xcassets */; }; @@ -320,10 +320,26 @@ E5B5C2192B238829006E57C8 /* asset_load_check.riv in Resources */ = {isa = PBXBuildFile; fileRef = E5B5C2172B238829006E57C8 /* asset_load_check.riv */; }; E5CD7D7127DC331900BFE5E2 /* SwiftMeshAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5CD7D7027DC331900BFE5E2 /* SwiftMeshAnimation.swift */; }; E5E87A012AE5A83800E7295F /* SwiftVariableFPS.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E87A002AE5A83700E7295F /* SwiftVariableFPS.swift */; }; + F221387F2CCBEDD400A25BA7 /* Example__visionOS_App.swift in Sources */ = {isa = PBXBuildFile; fileRef = F221387E2CCBEDD400A25BA7 /* Example__visionOS_App.swift */; }; + F22138812CCBEDD400A25BA7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F22138802CCBEDD400A25BA7 /* ContentView.swift */; }; + F22138832CCBEDD500A25BA7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F22138822CCBEDD500A25BA7 /* Assets.xcassets */; }; + F22138862CCBEDD500A25BA7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */; }; + F221388B2CCBEDE100A25BA7 /* marty.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89ACE2988709400044C17 /* marty.riv */; }; + F26E20AC2CF0E21000130111 /* streaming.riv in Resources */ = {isa = PBXBuildFile; fileRef = F26E20A92CF0E21000130111 /* streaming.riv */; }; + F2AB95D12CF0EB800055376E /* streaming.riv in Resources */ = {isa = PBXBuildFile; fileRef = F26E20A92CF0E21000130111 /* streaming.riv */; }; + F2AC7F3C2CCBEEDC00E3ED79 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; }; + F2AC7F3D2CCBEEDC00E3ED79 /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; F2C623362C874E3A0006E0CA /* fallback_fonts.riv in Resources */ = {isa = PBXBuildFile; fileRef = F2C623352C874E3A0006E0CA /* fallback_fonts.riv */; }; F2C623372C874E3A0006E0CA /* fallback_fonts.riv in Resources */ = {isa = PBXBuildFile; fileRef = F2C623352C874E3A0006E0CA /* fallback_fonts.riv */; }; F2C623392C874E690006E0CA /* SwiftFallbackFonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */; }; F2C6233A2C874E690006E0CA /* SwiftFallbackFonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */; }; + F2C852D42CD1772300F0D81F /* Example__tvOS_App.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */; }; + F2C852D62CD1772300F0D81F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C852D52CD1772300F0D81F /* ContentView.swift */; }; + F2C852D82CD1772400F0D81F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2C852D72CD1772400F0D81F /* Assets.xcassets */; }; + F2C852DB2CD1772400F0D81F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */; }; + F2C852EB2CD17B8200F0D81F /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; }; + F2C852EC2CD17B8200F0D81F /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F2C852F22CD19F6A00F0D81F /* marty.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89ACE2988709400044C17 /* marty.riv */; }; F8772AF02AD94A4400AB5920 /* marty.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89ACE2988709400044C17 /* marty.riv */; }; F8772AF12AD94A4400AB5920 /* paper.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89AD0298870A700044C17 /* paper.riv */; }; F8772AF22AD94A4400AB5920 /* Bear.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83DE4CB42AB3974300B88B72 /* Bear.riv */; }; @@ -371,6 +387,28 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + F2AC7F3E2CCBEEDC00E3ED79 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F2AC7F3D2CCBEEDC00E3ED79 /* RiveRuntime.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F2C852ED2CD17B8200F0D81F /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F2C852EC2CD17B8200F0D81F /* RiveRuntime.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -481,8 +519,21 @@ E5B5C2172B238829006E57C8 /* asset_load_check.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = asset_load_check.riv; sourceTree = ""; }; E5CD7D7027DC331900BFE5E2 /* SwiftMeshAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftMeshAnimation.swift; sourceTree = ""; }; E5E87A002AE5A83700E7295F /* SwiftVariableFPS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftVariableFPS.swift; sourceTree = ""; }; + F221387A2CCBEDD400A25BA7 /* Example (visionOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example (visionOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; + F221387E2CCBEDD400A25BA7 /* Example__visionOS_App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example__visionOS_App.swift; sourceTree = ""; }; + F22138802CCBEDD400A25BA7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + F22138822CCBEDD500A25BA7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + F22138872CCBEDD500A25BA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F26E20A92CF0E21000130111 /* streaming.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = streaming.riv; sourceTree = ""; }; + F2B7F2F72C5AC09200F47FBC /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = ""; }; F2C623352C874E3A0006E0CA /* fallback_fonts.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = fallback_fonts.riv; sourceTree = ""; }; F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftFallbackFonts.swift; sourceTree = ""; }; + F2C852D12CD1772300F0D81F /* Example (tvOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example (tvOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; + F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example__tvOS_App.swift; sourceTree = ""; }; + F2C852D52CD1772300F0D81F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + F2C852D72CD1772400F0D81F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; F8DA7B442AF523A800FF3CBF /* DismissableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissableView.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -519,6 +570,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F22138772CCBEDD400A25BA7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F2AC7F3C2CCBEEDC00E3ED79 /* RiveRuntime.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F2C852CE2CD1772300F0D81F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F2C852EB2CD17B8200F0D81F /* RiveRuntime.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -600,6 +667,7 @@ C9696B0E24FC6FD10041502A /* Assets */ = { isa = PBXGroup; children = ( + F26E20A92CF0E21000130111 /* streaming.riv */, 2E974F942CB3509200642588 /* layout_test.riv */, F2C623352C874E3A0006E0CA /* fallback_fonts.riv */, 2E83910C2C050BC4003BCF2A /* runtime_nested_inputs.riv */, @@ -694,6 +762,9 @@ C9696B0E24FC6FD10041502A /* Assets */, C9C73E9624FC471E00EF9516 /* Source */, 04E51C342A151A1E0075E473 /* Example (macOS) */, + F2B7F2F62C5AC09200F47FBC /* Packages */, + F221387B2CCBEDD400A25BA7 /* Example (visionOS) */, + F2C852D22CD1772300F0D81F /* Example (tvOS) */, C9C73E9524FC471E00EF9516 /* Products */, C9C741FF24FC53CF00EF9516 /* Frameworks */, ); @@ -706,6 +777,8 @@ 04E51C332A151A1E0075E473 /* Example (macOS).app */, 040553C72B7A274B008F076A /* Preview (macOS).app */, 040554302B7A2858008F076A /* Preview (iOS).app */, + F221387A2CCBEDD400A25BA7 /* Example (visionOS).app */, + F2C852D12CD1772300F0D81F /* Example (tvOS).app */, ); name = Products; sourceTree = ""; @@ -743,6 +816,53 @@ name = Frameworks; sourceTree = ""; }; + F221387B2CCBEDD400A25BA7 /* Example (visionOS) */ = { + isa = PBXGroup; + children = ( + F221387E2CCBEDD400A25BA7 /* Example__visionOS_App.swift */, + F22138802CCBEDD400A25BA7 /* ContentView.swift */, + F22138822CCBEDD500A25BA7 /* Assets.xcassets */, + F22138872CCBEDD500A25BA7 /* Info.plist */, + F22138842CCBEDD500A25BA7 /* Preview Content */, + ); + path = "Example (visionOS)"; + sourceTree = ""; + }; + F22138842CCBEDD500A25BA7 /* Preview Content */ = { + isa = PBXGroup; + children = ( + F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + F2B7F2F62C5AC09200F47FBC /* Packages */ = { + isa = PBXGroup; + children = ( + F2B7F2F72C5AC09200F47FBC /* RealityKitContent */, + ); + path = Packages; + sourceTree = ""; + }; + F2C852D22CD1772300F0D81F /* Example (tvOS) */ = { + isa = PBXGroup; + children = ( + F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */, + F2C852D52CD1772300F0D81F /* ContentView.swift */, + F2C852D72CD1772400F0D81F /* Assets.xcassets */, + F2C852D92CD1772400F0D81F /* Preview Content */, + ); + path = "Example (tvOS)"; + sourceTree = ""; + }; + F2C852D92CD1772400F0D81F /* Preview Content */ = { + isa = PBXGroup; + children = ( + F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -822,13 +942,51 @@ productReference = C9C73E9424FC471E00EF9516 /* Example (iOS).app */; productType = "com.apple.product-type.application"; }; + F22138792CCBEDD400A25BA7 /* Example (visionOS) */ = { + isa = PBXNativeTarget; + buildConfigurationList = F22138882CCBEDD500A25BA7 /* Build configuration list for PBXNativeTarget "Example (visionOS)" */; + buildPhases = ( + F22138762CCBEDD400A25BA7 /* Sources */, + F22138772CCBEDD400A25BA7 /* Frameworks */, + F22138782CCBEDD400A25BA7 /* Resources */, + F2AC7F3E2CCBEEDC00E3ED79 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Example (visionOS)"; + packageProductDependencies = ( + ); + productName = "Example (visionOS)"; + productReference = F221387A2CCBEDD400A25BA7 /* Example (visionOS).app */; + productType = "com.apple.product-type.application"; + }; + F2C852D02CD1772300F0D81F /* Example (tvOS) */ = { + isa = PBXNativeTarget; + buildConfigurationList = F2C852DC2CD1772400F0D81F /* Build configuration list for PBXNativeTarget "Example (tvOS)" */; + buildPhases = ( + F2C852CD2CD1772300F0D81F /* Sources */, + F2C852CE2CD1772300F0D81F /* Frameworks */, + F2C852CF2CD1772300F0D81F /* Resources */, + F2C852ED2CD17B8200F0D81F /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Example (tvOS)"; + productName = "Example (tvOS)"; + productReference = F2C852D12CD1772300F0D81F /* Example (tvOS).app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ C9C73E8C24FC471E00EF9516 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1500; + LastSwiftUpdateCheck = 1540; LastUpgradeCheck = 1310; ORGANIZATIONNAME = Rive; TargetAttributes = { @@ -838,6 +996,12 @@ C9C73E9324FC471E00EF9516 = { CreatedOnToolsVersion = 11.6; }; + F22138792CCBEDD400A25BA7 = { + CreatedOnToolsVersion = 15.4; + }; + F2C852D02CD1772300F0D81F = { + CreatedOnToolsVersion = 15.4; + }; }; }; buildConfigurationList = C9C73E8F24FC471E00EF9516 /* Build configuration list for PBXProject "RiveExample" */; @@ -866,6 +1030,8 @@ 040553822B7A274B008F076A /* Preview (macOS) */, C9C73E9324FC471E00EF9516 /* Example (iOS) */, 04E51C322A151A1E0075E473 /* Example (macOS) */, + F22138792CCBEDD400A25BA7 /* Example (visionOS) */, + F2C852D02CD1772300F0D81F /* Example (tvOS) */, ); }; /* End PBXProject section */ @@ -1154,6 +1320,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F22138782CCBEDD400A25BA7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F221388B2CCBEDE100A25BA7 /* marty.riv in Resources */, + F22138862CCBEDD500A25BA7 /* Preview Assets.xcassets in Resources */, + F26E20AC2CF0E21000130111 /* streaming.riv in Resources */, + F22138832CCBEDD500A25BA7 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F2C852CF2CD1772300F0D81F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F2C852F22CD19F6A00F0D81F /* marty.riv in Resources */, + F2C852DB2CD1772400F0D81F /* Preview Assets.xcassets in Resources */, + F2AB95D12CF0EB800055376E /* streaming.riv in Resources */, + F2C852D82CD1772400F0D81F /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1263,6 +1451,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F22138762CCBEDD400A25BA7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F22138812CCBEDD400A25BA7 /* ContentView.swift in Sources */, + F221387F2CCBEDD400A25BA7 /* Example__visionOS_App.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F2C852CD2CD1772300F0D81F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F2C852D62CD1772300F0D81F /* ContentView.swift in Sources */, + F2C852D42CD1772300F0D81F /* Example__tvOS_App.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ @@ -1550,7 +1756,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "\"Source/Preview Content\""; - DEVELOPMENT_TEAM = NJ3JMFUNS9; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = Source/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -1560,8 +1766,11 @@ ); PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.RiveExample; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; }; name = Debug; }; @@ -1571,7 +1780,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "\"Source/Preview Content\""; - DEVELOPMENT_TEAM = NJ3JMFUNS9; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = Source/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -1581,8 +1790,145 @@ ); PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.RiveExample; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Release; + }; + F22138892CCBEDD500A25BA7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Example (visionOS)/Preview Content\""; + DEVELOPMENT_TEAM = 8N4K3S3FJ4; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "app.rive.Example--visionOS-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Debug; + }; + F221388A2CCBEDD500A25BA7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Example (visionOS)/Preview Content\""; + DEVELOPMENT_TEAM = 8N4K3S3FJ4; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "app.rive.Example--visionOS-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Release; + }; + F2C852DD2CD1772400F0D81F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Example (tvOS)/Preview Content\""; + DEVELOPMENT_TEAM = 8N4K3S3FJ4; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "david.app.rive.Example--tvOS-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 16.0; + }; + name = Debug; + }; + F2C852DE2CD1772400F0D81F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Example (tvOS)/Preview Content\""; + DEVELOPMENT_TEAM = 8N4K3S3FJ4; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "david.app.rive.Example--tvOS-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 16.0; }; name = Release; }; @@ -1634,6 +1980,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F22138882CCBEDD500A25BA7 /* Build configuration list for PBXNativeTarget "Example (visionOS)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F22138892CCBEDD500A25BA7 /* Debug */, + F221388A2CCBEDD500A25BA7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F2C852DC2CD1772400F0D81F /* Build configuration list for PBXNativeTarget "Example (tvOS)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F2C852DD2CD1772400F0D81F /* Debug */, + F2C852DE2CD1772400F0D81F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ diff --git a/Example-iOS/RiveExample.xcodeproj/xcshareddata/xcschemes/Example (tvOS).xcscheme b/Example-iOS/RiveExample.xcodeproj/xcshareddata/xcschemes/Example (tvOS).xcscheme new file mode 100644 index 0000000..1126c34 --- /dev/null +++ b/Example-iOS/RiveExample.xcodeproj/xcshareddata/xcschemes/Example (tvOS).xcscheme @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example-iOS/Source/Examples/Storyboard/StressTest.swift b/Example-iOS/Source/Examples/Storyboard/StressTest.swift index 1b7944e..8b7e026 100644 --- a/Example-iOS/Source/Examples/Storyboard/StressTest.swift +++ b/Example-iOS/Source/Examples/Storyboard/StressTest.swift @@ -30,7 +30,11 @@ class StressTestViewController: UIViewController { viewModel!.setView(rView!) view.addSubview(rView!) let f = view.frame + #if os(visionOS) + let h: CGFloat = 0 + #else let h = UIApplication.shared.statusBarFrame.height + 40 + #endif rView!.frame = CGRect(x:f.minX, y:f.minY + h, width:f.width, height:f.height - h) let gesture = UITapGestureRecognizer(target: self, action: #selector (self.onTap (_:))) @@ -48,10 +52,17 @@ class CustomRiveView: RiveView { super.init() rModel = model } - + + #if os(visionOS) + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + #else required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } + #endif + override func drawRive(_ rect: CGRect, size: CGSize) { // This prevents breaking when loading RiveFile async guard let artboard = rModel?.artboard else { return } diff --git a/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift b/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift index b3f7c2a..0867929 100644 --- a/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift +++ b/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift @@ -45,7 +45,7 @@ class RiveEventsVMExample: RiveViewModel { if let openUrlEvent = riveEvent as? RiveOpenUrlEvent { debugPrint("Open URL Event Properties: \(openUrlEvent.properties())") if let url = URL(string: openUrlEvent.url()) { - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) UIApplication.shared.open(url) #else NSWorkspace.shared.open(url) diff --git a/RiveRuntime.xcodeproj/project.pbxproj b/RiveRuntime.xcodeproj/project.pbxproj index 0bc2900..a349b9c 100644 --- a/RiveRuntime.xcodeproj/project.pbxproj +++ b/RiveRuntime.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -80,7 +80,7 @@ C38BB5F4287629C20039E385 /* defaultstatemachine.riv in Resources */ = {isa = PBXBuildFile; fileRef = C38BB5F3287629C20039E385 /* defaultstatemachine.riv */; }; C38BB5F628762B720039E385 /* RiveStateMachineTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38BB5F528762B720039E385 /* RiveStateMachineTest.swift */; }; C3E2B580282F242400A8651B /* RiveStateMachineInstance+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E2B57F282F242400A8651B /* RiveStateMachineInstance+Extensions.swift */; }; - C9161A81263CBCBC007749A1 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C73ED124FC478800EF9516 /* RiveRuntime.framework */; platformFilter = ios; }; + C9161A81263CBCBC007749A1 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C73ED124FC478800EF9516 /* RiveRuntime.framework */; }; C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9601F2A250C25930032AA07 /* CoreGraphicsRenderer.mm */; }; C9C73EE024FC478900EF9516 /* RiveRuntimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9C73EDF24FC478900EF9516 /* RiveRuntimeTests.mm */; }; C9C73EE224FC478900EF9516 /* RiveRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = C9C73ED424FC478800EF9516 /* RiveRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -95,14 +95,15 @@ E599DCFA2AAFA06100D1E49A /* rating_animation.riv in Resources */ = {isa = PBXBuildFile; fileRef = E599DCF82AAFA06100D1E49A /* rating_animation.riv */; }; F21F08142C66526D00FFA205 /* RiveFallbackFontDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F21F08132C66526D00FFA205 /* RiveFallbackFontDescriptor.swift */; }; F23626AA2C8F90FA00727D9A /* nested_text_run.riv in Resources */ = {isa = PBXBuildFile; fileRef = F23626A92C8F90FA00727D9A /* nested_text_run.riv */; }; + F23992E72CB9C1C60021EF61 /* RenderContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F23992E62CB9C1C60021EF61 /* RenderContextTests.m */; }; F2610DD22CA5B4C40090D50B /* RiveLogger+StateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD12CA5B4C40090D50B /* RiveLogger+StateMachine.swift */; }; F2610DD42CA5B5460090D50B /* RiveLogger+Artboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD32CA5B5460090D50B /* RiveLogger+Artboard.swift */; }; F2610DD62CA5B5DD0090D50B /* RiveLogger+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD52CA5B5DD0090D50B /* RiveLogger+ViewModel.swift */; }; F2610DD82CA5B6570090D50B /* RiveLogger+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD72CA5B6570090D50B /* RiveLogger+Model.swift */; }; F2610DDA2CA5B84B0090D50B /* RiveLogger+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD92CA5B84B0090D50B /* RiveLogger+File.swift */; }; F2610DE12CA5FBE30090D50B /* RiveLogger+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DE02CA5FBE30090D50B /* RiveLogger+View.swift */; }; - F23992E72CB9C1C60021EF61 /* RenderContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F23992E62CB9C1C60021EF61 /* RenderContextTests.m */; }; F28DE4532C5002D900F3C379 /* RiveModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F28DE4522C5002D900F3C379 /* RiveModelTests.swift */; }; + F2C003E82C933D2300339E67 /* RiveMetalDrawableView.h in Headers */ = {isa = PBXBuildFile; fileRef = F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */; settings = {ATTRIBUTES = (Public, ); }; }; F2CCA9792C9B2799007DC0D2 /* referenced_image_asset.riv in Resources */ = {isa = PBXBuildFile; fileRef = F2CCA9782C9B2799007DC0D2 /* referenced_image_asset.riv */; }; F2CCA9C22C9E13BA007DC0D2 /* RiveLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2CCA9C12C9E13BA007DC0D2 /* RiveLogger.swift */; }; F2D285492C6D469900728340 /* RiveFallbackFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D285482C6D469900728340 /* RiveFallbackFontProvider.swift */; }; @@ -215,14 +216,15 @@ E599DCF82AAFA06100D1E49A /* rating_animation.riv */ = {isa = PBXFileReference; lastKnownFileType = file; name = rating_animation.riv; path = "Example-iOS/Assets/rating_animation.riv"; sourceTree = SOURCE_ROOT; }; F21F08132C66526D00FFA205 /* RiveFallbackFontDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontDescriptor.swift; sourceTree = ""; }; F23626A92C8F90FA00727D9A /* nested_text_run.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = nested_text_run.riv; sourceTree = ""; }; + F23992E62CB9C1C60021EF61 /* RenderContextTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RenderContextTests.m; sourceTree = ""; }; F2610DD12CA5B4C40090D50B /* RiveLogger+StateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+StateMachine.swift"; sourceTree = ""; }; F2610DD32CA5B5460090D50B /* RiveLogger+Artboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+Artboard.swift"; sourceTree = ""; }; F2610DD52CA5B5DD0090D50B /* RiveLogger+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+ViewModel.swift"; sourceTree = ""; }; F2610DD72CA5B6570090D50B /* RiveLogger+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+Model.swift"; sourceTree = ""; }; F2610DD92CA5B84B0090D50B /* RiveLogger+File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+File.swift"; sourceTree = ""; }; F2610DE02CA5FBE30090D50B /* RiveLogger+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+View.swift"; sourceTree = ""; }; - F23992E62CB9C1C60021EF61 /* RenderContextTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RenderContextTests.m; sourceTree = ""; }; F28DE4522C5002D900F3C379 /* RiveModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveModelTests.swift; sourceTree = ""; }; + F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RiveMetalDrawableView.h; sourceTree = ""; }; F2CCA9782C9B2799007DC0D2 /* referenced_image_asset.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = referenced_image_asset.riv; sourceTree = ""; }; F2CCA9C12C9E13BA007DC0D2 /* RiveLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveLogger.swift; sourceTree = ""; }; F2D285482C6D469900728340 /* RiveFallbackFontProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontProvider.swift; sourceTree = ""; }; @@ -281,6 +283,7 @@ 043025F92AFA860E00320F2E /* FileAssetLoaderAdapter.hpp */, 043025FD2AFA8FCF00320F2E /* RiveFileAsset.h */, 043026012AFB9FCD00320F2E /* RiveFactory.h */, + F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */, ); path = include; sourceTree = ""; @@ -474,6 +477,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + C9C741F424FC510200EF9516 /* Rive.h in Headers */, 046FB7F7264EAA60000129B1 /* RiveFile.h in Headers */, 046FB7FC264EAA61000129B1 /* RiveArtboard.h in Headers */, 2A7079352726277C00C035A1 /* rive_renderer_view.hh in Headers */, @@ -488,6 +492,7 @@ 043025F22AF90D4800320F2E /* RiveFileAssetLoader.h in Headers */, 043025FE2AFA8FCF00320F2E /* RiveFileAsset.h in Headers */, E5964A962A965A9300140479 /* RiveEvent.h in Headers */, + F2C003E82C933D2300339E67 /* RiveMetalDrawableView.h in Headers */, 043026022AFB9FCD00320F2E /* RiveFactory.h in Headers */, C9C741F424FC510200EF9516 /* Rive.h in Headers */, F2FD94052CC9492B00C1FC85 /* RiveFont.h in Headers */, @@ -638,6 +643,7 @@ F2610DDA2CA5B84B0090D50B /* RiveLogger+File.swift in Sources */, C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */, C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */, + C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */, 043025F42AF90EAC00320F2E /* RiveFileAssetLoader.mm in Sources */, F2D285492C6D469900728340 /* RiveFallbackFontProvider.swift in Sources */, 043025FC2AFA862E00320F2E /* FileAssetLoaderAdapter.mm in Sources */, @@ -691,7 +697,6 @@ /* Begin PBXTargetDependency section */ C9C73EDD24FC478900EF9516 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - platformFilter = ios; target = C9C73ED024FC478800EF9516 /* RiveRuntime */; targetProxy = C9C73EDC24FC478900EF9516 /* PBXContainerItemProxy */; }; @@ -849,7 +854,6 @@ "HEADER_SEARCH_PATHS[arch=*]" = ( dependencies/includes/rive/include, dependencies/includes/renderer/include, - dependencies/includes/renderer/include, dependencies/includes/cg_renderer/include, ); INFOPLIST_FILE = Source/Info.plist; @@ -874,6 +878,32 @@ "$(OTHER_CFLAGS)", "-DYOGA_EXPORT=", ); + "OTHER_LDFLAGS[sdk=appletvos*]" = ( + "-lrive_appletvos", + "-lrive_harfbuzz_appletvos", + "-lrive_sheenbidi_appletvos", + "-lrive_yoga_appletvos", + "-lrive_pls_renderer_appletvos", + "-lrive_cg_renderer_appletvos", + "-lrive_decoders_appletvos", + "-lrive_png_appletvos", + "-lrive_zlib_appletvos", + "-lrive_jpeg_appletvos", + "-lrive_webp_appletvos", + ); + "OTHER_LDFLAGS[sdk=appletvsimulator*]" = ( + "-lrive_appletvsimulator", + "-lrive_harfbuzz_appletvsimulator", + "-lrive_sheenbidi_appletvsimulator", + "-lrive_yoga_appletvsimulator", + "-lrive_pls_renderer_appletvsimulator", + "-lrive_cg_renderer_appletvsimulator", + "-lrive_decoders_appletvsimulator", + "-lrive_png_appletvsimulator", + "-lrive_zlib_appletvsimulator", + "-lrive_jpeg_appletvsimulator", + "-lrive_webp_appletvsimulator", + ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-lrive", "-lrive_harfbuzz", @@ -901,16 +931,37 @@ "-lrive_cg_renderer_macos", "-lrive_decoders_macos", ); + "OTHER_LDFLAGS[sdk=xros*]" = ( + "-lrive_xros", + "-lrive_harfbuzz_xros", + "-lrive_sheenbidi_xros", + "-lrive_yoga_xros", + "-lrive_pls_renderer_xros", + "-lrive_cg_renderer_xros", + "-lrive_decoders_xros", + ); + "OTHER_LDFLAGS[sdk=xrsimulator*]" = ( + "-lrive_xrsimulator", + "-lrive_harfbuzz_xrsimulator", + "-lrive_sheenbidi_xrsimulator", + "-lrive_yoga_xrsimulator", + "-lrive_pls_renderer_xrsimulator", + "-lrive_cg_renderer_xrsimulator", + "-lrive_decoders_xrsimulator", + ); PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntime; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,6"; + TARGETED_DEVICE_FAMILY = "1,2,3,6,7"; + TVOS_DEPLOYMENT_TARGET = 16.0; + XROS_DEPLOYMENT_TARGET = 1.0; }; name = Debug; }; @@ -935,7 +986,6 @@ "HEADER_SEARCH_PATHS[arch=*]" = ( dependencies/includes/rive/include, dependencies/includes/renderer/include, - dependencies/includes/renderer/include, dependencies/includes/cg_renderer/include, ); INFOPLIST_FILE = Source/Info.plist; @@ -962,6 +1012,32 @@ "$(OTHER_CFLAGS)", "-DYOGA_EXPORT=", ); + "OTHER_LDFLAGS[sdk=appletvos*]" = ( + "-lrive_appletvos", + "-lrive_harfbuzz_appletvos", + "-lrive_sheenbidi_appletvos", + "-lrive_yoga_appletvos", + "-lrive_pls_renderer_appletvos", + "-lrive_cg_renderer_appletvos", + "-lrive_decoders_appletvos", + "-lrive_png_appletvos", + "-lrive_zlib_appletvos", + "-lrive_jpeg_appletvos", + "-lrive_webp_appletvos", + ); + "OTHER_LDFLAGS[sdk=appletvsimulator*]" = ( + "-lrive_appletvsimulator", + "-lrive_harfbuzz_appletvsimulator", + "-lrive_sheenbidi_appletvsimulator", + "-lrive_yoga_appletvsimulator", + "-lrive_pls_renderer_appletvsimulator", + "-lrive_cg_renderer_appletvsimulator", + "-lrive_decoders_appletvsimulator", + "-lrive_png_appletvsimulator", + "-lrive_zlib_appletvsimulator", + "-lrive_jpeg_appletvsimulator", + "-lrive_webp_appletvsimulator", + ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-lrive", "-lrive_harfbuzz", @@ -989,16 +1065,37 @@ "-lrive_cg_renderer_macos", "-lrive_decoders_macos", ); + "OTHER_LDFLAGS[sdk=xros*]" = ( + "-lrive_xros", + "-lrive_harfbuzz_xros", + "-lrive_sheenbidi_xros", + "-lrive_yoga_xros", + "-lrive_pls_renderer_xros", + "-lrive_cg_renderer_xros", + "-lrive_decoders_xros", + ); + "OTHER_LDFLAGS[sdk=xrsimulator*]" = ( + "-lrive_xrsimulator", + "-lrive_harfbuzz_xrsimulator", + "-lrive_sheenbidi_xrsimulator", + "-lrive_yoga_xrsimulator", + "-lrive_pls_renderer_xrsimulator", + "-lrive_cg_renderer_xrsimulator", + "-lrive_decoders_xrsimulator", + ); PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntime; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,6"; + TARGETED_DEVICE_FAMILY = "1,2,3,6,7"; + TVOS_DEPLOYMENT_TARGET = 16.0; + XROS_DEPLOYMENT_TARGET = 1.0; }; name = Release; }; @@ -1017,12 +1114,12 @@ ); PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntimeTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,3,7"; }; name = Debug; }; @@ -1041,11 +1138,11 @@ ); PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntimeTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,3,7"; }; name = Release; }; diff --git a/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift b/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift index 8ad1d79..90d7acd 100644 --- a/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift +++ b/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift @@ -7,7 +7,7 @@ // import Foundation -#if os(iOS) +#if os(iOS) || os(visionOS) || os(tvOS) import UIKit public typealias RiveNativeFont = UIFont private typealias RiveNativeFontDescriptor = UIFontDescriptor @@ -120,7 +120,7 @@ extension RiveFallbackFontDescriptor: RiveFallbackFontProvider { /// - Returns: The font generated from all values of a `RiveFallbackFontDescriptor`. @objc public var fallbackFont: RiveNativeFont { let font: RiveNativeFont? - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) font = RiveNativeFont(descriptor: toFontDescriptor(), size: Self.defaultFontSize) #elseif os(macOS) font = RiveNativeFont(descriptor: toFontDescriptor(), size: Self.defaultFontSize) diff --git a/Source/Renderer/RenderContextManager.mm b/Source/Renderer/RenderContextManager.mm index d43ff5d..1dcec81 100644 --- a/Source/Renderer/RenderContextManager.mm +++ b/Source/Renderer/RenderContextManager.mm @@ -4,9 +4,11 @@ #import #import +#import #import #import #import +#import #include "utils/auto_cf.hpp" #include "cg_factory.hpp" @@ -25,10 +27,12 @@ static CGSize Maximum2DTextureSizeFromDevice(id device) { size = CGSizeMake(16384, 16384); } +#if !TARGET_OS_VISION && !TARGET_OS_TV else if ([device supportsFamily:MTLGPUFamilyApple9]) { size = CGSizeMake(16384, 16384); } +#endif else if ([device supportsFamily:MTLGPUFamilyApple8]) { size = CGSizeMake(16384, 16384); @@ -77,12 +81,12 @@ static CGSize Maximum2DTextureSizeFromDevice(id device) return nil; } -- (rive::Renderer*)beginFrame:(MTKView*)view +- (rive::Renderer*)beginFrame:(id)view { return nil; } -- (void)endFrame:(MTKView*)view +- (void)endFrame:(id)view withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; {} @@ -128,7 +132,6 @@ static CGSize Maximum2DTextureSizeFromDevice(id device) #include "rive/renderer/rive_renderer.hpp" @interface RiveRendererContext : RenderContext -- (rive::Renderer*)beginFrame:(MTKView*)view; @end @implementation RiveRendererContext @@ -178,7 +181,7 @@ static std::unique_ptr make_pls_context_native( return _renderContext; } -- (rive::Renderer*)beginFrame:(MTKView*)view +- (rive::Renderer*)beginFrame:(id)view { id surface = view.currentDrawable; if (!surface.texture) @@ -219,7 +222,7 @@ static std::unique_ptr make_pls_context_native( return _renderer.get(); } -- (void)endFrame:(MTKView*)view +- (void)endFrame:(id)view withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; { id flushCommandBuffer = [self.metalQueue commandBuffer]; @@ -249,7 +252,7 @@ static std::unique_ptr make_pls_context_native( @end @interface CGRendererContext : RenderContext -- (rive::Renderer*)beginFrame:(MTKView*)view; +- (rive::Renderer*)beginFrame:(id)view; @end constexpr static int kBufferRingSize = 3; @@ -295,7 +298,7 @@ constexpr static int kBufferRingSize = 3; return &factory; } -- (rive::Renderer*)beginFrame:(MTKView*)view +- (rive::Renderer*)beginFrame:(id)view { uint32_t cgBitmapInfo; switch (view.colorPixelFormat) @@ -346,7 +349,7 @@ constexpr static int kBufferRingSize = 3; return _renderer.get(); } -- (void)endFrame:(MTKView*)view +- (void)endFrame:(id)view withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; { if (_cgContext != nil) diff --git a/Source/Renderer/include/RenderContext.h b/Source/Renderer/include/RenderContext.h index c8588d3..0261b7d 100644 --- a/Source/Renderer/include/RenderContext.h +++ b/Source/Renderer/include/RenderContext.h @@ -18,7 +18,7 @@ class Renderer; NS_ASSUME_NONNULL_BEGIN -@class MTKView; +@protocol RiveMetalDrawableView; /// RenderContext knows how to set up a backend-specific render context (e.g., /// CG, Rive, ...), and provides a rive::Factory and rive::Renderer for it. @@ -28,11 +28,11 @@ NS_ASSUME_NONNULL_BEGIN @property MTLPixelFormat depthStencilPixelFormat; @property BOOL framebufferOnly; - (rive::Factory*)factory; -- (rive::Renderer*)beginFrame:(MTKView*)view; -- (void)endFrame:(MTKView*)view +- (rive::Renderer*)beginFrame:(id)view; +- (void)endFrame:(id)view withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler; - (BOOL)canDrawInRect:(CGRect)rect - drawableSize:(CGSize)drawableSize + drawableSize:(CGSize)size scale:(CGFloat)scale; @end diff --git a/Source/Renderer/include/RiveFactory.h b/Source/Renderer/include/RiveFactory.h index 639d22b..70a0a7c 100644 --- a/Source/Renderer/include/RiveFactory.h +++ b/Source/Renderer/include/RiveFactory.h @@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN */ @interface RiveFactory : NSObject - (RiveFont*)decodeFont:(NSData*)data; -#if TARGET_OS_IPHONE +#if TARGET_OS_IPHONE || TARGET_OS_VISION || TARGET_OS_TV - (RiveFont*)decodeUIFont:(UIFont*)data NS_SWIFT_NAME(decodeFont(_:)); #else - (RiveFont*)decodeNSFont:(NSFont*)data NS_SWIFT_NAME(decodeFont(_:)); diff --git a/Source/Renderer/include/RiveMetalDrawableView.h b/Source/Renderer/include/RiveMetalDrawableView.h new file mode 100644 index 0000000..8bbce2d --- /dev/null +++ b/Source/Renderer/include/RiveMetalDrawableView.h @@ -0,0 +1,30 @@ +// +// RiveMetalDrawableView.h +// RiveRuntime +// +// Created by David Skuza on 9/12/24. +// Copyright © 2024 Rive. All rights reserved. +// + +#ifndef RiveMetalDrawableView_h +#define RiveMetalDrawableView_h + +#import + +@protocol RiveMetalDrawableView +@property(nullable, nonatomic, retain) id device; +@property(nonatomic) MTLPixelFormat + depthStencilPixelFormat; // Currently unused; not available in CAMetalLayer +@property(nonatomic) BOOL framebufferOnly; +@property(nonatomic) + NSUInteger sampleCount; // Currently unused; not available in CAMetalLayer +@property(nonatomic) BOOL + enableSetNeedsDisplay; // Currently unused; not available in CAMetalLayer +@property(nonatomic, getter=isPaused) + BOOL paused; // Currently unused; no internal display link used +@property(nullable, nonatomic, readonly) id currentDrawable; +@property(nonatomic) MTLPixelFormat colorPixelFormat; +@property(nonatomic) CGSize drawableSize; +@end + +#endif /* RiveMetalDrawableView_h */ diff --git a/Source/Renderer/include/rive_renderer_view.hh b/Source/Renderer/include/rive_renderer_view.hh index 3cc120b..88b7f24 100644 --- a/Source/Renderer/include/rive_renderer_view.hh +++ b/Source/Renderer/include/rive_renderer_view.hh @@ -1,12 +1,22 @@ #import #import #import +#import #import +#if TARGET_OS_VISION +@interface RiveMTKView : UIView +- (nonnull instancetype)initWithFrame:(CGRect) frameRect device:(nullable id) device; +@end +#else +@interface RiveMTKView : MTKView +@end +#endif + NS_ASSUME_NONNULL_BEGIN -@interface RiveRendererView : MTKView +@interface RiveRendererView : RiveMTKView - (instancetype)initWithFrame:(CGRect)frameRect; /// Deprecated. Use `alignWithRect:contentRect:alignment:fit:scaleFactor:` instead. diff --git a/Source/Renderer/rive_renderer_view.mm b/Source/Renderer/rive_renderer_view.mm index d4b4455..dbaf075 100644 --- a/Source/Renderer/rive_renderer_view.mm +++ b/Source/Renderer/rive_renderer_view.mm @@ -3,7 +3,7 @@ #import #import -#if TARGET_OS_IPHONE +#if TARGET_OS_IPHONE || TARGET_VISION_OS || TARGET_OS_TV #import #else #import @@ -17,6 +17,138 @@ #define WITH_RIVE_AUDIO #include "rive/audio/audio_engine.hpp" +#if TARGET_OS_VISION +@implementation RiveMTKView +{ + id _currentDrawable; +} + +@synthesize enableSetNeedsDisplay; + +@synthesize paused; + +@synthesize sampleCount; + +@synthesize depthStencilPixelFormat; + +- (instancetype)initWithFrame:(CGRect)frameRect device:(id)device +{ + self = [super initWithFrame:frameRect]; + self.device = device; + return self; +} + ++ (Class)layerClass +{ + return [CAMetalLayer class]; +} + +- (nullable id)device +{ + return [self metalLayer].device; +} + +- (void)setDevice:(nullable id)device +{ + [self metalLayer].device = device; +} + +- (CAMetalLayer*)metalLayer +{ + return (CAMetalLayer*)self.layer; +} + +- (void)setFramebufferOnly:(BOOL)framebufferOnly +{ + [self metalLayer].framebufferOnly = framebufferOnly; +} + +- (BOOL)framebufferOnly +{ + return [self metalLayer].framebufferOnly; +} + +- (void)setCurrentDrawable:(id _Nullable)currentDrawable +{ + return; +} + +- (nullable id)currentDrawable +{ + if (_currentDrawable == nil) + { + _currentDrawable = [self metalLayer].nextDrawable; + } + return _currentDrawable; +} + +- (void)setColorPixelFormat:(MTLPixelFormat)colorPixelFormat +{ + [self metalLayer].pixelFormat = colorPixelFormat; +} + +- (MTLPixelFormat)colorPixelFormat +{ + return [self metalLayer].pixelFormat; +} + +- (void)setDrawableSize:(CGSize)drawableSize +{ + [self metalLayer].drawableSize = drawableSize; +} + +- (CGSize)drawableSize +{ + return [self metalLayer].drawableSize; +} + +- (void)_updateDrawableSizeFromBounds +{ + CGSize newSize = self.bounds.size; + newSize.width *= self.traitCollection.displayScale; + newSize.height *= self.traitCollection.displayScale; + self.drawableSize = newSize; +} + +- (void)setContentScaleFactor:(CGFloat)contentScaleFactor +{ + [super setContentScaleFactor:contentScaleFactor]; + [self _updateDrawableSizeFromBounds]; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + [self _updateDrawableSizeFromBounds]; +} + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + [self _updateDrawableSizeFromBounds]; +} + +- (void)setBounds:(CGRect)bounds +{ + [super setBounds:bounds]; + [self _updateDrawableSizeFromBounds]; +} + +// For some reason, when setNeedsDisplay is called, drawRect is not called +// But, we get a delegate callback when the layer should be displayed, +// so we'll just piggyback off of that and draw for now. +- (void)displayLayer:(CALayer*)layer +{ + _currentDrawable = [self metalLayer].nextDrawable; + [self drawRect:self.bounds]; +} + +@end +#else +@implementation RiveMTKView +@end +#endif + @implementation RiveRendererView { RenderContext* _renderContext; @@ -43,7 +175,7 @@ - (instancetype)initWithCoder:(NSCoder*)decoder { -#if TARGET_OS_IPHONE +#if TARGET_OS_IPHONE || TARGET_OS_VISION || TARGET_OS_TV [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground:) diff --git a/Source/RiveView.swift b/Source/RiveView.swift index 743c3c8..2093e93 100644 --- a/Source/RiveView.swift +++ b/Source/RiveView.swift @@ -26,7 +26,7 @@ open class RiveView: RiveRendererView { /// Defaults to the "legacy" methods, which will be overridden /// by window handlers in this view when the window changes. private lazy var _layoutScaleFactor: Double = { - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) return self.traitCollection.displayScale #else guard let scale = NSScreen.main?.backingScaleFactor else { return 1 } @@ -86,27 +86,36 @@ open class RiveView: RiveRendererView { try! setModel(model, autoPlay: autoPlay) } + + #if os(visionOS) + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + #else required public init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } + #endif private func commonInit() { - #if os(iOS) - if #available(iOS 17, *) { + #if os(iOS) || os(visionOS) || os(tvOS) + if #available(iOS 17, tvOS 17, visionOS 1, *) { registerForTraitChanges([UITraitHorizontalSizeClass.self, UITraitVerticalSizeClass.self]) { [weak self] (_: UITraitEnvironment, traitCollection: UITraitCollection) in guard let self else { return } self.redrawIfNecessary() } } - if #available(iOS 17, *) { + if #available(iOS 17, tvOS 17, visionOS 1, *) { registerForTraitChanges([UITraitDisplayScale.self]) { [weak self] (_: UITraitEnvironment, traitCollection: UITraitCollection) in guard let self else { return } self._layoutScaleFactor = self.traitCollection.displayScale } } + #endif + #if os(iOS) UIDevice.current.beginGeneratingDeviceOrientationNotifications() orientationObserver = NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil) { [weak self] _ in guard let self else { return } @@ -146,19 +155,25 @@ open class RiveView: RiveRendererView { } private func needsDisplay() { - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) setNeedsDisplay() #else needsDisplay=true #endif } - #if os(iOS) + #if os(iOS) || os(tvOS) open override func didMoveToWindow() { super.didMoveToWindow() guard let scale = window?.windowScene?.screen.scale else { return } _layoutScaleFactor = scale } + #elseif os(visionOS) + open override func didMoveToWindow() { + super.didMoveToWindow() + let scale = traitCollection.displayScale + _layoutScaleFactor = scale + } #else open override func viewDidMoveToWindow() { super.viewDidMoveToWindow() @@ -172,7 +187,7 @@ open class RiveView: RiveRendererView { stopTimer() isPlaying = false riveModel = model - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) isOpaque = false #else layer?.isOpaque=false @@ -188,7 +203,7 @@ open class RiveView: RiveRendererView { setFPSCounterVisibility() } - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) /// Hints to underlying CADisplayLink the preferred FPS to run at /// - Parameters: /// - preferredFramesPerSecond: Integer number of seconds to set preferred FPS at @@ -268,7 +283,7 @@ open class RiveView: RiveRendererView { forMode: .common ) } - #if os(iOS) + #if os(iOS) || os(visionOS) if displayLinkProxy?.displayLink?.isPaused == true { displayLinkProxy?.displayLink?.isPaused = false } @@ -283,7 +298,7 @@ open class RiveView: RiveRendererView { } private func timestamp() -> CFTimeInterval { - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) return displayLinkProxy?.displayLink?.targetTimestamp ?? Date().timeIntervalSince1970 #else return Date().timeIntervalSince1970 @@ -310,7 +325,7 @@ open class RiveView: RiveRendererView { // Calculate the time elapsed between ticks let elapsedTime = timestamp - lastTime - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) fpsCounter?.didDrawFrame(timestamp: timestamp) #else fpsCounter?.elapsed(time: elapsedTime) @@ -394,7 +409,7 @@ open class RiveView: RiveRendererView { } align(with: newFrame, contentRect: artboard.bounds(), alignment: alignment, fit: fit, scaleFactor: scale) draw(with: artboard) - + } // MARK: - UITraitCollection @@ -416,7 +431,7 @@ open class RiveView: RiveRendererView { #endif // MARK: - UIResponder - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) open override func touchesBegan(_ touches: Set, with event: UIEvent?) { guard let touch = touches.first else { return } @@ -692,7 +707,7 @@ open class RiveView: RiveRendererView { func player(didAdvanceby seconds: Double, riveModel: RiveModel?) } -#if os(iOS) +#if os(iOS) || os(visionOS) || os(tvOS) fileprivate class DisplayLinkProxy { var displayLink: CADisplayLink? var handle: (() -> Void)? diff --git a/Source/RiveViewModel.swift b/Source/RiveViewModel.swift index 857a02c..de21dcd 100644 --- a/Source/RiveViewModel.swift +++ b/Source/RiveViewModel.swift @@ -203,7 +203,7 @@ import Combine didSet { riveView?.forwardsListenerEvents = forwardsListenerEvents } } - #if os(iOS) + #if os(iOS) || os(visionOS) || os(tvOS) /// Hints to underlying CADisplayLink in RiveView (if created) the preferred FPS to run at /// For more, see: https://developer.apple.com/documentation/quartzcore/cadisplaylink/1648421-preferredframespersecond /// - Parameters: @@ -614,7 +614,7 @@ import Combine } } -#if os(iOS) +#if os(iOS) || os(visionOS) || os(tvOS) /// This makes a SwiftUI digestable view from an `RiveViewModel` and its `RiveView` public struct RiveViewRepresentable: UIViewRepresentable { let viewModel: RiveViewModel diff --git a/scripts/build.rive.sh b/scripts/build.rive.sh index 9199ed7..33768d2 100755 --- a/scripts/build.rive.sh +++ b/scripts/build.rive.sh @@ -147,8 +147,186 @@ build_runtime_macosx() { cp -r $RIVE_RUNTIME_DIR/decoders/out/$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_macos.a } +build_runtime_xros() { + # Build the rive runtime. + pushd $RIVE_RUNTIME_DIR + ./build.sh -p xros clean + ./build.sh -p xros $1 + popd + cp -r $RIVE_RUNTIME_DIR/build/xros/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_xros.a + cp -r $RIVE_RUNTIME_DIR/dependencies/xros/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_xros.a + cp -r $RIVE_RUNTIME_DIR/dependencies/xros/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_xros.a + cp -r $RIVE_RUNTIME_DIR/dependencies/xros/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_xros.a + cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive + + # Build rive_cg_renderer. + pushd $RIVE_RUNTIME_DIR/cg_renderer + premake5 --config=$1 --out=out/xros_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xros gmake2 + make -C out/xros_$1 clean + make -C out/xros_$1 -j12 rive_cg_renderer + popd + cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/xros_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_xros.a + cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer + + # Build rive_pls_renderer. + pushd $RIVE_PLS_DIR + premake5 --config=$1 --out=out/xros_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=xros gmake2 + make -C out/xros_$1 clean + make -C out/xros_$1 -j12 rive_pls_renderer + popd + cp -r $RIVE_PLS_DIR/out/xros_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xros.a + $DEV_SCRIPT_DIR/strip_static_lib.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xros.a + cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer + + # Build rive_decoders. + pushd $RIVE_RUNTIME_DIR/decoders + premake5 --file=premake5_v2.lua --config=$1 --out=out/xros_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xros gmake2 + make -C out/xros_$1 clean + make -C out/xros_$1 -j12 rive_decoders + popd + cp -r $RIVE_RUNTIME_DIR/decoders/out/xros_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_xros.a +} + +build_runtime_xrsimulator() { + # Build the rive runtime. + pushd $RIVE_RUNTIME_DIR + ./build.sh -p xrsimulator clean + ./build.sh -p xrsimulator $1 + popd + cp -r $RIVE_RUNTIME_DIR/build/xrsimulator/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_xrsimulator.a + cp -r $RIVE_RUNTIME_DIR/dependencies/xrsimulator/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_xrsimulator.a + cp -r $RIVE_RUNTIME_DIR/dependencies/xrsimulator/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_xrsimulator.a + cp -r $RIVE_RUNTIME_DIR/dependencies/xrsimulator/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_xrsimulator.a + cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive + + # Build rive_cg_renderer. + pushd $RIVE_RUNTIME_DIR/cg_renderer + premake5 --config=$1 --out=out/xrsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xrsimulator gmake2 + + make -C out/xrsimulator_$1 clean + make -C out/xrsimulator_$1 -j12 rive_cg_renderer + popd + cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/xrsimulator_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_xrsimulator.a + cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer + + # Build rive_pls_renderer. + pushd $RIVE_PLS_DIR + premake5 --config=$1 --out=out/xrsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=xrsimulator gmake2 + make -C out/xrsimulator_$1 clean + make -C out/xrsimulator_$1 -j12 rive_pls_renderer + popd + cp -r $RIVE_PLS_DIR/out/xrsimulator_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xrsimulator.a + $DEV_SCRIPT_DIR/strip_static_lib_fat.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xrsimulator.a arm64 x86_64 + cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer + + # Build rive_decoders. + pushd $RIVE_RUNTIME_DIR/decoders + premake5 --file=premake5_v2.lua --config=$1 --out=out/xrsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xrsimulator gmake2 + make -C out/xrsimulator_$1 clean + make -C out/xrsimulator_$1 -j12 rive_decoders + popd + cp -r $RIVE_RUNTIME_DIR/decoders/out/xrsimulator_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_xrsimulator.a +} + +build_runtime_appletvos() { + # Build the rive runtime. + pushd $RIVE_RUNTIME_DIR + ./build.sh -p appletvos clean + ./build.sh -p appletvos $1 + popd + cp -r $RIVE_RUNTIME_DIR/build/appletvos/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_appletvos.a + cp -r $RIVE_RUNTIME_DIR/dependencies/appletvos/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_appletvos.a + cp -r $RIVE_RUNTIME_DIR/dependencies/appletvos/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_appletvos.a + cp -r $RIVE_RUNTIME_DIR/dependencies/appletvos/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_appletvos.a + cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive + + # Build rive_cg_renderer. + pushd $RIVE_RUNTIME_DIR/cg_renderer + premake5 --config=$1 --out=out/appletvos_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvos gmake2 + make -C out/appletvos_$1 clean + make -C out/appletvos_$1 -j12 rive_cg_renderer + popd + cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/appletvos_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_appletvos.a + cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer + + # Build rive_pls_renderer. + pushd $RIVE_PLS_DIR + premake5 --config=$1 --out=out/appletvos_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=appletvos gmake2 + make -C out/appletvos_$1 clean + make -C out/appletvos_$1 -j12 rive_pls_renderer + popd + cp -r $RIVE_PLS_DIR/out/appletvos_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvos.a + $DEV_SCRIPT_DIR/strip_static_lib.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvos.a + cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer + + # Build rive_decoders. + pushd $RIVE_RUNTIME_DIR/decoders + premake5 --file=premake5_v2.lua --config=$1 --out=out/appletvos_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvos gmake2 + make -C out/appletvos_$1 clean + make -C out/appletvos_$1 -j12 rive_decoders + make -C out/appletvos_$1 -j12 libpng + make -C out/appletvos_$1 -j12 zlib + make -C out/appletvos_$1 -j12 libjpeg + make -C out/appletvos_$1 -j12 libwebp + popd + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_appletvos.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/liblibpng.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_png_appletvos.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/libzlib.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_zlib_appletvos.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/liblibjpeg.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_jpeg_appletvos.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/liblibwebp.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_webp_appletvos.a +} + +build_runtime_appletvsimulator() { + # Build the rive runtime. + pushd $RIVE_RUNTIME_DIR + ./build.sh -p appletvsimulator clean + ./build.sh -p appletvsimulator $1 + popd + cp -r $RIVE_RUNTIME_DIR/build/appletvsimulator/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/dependencies/appletvsimulator/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/dependencies/appletvsimulator/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/dependencies/appletvsimulator/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive + + # Build rive_cg_renderer. + pushd $RIVE_RUNTIME_DIR/cg_renderer + premake5 --config=$1 --out=out/appletvsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvsimulator gmake2 + + make -C out/appletvsimulator_$1 clean + make -C out/appletvsimulator_$1 -j12 rive_cg_renderer + popd + cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/appletvsimulator_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer + + # Build rive_pls_renderer. + pushd $RIVE_PLS_DIR + premake5 --config=$1 --out=out/appletvsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=appletvsimulator gmake2 + make -C out/appletvsimulator_$1 clean + make -C out/appletvsimulator_$1 -j12 rive_pls_renderer + popd + cp -r $RIVE_PLS_DIR/out/appletvsimulator_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvsimulator.a + $DEV_SCRIPT_DIR/strip_static_lib_fat.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvsimulator.a arm64 x86_64 + cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer + + # Build rive_decoders. + pushd $RIVE_RUNTIME_DIR/decoders + premake5 --file=premake5_v2.lua --config=$1 --out=out/appletvsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvsimulator gmake2 + make -C out/appletvsimulator_$1 clean + make -C out/appletvsimulator_$1 -j12 rive_decoders + make -C out/appletvsimulator_$1 -j12 libpng + make -C out/appletvsimulator_$1 -j12 zlib + make -C out/appletvsimulator_$1 -j12 libjpeg + make -C out/appletvsimulator_$1 -j12 libwebp + popd + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/liblibpng.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_png_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/libzlib.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_zlib_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/liblibjpeg.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_jpeg_appletvsimulator.a + cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/liblibwebp.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_webp_appletvsimulator.a +} + usage() { - echo "USAGE: $0 " + echo "USAGE: $0 " exit 1 } @@ -165,6 +343,14 @@ all) build_runtime_sim release build_runtime_macosx debug build_runtime_macosx release + build_runtime_xros debug + build_runtime_xros release + build_runtime_xrsimulator debug + build_runtime_xrsimulator release + build_runtime_appletvos debug + build_runtime_appletvos release + build_runtime_appletvsimulator debug + build_runtime_appletvsimulator release ;; macosx) if (($# < 2)); then @@ -214,6 +400,74 @@ ios_sim) ;; esac ;; +xros) + if (($# < 2)); then + usage + fi + case $2 in + release | debug) + make_dependency_directories + build_runtime_xros $2 + ;; + *) + usage + ;; + esac + ;; +xrsimulator) + if (($# < 2)); then + usage + fi + case $2 in + release | debug) + make_dependency_directories + build_runtime_xrsimulator $2 + # TODO: + # to build for the example you need debug, but to profile you need release. + # each time you build, both version are removed. to imnprove this only remove + # the version being built, or add a "both" option. + # build_runtime_sim debug + # build_runtime_sim release + ;; + *) + usage + ;; + esac + ;; +appletvos) + if (($# < 2)); then + usage + fi + case $2 in + release | debug) + make_dependency_directories + build_runtime_appletvos $2 + ;; + *) + usage + ;; + esac + ;; +appletvsimulator) + if (($# < 2)); then + usage + fi + case $2 in + release | debug) + make_dependency_directories + build_runtime_appletvsimulator $2 + # TODO: + # to build for the example you need debug, but to profile you need release. + # each time you build, both version are removed. to imnprove this only remove + # the version being built, or add a "both" option. + # build_runtime_sim debug + # build_runtime_sim release + ;; + *) + usage + ;; + esac + ;; *) usage ;; diff --git a/scripts/build_framework.sh b/scripts/build_framework.sh index 1042a8f..4ba5b03 100755 --- a/scripts/build_framework.sh +++ b/scripts/build_framework.sh @@ -53,9 +53,53 @@ xcodebuild archive \ SKIP_INSTALL=NO \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES +xcodebuild archive \ + -configuration ${CONFIGURATION} \ + -project RiveRuntime.xcodeproj \ + -scheme RiveRuntime \ + -sdk xros \ + -destination generic/platform=visionOS \ + -archivePath ".build/archives/RiveRuntime_visionOS" \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES + +xcodebuild archive \ + -configuration ${CONFIGURATION} \ + -project RiveRuntime.xcodeproj \ + -scheme RiveRuntime \ + -sdk xrsimulator \ + -destination "generic/platform=visionOS Simulator" \ + -archivePath ".build/archives/RiveRuntime_visionOS_Simulator" \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES + +xcodebuild archive \ + -configuration ${CONFIGURATION} \ + -project RiveRuntime.xcodeproj \ + -scheme RiveRuntime \ + -sdk appletvos \ + -destination generic/platform=tvOS \ + -archivePath ".build/archives/RiveRuntime_tvOS" \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES + +xcodebuild archive \ + -configuration ${CONFIGURATION} \ + -project RiveRuntime.xcodeproj \ + -scheme RiveRuntime \ + -sdk appletvsimulator \ + -destination "generic/platform=tvOS Simulator" \ + -archivePath ".build/archives/RiveRuntime_tvOS_Simulator" \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES + xcodebuild \ -create-xcframework \ -framework .build/archives/RiveRuntime_iOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ -framework .build/archives/RiveRuntime_iOS_Simulator.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ -framework .build/archives/RiveRuntime_macOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ + -framework .build/archives/RiveRuntime_visionOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ + -framework .build/archives/RiveRuntime_visionOS_Simulator.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ + -framework .build/archives/RiveRuntime_tvOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ + -framework .build/archives/RiveRuntime_tvOS_Simulator.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \ -output archive/RiveRuntime.xcframework \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh index c5b37b7..ac69851 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,7 +1,52 @@ set -eo pipefail -# test RiveRuntime on a simulator -xcodebuild -workspace Rive.xcworkspace \ - -scheme RiveRuntime \ - -destination platform=iOS\ Simulator,name=iPhone\ 15 \ - clean test | xcpretty +test_ios_simulator() { + echo "=== Running tests on iOS Simulator ===" + # Test RiveRuntime on a iOS simulator + xcodebuild -workspace Rive.xcworkspace \ + -scheme RiveRuntime \ + -destination platform=iOS\ Simulator,name=iPhone\ 15 \ + clean test | xcpretty +} + +test_visionos_simulator() { + echo "=== Running tests on visionOS Simulator ===" + # Test RiveRuntime on a visionOS simulator + xcodebuild -workspace Rive.xcworkspace \ + -scheme RiveRuntime \ + -destination platform=visionOS\ Simulator,name=Apple\ Vision\ Pro \ + clean test | xcpretty +} + +test_tvos_simulator() { + echo "=== Running tests on tvOS Simulator ===" + # Test RiveRuntime on a tvOS simulator + xcodebuild -workspace Rive.xcworkspace \ + -scheme RiveRuntime \ + -destination platform=tvOS\ Simulator,name=Apple\ TV\ 4K\ \(3rd\ generation\) \ + clean test | xcpretty +} + +usage() { + echo "USAGE: $0 ios_sim|xrsimulator|appletvsimulator" + exit 1 +} + +if [[ $# -ne 1 ]]; then + usage +fi + +case $1 in +ios_sim) + test_ios_simulator + ;; +xrsimulator) + test_visionos_simulator + ;; +appletvsimulator) + test_tvos_simulator + ;; +*) + usage + ;; +esac diff --git a/submodules/rive-runtime b/submodules/rive-runtime index e27fe66..f8c6fc4 160000 --- a/submodules/rive-runtime +++ b/submodules/rive-runtime @@ -1 +1 @@ -Subproject commit e27fe665377a770989307fbbb8dd65c0d2eb02c4 +Subproject commit f8c6fc41890792f5c6b92b3281cb2e5d710d91a8