Skip to content

Commit

Permalink
Add ability to set iOS artboard volume through RiveModel
Browse files Browse the repository at this point in the history
Updates the `RiveModel` API with the ability to set and get the volume for the currently set artboard. Any new artboards will default to use the last-set volume of the model. A volume default of 1.0 is set to match rive-cpp's default. `RiveArtboard` is also updated to forward volume calls to the artboard instance, exposing a new `volume` property.

There's an open question whether this belongs in `RiveViewModel`, or `RiveModel`, but I went for `RiveModel` since there's a direct reference to the artboard within the model itself, and an indirect reference through the view model (model?.artboard)

Diffs=
a31cd9761 Add ability to set iOS artboard volume through RiveModel (#7658)

Co-authored-by: David Skuza <david@rive.app>
  • Loading branch information
dskuza and dskuza committed Jul 23, 2024
1 parent 164e65c commit e77bda6
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
114da4e39ba61dd337e8f6f47c1c7b2fb2223915
a31cd9761efdc411d4c462f065e37d84af04984c
6 changes: 5 additions & 1 deletion Example-iOS/Source/Examples/SwiftUI/SwiftAudioAssets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ struct SwiftAudioAssets: DismissableView {
);

var body: some View {
riveViewModel.view()
riveViewModel
.view()
.onAppear {
riveViewModel.riveModel?.volume = 0.01
}
}
}
4 changes: 4 additions & 0 deletions RiveRuntime.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
E5964A982A9697B600140479 /* RiveEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5964A972A9697B600140479 /* RiveEvent.mm */; };
E599DCF92AAFA06100D1E49A /* rating_animation.riv in Resources */ = {isa = PBXBuildFile; fileRef = E599DCF82AAFA06100D1E49A /* rating_animation.riv */; };
E599DCFA2AAFA06100D1E49A /* rating_animation.riv in Resources */ = {isa = PBXBuildFile; fileRef = E599DCF82AAFA06100D1E49A /* rating_animation.riv */; };
F28DE4532C5002D900F3C379 /* RiveModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F28DE4522C5002D900F3C379 /* RiveModelTests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -198,6 +199,7 @@
E5964A952A965A9300140479 /* RiveEvent.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = RiveEvent.h; sourceTree = "<group>"; };
E5964A972A9697B600140479 /* RiveEvent.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RiveEvent.mm; sourceTree = "<group>"; };
E599DCF82AAFA06100D1E49A /* rating_animation.riv */ = {isa = PBXFileReference; lastKnownFileType = file; name = rating_animation.riv; path = "Example-iOS/Assets/rating_animation.riv"; sourceTree = SOURCE_ROOT; };
F28DE4522C5002D900F3C379 /* RiveModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveModelTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -389,6 +391,7 @@
04BE542C264C1A3300427B39 /* RiveDelegatesTest.swift */,
C38BB5F528762B720039E385 /* RiveStateMachineTest.swift */,
041265252B0CB41E009400EC /* OutOfBandAssetTest.mm */,
F28DE4522C5002D900F3C379 /* RiveModelTests.swift */,
);
path = Tests;
sourceTree = "<group>";
Expand Down Expand Up @@ -594,6 +597,7 @@
04BE541C264A90D600427B39 /* RiveAnimationLoadTest.mm in Sources */,
C9C73EE024FC478900EF9516 /* RiveRuntimeTests.mm in Sources */,
04BE5413264943BB00427B39 /* util.mm in Sources */,
F28DE4532C5002D900F3C379 /* RiveModelTests.swift in Sources */,
04BE54112649434900427B39 /* RiveFileLoadTest.mm in Sources */,
C38BB5F628762B720039E385 /* RiveStateMachineTest.swift in Sources */,
04BE5418264A818F00427B39 /* RiveAnimationConfigurationsTest.mm in Sources */,
Expand Down
10 changes: 10 additions & 0 deletions Source/Renderer/RiveArtboard.mm
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,14 @@ - (RiveSMINumber*)getNumber:(NSString*)name path:(NSString*)path
}
}

- (float)volume
{
return _artboardInstance->volume();
}

- (void)setVolume:(float)volume
{
_artboardInstance->volume(volume);
}

@end
2 changes: 2 additions & 0 deletions Source/Renderer/include/RiveArtboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
//
@interface RiveArtboard : NSObject

@property(nonatomic, assign) float volume NS_REFINED_FOR_SWIFT;

- (NSString*)name;
- (CGRect)bounds;

Expand Down
29 changes: 27 additions & 2 deletions Source/RiveModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,27 @@ import Combine
public init(webURL: String, delegate: RiveFileDelegate, loadCdn: Bool) {
riveFile = RiveFile(httpUrl: webURL, loadCdn:loadCdn, with: delegate)!
}


// rive-cpp defaults the volume to 1.0f
// This value is used if there is no artboard,
// and will be used to set the volume once a model is configured (with an artboard)
private var _volume: Float = 1

/// The volume of the current artboard, if available. Defaults to 1.
@objc open var volume: Float {
get {
if let volume = artboard?.__volume {
return volume
}

return _volume
}
set {
_volume = newValue
artboard?.__volume = newValue
}
}

// MARK: - Setters

/// Sets a new Artboard and makes the current StateMachine and Animation nil
Expand All @@ -36,6 +56,7 @@ import Combine
stateMachine = nil
animation = nil
artboard = try riveFile.artboard(fromName: name)
artboard.__volume = _volume
}
catch { throw RiveModelError.invalidArtboard("Name \(name) not found") }
}
Expand All @@ -47,11 +68,15 @@ import Combine
stateMachine = nil
animation = nil
artboard = try riveFile.artboard(from: index)
artboard.__volume = _volume
}
catch { throw RiveModelError.invalidArtboard("Index \(index) not found") }
} else {
// This tries to find the 'default' Artboard
do { artboard = try riveFile.artboard() }
do {
artboard = try riveFile.artboard()
artboard.__volume = _volume
}
catch { throw RiveModelError.invalidArtboard("No Default Artboard") }
}
}
Expand Down
1 change: 0 additions & 1 deletion Source/RiveViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ import Combine
didSet { riveView?.fit = fit }
}


open var alignment: RiveAlignment = .center {
didSet { riveView?.alignment = alignment }
}
Expand Down
38 changes: 38 additions & 0 deletions Tests/RiveModelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// RiveModelTests.swift
// RiveRuntimeTests
//
// Created by David Skuza on 7/23/24.
// Copyright © 2024 Rive. All rights reserved.
//

import XCTest
@testable import RiveRuntime

class RiveModelTests: XCTestCase {
func test_volume() throws {
let file = try RiveFile(testfileName: "multipleartboards")
let model = RiveModel(riveFile: file)

XCTAssertEqual(model.volume, 1)

do {
try model.setArtboard()

model.volume = 0.5
XCTAssertEqual(model.volume, 0.5)
XCTAssertEqual(model.artboard?.__volume, 0.5)
}

do {
try model.setArtboard("artboard2")

XCTAssertEqual(model.volume, 0.5)
XCTAssertEqual(model.artboard?.__volume, 0.5)

model.volume = 0
XCTAssertEqual(model.volume, 0)
XCTAssertEqual(model.artboard?.__volume, 0)
}
}
}

0 comments on commit e77bda6

Please sign in to comment.