Add visionOS and tvOS support to Apple runtime

This pull request adds support for both visionOS and tvOS to the Apple (colloquially referred to as iOS) runtime.

It should _not_ be a breaking change, since the only major API change is an internal one (see `RenderContext` below). I believe we should be able to make this a minor release. Developers who have subclassed `RiveView` or `RiveRendererView` should not see any changes, unless they were explicitly expecting this view to be `MTKView`, which is fully unavailable on visionOS (hence our recreation - see `RiveMTKView` below.

## Premake Scripts

The premake scripts were updated to add a few new variants for iOS:
- xros (visionOS devices; named after the internal sdk)
- xrsimulator (visionOS simulator; named after the internal sdk)
- appletvos (tvOS devices; named after the internal sdk)
- appletvsimulator (tvOS simulators; named after the internal sdk)

The majority of the work here is copy/pasting existing code, and just adding additional filters when these new options are used, primarily used to target the new SDKs / minimums for those SDKs.

## Shaders

Shaders are pre-compiled for visionOS and tvOS separately, and the correct shaders are then used later-on at compile time.

## Build scripts

Build scripts were updated to support building the new libraries, targeting the new devices, using the new options above. Additionally, they have to point to new output files.

The `build_framework` script has been updated to build the new libraries to add to the final output `xcframework`.

## Project

Example targets for both visionOS and tvOS, since these truly are the "native" apps, rather than just iPad-on-your-device. These use a new `streaming` riv by the creative team.

The tvOS example app adds additional support for remote control, since that behavior can be utilized in multiple ways during development; that is, we don't add any "default" behavior for remote controls. The visionOS app, on the other hand, works out-of-the-box with no additional changes.

## RenderContext

`RenderContext` is an internal type; it's forward-declared, so it's unusable outside of the scope of internal development. There have been some "breaking" changes here - the API has been updated to, instead of passing in `MTKView` around, using `id<RiveMetalDrawableView>`. This had to be changed, regardless, since visionOS does not have `MTKView`. The choice to use a protocol was because it forces a little more explicit initialization across platforms, rather than having a parent class that acts as an abstract class, but isn't abstract because it still needs some default values, but those values are different based on device and API availability, etc. We could've passed around `RiveMTKView` as the type, but with a protocol, there's a possibility of being able to use a type that isn't exactly a view, but might want to still act against the drawing process. Personal choice, really.

## RiveRendererView

`RiveRendererView` is now a subclass of `RiveMTKView`. `RiveMTKView`'s superclass depends on the device:
- On visionOS, this is a `UIView` with an underlying `CAMetalLayer`
- On all other platforms, `MTKView`

This new class conforms to `RiveMetalDrawableView`, which allows it to be passed to `RenderContext` types.

### RiveMTKView (visionOS)

`RiveMTKView` on visionOS is a subclass of `UIView` that is backed by a `CAMetalLayer`, providing the necessary properties of `RiveMetalDrawableView` (compile-time safety here, baby). This is quite a simple recreation of the default `MTKView`, since that type is not available on visionOS (thanks, Apple).

## Other things

Additional compile-time checks for platform OS have been added to make sure each new platform compiles with the correct APIs that can be shared, or otherwise newly implemented.

Diffs=
6f70a0e803 Add visionOS and tvOS support to Apple runtime (#8107)

Co-authored-by: David Skuza <david@rive.app>
This commit is contained in:
dskuza
2024-12-11 23:37:59 +00:00
parent 765575c693
commit 08532a7036
65 changed files with 2217 additions and 71 deletions

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -1 +1 @@
f69757c8dd221c54942fee2e47bae55df8f6dc12
6f70a0e803b1eaf43374b98cc4fda6e79163667d

Binary file not shown.

View File

@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,11 @@
{
"images" : [
{
"idiom" : "tv"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.imagestacklayer"
},
{
"filename" : "Middle.imagestacklayer"
},
{
"filename" : "Back.imagestacklayer"
}
]
}

View File

@@ -0,0 +1,11 @@
{
"images" : [
{
"idiom" : "tv"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,11 @@
{
"images" : [
{
"idiom" : "tv"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.imagestacklayer"
},
{
"filename" : "Middle.imagestacklayer"
},
{
"filename" : "Back.imagestacklayer"
}
]
}

View File

@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -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
}
}

View File

@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -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()
}

View File

@@ -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()
}
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.solidimagestacklayer"
},
{
"filename" : "Middle.solidimagestacklayer"
},
{
"filename" : "Back.solidimagestacklayer"
}
]
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -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()
}

View File

@@ -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()
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
<string>UIWindowSceneSessionRoleApplication</string>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict/>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -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"
}
}

View File

@@ -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
}
]
}
}

View File

@@ -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"
}
}

View File

@@ -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: []),
]
)

View File

@@ -0,0 +1,3 @@
# RealityKitContent
A description of this package.

View File

@@ -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 = </Root/GridMaterial/MaterialXPreviewSurface.outputs:out>
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 = </Root/GridMaterial/Remap.outputs:out>
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 = </Root/GridMaterial/Texcoord.outputs:out>
float2 inputs:in2 = (32, 15)
float2 inputs:in2.connect = </Root/GridMaterial/LineCounts.outputs:out>
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 = </Root/GridMaterial/Multiply.outputs:out>
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 = </Root/GridMaterial/Combine3.outputs:out>
color3f inputs:inhigh.connect = None
color3f inputs:inlow.connect = None
color3f inputs:outhigh.connect = </Root/GridMaterial/BaseColor.outputs:out>
color3f inputs:outlow.connect = </Root/GridMaterial/LineColor.outputs:out>
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 = </Root/GridMaterial/Range.outputs:out>
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 = </Root/GridMaterial/Min.outputs:out>
float inputs:in2.connect = </Root/GridMaterial/Min.outputs:out>
float inputs:in3.connect = </Root/GridMaterial/Min.outputs:out>
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 = </Root/GridMaterial/Absval.outputs:out>
float2 inputs:inhigh.connect = </Root/GridMaterial/LineWidths.outputs:out>
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 = </Root/GridMaterial/Fractional.outputs:out>
float2 inputs:in2.connect = </Root/GridMaterial/LineWidths.outputs:out>
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 = </Root/GridMaterial/Subtract.outputs:out>
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 = </Root/GridMaterial/Separate2.outputs:outx>
float inputs:in2.connect = </Root/GridMaterial/Separate2.outputs:outy>
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
}
}
}

View File

@@ -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 = </Root/GridMaterial/GridMaterial> (
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"]
}
}

View File

@@ -0,0 +1,4 @@
import Foundation
/// Bundle for the RealityKitContent project
public let realityKitContentBundle = Bundle.module

View File

@@ -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 = "<group>"; };
E5CD7D7027DC331900BFE5E2 /* SwiftMeshAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftMeshAnimation.swift; sourceTree = "<group>"; };
E5E87A002AE5A83700E7295F /* SwiftVariableFPS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftVariableFPS.swift; sourceTree = "<group>"; };
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 = "<group>"; };
F22138802CCBEDD400A25BA7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
F22138822CCBEDD500A25BA7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
F22138872CCBEDD500A25BA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F26E20A92CF0E21000130111 /* streaming.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = streaming.riv; sourceTree = "<group>"; };
F2B7F2F72C5AC09200F47FBC /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = "<group>"; };
F2C623352C874E3A0006E0CA /* fallback_fonts.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = fallback_fonts.riv; sourceTree = "<group>"; };
F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftFallbackFonts.swift; sourceTree = "<group>"; };
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 = "<group>"; };
F2C852D52CD1772300F0D81F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
F2C852D72CD1772400F0D81F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
F8DA7B442AF523A800FF3CBF /* DismissableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissableView.swift; sourceTree = "<group>"; };
/* 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 = "<group>";
@@ -743,6 +816,53 @@
name = Frameworks;
sourceTree = "<group>";
};
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 = "<group>";
};
F22138842CCBEDD500A25BA7 /* Preview Content */ = {
isa = PBXGroup;
children = (
F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
F2B7F2F62C5AC09200F47FBC /* Packages */ = {
isa = PBXGroup;
children = (
F2B7F2F72C5AC09200F47FBC /* RealityKitContent */,
);
path = Packages;
sourceTree = "<group>";
};
F2C852D22CD1772300F0D81F /* Example (tvOS) */ = {
isa = PBXGroup;
children = (
F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */,
F2C852D52CD1772300F0D81F /* ContentView.swift */,
F2C852D72CD1772400F0D81F /* Assets.xcassets */,
F2C852D92CD1772400F0D81F /* Preview Content */,
);
path = "Example (tvOS)";
sourceTree = "<group>";
};
F2C852D92CD1772400F0D81F /* Preview Content */ = {
isa = PBXGroup;
children = (
F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
/* 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 */

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2C852D02CD1772300F0D81F"
BuildableName = "Example (tvOS).app"
BlueprintName = "Example (tvOS)"
ReferencedContainer = "container:RiveExample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2C852D02CD1772300F0D81F"
BuildableName = "Example (tvOS).app"
BlueprintName = "Example (tvOS)"
ReferencedContainer = "container:RiveExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F2C852D02CD1772300F0D81F"
BuildableName = "Example (tvOS).app"
BlueprintName = "Example (tvOS)"
ReferencedContainer = "container:RiveExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -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 }

View File

@@ -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)

View File

@@ -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 = "<group>"; };
F23626A92C8F90FA00727D9A /* nested_text_run.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = nested_text_run.riv; sourceTree = "<group>"; };
F23992E62CB9C1C60021EF61 /* RenderContextTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RenderContextTests.m; sourceTree = "<group>"; };
F2610DD12CA5B4C40090D50B /* RiveLogger+StateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+StateMachine.swift"; sourceTree = "<group>"; };
F2610DD32CA5B5460090D50B /* RiveLogger+Artboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+Artboard.swift"; sourceTree = "<group>"; };
F2610DD52CA5B5DD0090D50B /* RiveLogger+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+ViewModel.swift"; sourceTree = "<group>"; };
F2610DD72CA5B6570090D50B /* RiveLogger+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+Model.swift"; sourceTree = "<group>"; };
F2610DD92CA5B84B0090D50B /* RiveLogger+File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+File.swift"; sourceTree = "<group>"; };
F2610DE02CA5FBE30090D50B /* RiveLogger+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+View.swift"; sourceTree = "<group>"; };
F23992E62CB9C1C60021EF61 /* RenderContextTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RenderContextTests.m; sourceTree = "<group>"; };
F28DE4522C5002D900F3C379 /* RiveModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveModelTests.swift; sourceTree = "<group>"; };
F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RiveMetalDrawableView.h; sourceTree = "<group>"; };
F2CCA9782C9B2799007DC0D2 /* referenced_image_asset.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = referenced_image_asset.riv; sourceTree = "<group>"; };
F2CCA9C12C9E13BA007DC0D2 /* RiveLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveLogger.swift; sourceTree = "<group>"; };
F2D285482C6D469900728340 /* RiveFallbackFontProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontProvider.swift; sourceTree = "<group>"; };
@@ -281,6 +283,7 @@
043025F92AFA860E00320F2E /* FileAssetLoaderAdapter.hpp */,
043025FD2AFA8FCF00320F2E /* RiveFileAsset.h */,
043026012AFB9FCD00320F2E /* RiveFactory.h */,
F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */,
);
path = include;
sourceTree = "<group>";
@@ -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;
};

View File

@@ -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)

View File

@@ -4,9 +4,11 @@
#import <RenderContextManager.h>
#import <RenderContext.h>
#import <RiveMetalDrawableView.h>
#import <Rive.h>
#import <RivePrivateHeaders.h>
#import <RiveFactory.h>
#import <rive_renderer_view.hh>
#include "utils/auto_cf.hpp"
#include "cg_factory.hpp"
@@ -25,10 +27,12 @@ static CGSize Maximum2DTextureSizeFromDevice(id<MTLDevice> 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<MTLDevice> device)
return nil;
}
- (rive::Renderer*)beginFrame:(MTKView*)view
- (rive::Renderer*)beginFrame:(id<RiveMetalDrawableView>)view
{
return nil;
}
- (void)endFrame:(MTKView*)view
- (void)endFrame:(id<RiveMetalDrawableView>)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
{}
@@ -128,7 +132,6 @@ static CGSize Maximum2DTextureSizeFromDevice(id<MTLDevice> 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<rive::gpu::RenderContext> make_pls_context_native(
return _renderContext;
}
- (rive::Renderer*)beginFrame:(MTKView*)view
- (rive::Renderer*)beginFrame:(id<RiveMetalDrawableView>)view
{
id<CAMetalDrawable> surface = view.currentDrawable;
if (!surface.texture)
@@ -219,7 +222,7 @@ static std::unique_ptr<rive::gpu::RenderContext> make_pls_context_native(
return _renderer.get();
}
- (void)endFrame:(MTKView*)view
- (void)endFrame:(id<RiveMetalDrawableView>)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
{
id<MTLCommandBuffer> flushCommandBuffer = [self.metalQueue commandBuffer];
@@ -249,7 +252,7 @@ static std::unique_ptr<rive::gpu::RenderContext> make_pls_context_native(
@end
@interface CGRendererContext : RenderContext
- (rive::Renderer*)beginFrame:(MTKView*)view;
- (rive::Renderer*)beginFrame:(id<RiveMetalDrawableView>)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<RiveMetalDrawableView>)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<RiveMetalDrawableView>)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
{
if (_cgContext != nil)

View File

@@ -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<RiveMetalDrawableView>)view;
- (void)endFrame:(id<RiveMetalDrawableView>)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
- (BOOL)canDrawInRect:(CGRect)rect
drawableSize:(CGSize)drawableSize
drawableSize:(CGSize)size
scale:(CGFloat)scale;
@end

View File

@@ -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(_:));

View File

@@ -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 <Metal/Metal.h>
@protocol RiveMetalDrawableView
@property(nullable, nonatomic, retain) id<MTLDevice> 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<CAMetalDrawable> currentDrawable;
@property(nonatomic) MTLPixelFormat colorPixelFormat;
@property(nonatomic) CGSize drawableSize;
@end
#endif /* RiveMetalDrawableView_h */

View File

@@ -1,12 +1,22 @@
#import <MetalKit/MetalKit.h>
#import <RiveRuntime/RiveArtboard.h>
#import <RiveRuntime/Rive.h>
#import <RiveRuntime/RiveMetalDrawableView.h>
#import <Metal/Metal.h>
#if TARGET_OS_VISION
@interface RiveMTKView : UIView <RiveMetalDrawableView>
- (nonnull instancetype)initWithFrame:(CGRect) frameRect device:(nullable id<MTLDevice>) device;
@end
#else
@interface RiveMTKView : MTKView <RiveMetalDrawableView>
@end
#endif
NS_ASSUME_NONNULL_BEGIN
@interface RiveRendererView : MTKView
@interface RiveRendererView : RiveMTKView
- (instancetype)initWithFrame:(CGRect)frameRect;
/// Deprecated. Use `alignWithRect:contentRect:alignment:fit:scaleFactor:` instead.

View File

@@ -3,7 +3,7 @@
#import <Metal/Metal.h>
#import <MetalKit/MetalKit.h>
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE || TARGET_VISION_OS || TARGET_OS_TV
#import <UIKit/UIKit.h>
#else
#import <AppKit/AppKit.h>
@@ -17,6 +17,138 @@
#define WITH_RIVE_AUDIO
#include "rive/audio/audio_engine.hpp"
#if TARGET_OS_VISION
@implementation RiveMTKView
{
id<CAMetalDrawable> _currentDrawable;
}
@synthesize enableSetNeedsDisplay;
@synthesize paused;
@synthesize sampleCount;
@synthesize depthStencilPixelFormat;
- (instancetype)initWithFrame:(CGRect)frameRect device:(id<MTLDevice>)device
{
self = [super initWithFrame:frameRect];
self.device = device;
return self;
}
+ (Class)layerClass
{
return [CAMetalLayer class];
}
- (nullable id<MTLDevice>)device
{
return [self metalLayer].device;
}
- (void)setDevice:(nullable id<MTLDevice>)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<CAMetalDrawable> _Nullable)currentDrawable
{
return;
}
- (nullable id<CAMetalDrawable>)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:)

View File

@@ -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<UITouch>, 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)?

View File

@@ -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

View File

@@ -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 <all|ios|ios_sim|macosx> <debug|release>"
echo "USAGE: $0 <all|ios|ios_sim|xros|xrsimulator|appletvos|appletvsimulator|macosx> <debug|release>"
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
;;

View File

@@ -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

View File

@@ -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