Added in default state machines

This commit is contained in:
Zachary Duncan
2022-07-05 16:27:50 -04:00
committed by Zachary Duncan
parent 4948e746b1
commit dcc6d8dd18
9 changed files with 89 additions and 39 deletions

View File

@@ -35,6 +35,8 @@ class StateMachineView: UIView {
}
class StateMachineViewController: UIViewController {
// MARK: RiveViewModel
// This view model specifies the exact StateMachine that it wants from the file
var viewModel = RiveViewModel(fileName: "skills", stateMachineName: "Designer's Test")
override public func loadView() {
@@ -47,16 +49,16 @@ class StateMachineViewController: UIViewController {
viewModel.setView(stateMachineView.riveView)
stateMachineView.beginnerButtonAction = {
try? self.viewModel.setInput("Level", value: 0.0)
self.viewModel.setInput("Level", value: 0.0)
}
stateMachineView.intermediateButtonAction = {
try? self.viewModel.setInput("Level", value: 1.0)
self.viewModel.setInput("Level", value: 1.0)
}
stateMachineView.expertButtonAction = {
try? self.viewModel.setInput("Level", value: 2.0)
self.viewModel.setInput("Level", value: 2.0)
}
stateMachineView.resetButtonAction = {
try? self.viewModel.reset()
self.viewModel.reset()
}
}

View File

@@ -13,6 +13,11 @@ struct SwiftCannonGame: DismissableView {
var dismiss: () -> Void = {}
var body: some View {
RiveViewModel(fileName: "bullet_man_game", stateMachineName: "State Machine 1").view()
// MARK: RiveViewModel
// This view model controls a file configured with:
// - StateMachine
// - Listeners
RiveViewModel(fileName: "bullet_man_game").view()
}
}

View File

@@ -10,16 +10,19 @@ import SwiftUI
import RiveRuntime
struct SwiftMeshAnimation: DismissableView {
var dismiss: () -> Void = {}
// MARK: RiveViewModel
// This view model specifies the exact StateMachine that it wants from the file
var tapePlayer = RiveViewModel(fileName: "prop_example", stateMachineName: "State Machine 1")
@State var isTapped: Bool = false
var dismiss: () -> Void = {}
var body: some View {
tapePlayer.view()
.aspectRatio(1, contentMode: .fit)
.onTapGesture {
isTapped = !isTapped
try? tapePlayer.setInput("Hover", value: isTapped)
tapePlayer.setInput("Hover", value: isTapped)
}
}
}

View File

@@ -10,9 +10,13 @@ import SwiftUI
import RiveRuntime
struct SwiftStateMachine: DismissableView {
var stateChanger = RiveViewModel(fileName: "skills", stateMachineName: "Designer's Test")
var dismiss: () -> Void = {}
// MARK: RiveViewModel
// This view model specifies the exact StateMachine that it wants from the file
var stateChanger = RiveViewModel(fileName: "skills", stateMachineName: "Designer's Test")
var body: some View {
ScrollView{
VStack {
@@ -21,13 +25,13 @@ struct SwiftStateMachine: DismissableView {
HStack{
Button("Beginner") {
try? stateChanger.setInput("Level", value: 0.0)
stateChanger.setInput("Level", value: 0.0)
}
Button("Intermediate") {
try? stateChanger.setInput("Level", value: 1.0)
stateChanger.setInput("Level", value: 1.0)
}
Button("Expert") {
try? stateChanger.setInput("Level", value: 2.0)
stateChanger.setInput("Level", value: 2.0)
}
}

View File

@@ -11,13 +11,19 @@ import RiveRuntime
struct SwiftTouchEvents: DismissableView {
var dismiss: () -> Void = {}
// MARK: RiveViewModels
// Each of the these view models controls a file configured with:
// - State Machine
// - Listeners
@StateObject var clock = ClockViewModel()
@StateObject var jelly = RiveViewModel(fileName: "hero_editor", stateMachineName: "Jellyfish")
@StateObject var playButton = RiveViewModel(fileName: "play_button_event_example", stateMachineName: "State Machine")
@StateObject var lighthouse = RiveViewModel(fileName: "switch_event_example", stateMachineName: "Main State Machine")
@StateObject var eightball = RiveViewModel(fileName: "magic_8-ball_v2", stateMachineName: "Main State Machine")
@StateObject var bearGuy = RiveViewModel(fileName: "leg_day_events_example", stateMachineName: "Don't Skip Leg Day")
@StateObject var toggle = RiveViewModel(fileName: "light_switch", stateMachineName: "Switch")
@StateObject var jelly = RiveViewModel(fileName: "hero_editor")
@StateObject var playButton = RiveViewModel(fileName: "play_button_event_example")
@StateObject var lighthouse = RiveViewModel(fileName: "switch_event_example")
@StateObject var eightball = RiveViewModel(fileName: "magic_8-ball_v2")
@StateObject var bearGuy = RiveViewModel(fileName: "leg_day_events_example")
@StateObject var toggle = RiveViewModel(fileName: "light_switch")
var body: some View {
ScrollView {

View File

@@ -30,43 +30,56 @@ open class RiveModel: ObservableObject {
open func setArtboard(_ name: String) throws {
do { artboard = try riveFile.artboard(fromName: name) }
catch { throw RiveModelError.invalidArtboard(name: name) }
catch { throw RiveModelError.invalidArtboard("Name \(name) not found") }
}
open func setArtboard(_ index: Int? = nil) throws {
if let index = index {
do { artboard = try riveFile.artboard(from: index) }
catch { throw RiveModelError.invalidArtboard(index: index) }
catch { throw RiveModelError.invalidArtboard("Index \(index) not found") }
} else {
// This tries to find the 'default' Artboard
do { artboard = try riveFile.artboard() }
catch { throw RiveModelError.invalidArtboard(message: "No Default Artboard") }
catch { throw RiveModelError.invalidArtboard("No Default Artboard") }
}
}
open func setStateMachine(_ name: String) throws {
do { stateMachine = try artboard.stateMachine(fromName: name) }
catch { throw RiveModelError.invalidStateMachine(name: name) }
catch { throw RiveModelError.invalidStateMachine("Name \(name) not found") }
}
open func setStateMachine(_ index: Int? = nil) throws {
// Defaults to 0 as it's assumed to be the first element in the collection
let index = index ?? 0
do { stateMachine = try artboard.stateMachine(from: index) }
catch { throw RiveModelError.invalidStateMachine(index: index) }
do {
// Set by index
if let index = index {
stateMachine = try artboard.stateMachine(from: index)
}
// Set from Artboard's default StateMachine configured in editor
else if let defaultStateMachine = artboard.defaultStateMachine() {
stateMachine = defaultStateMachine
}
// Set by index 0 as a fallback
else {
stateMachine = try artboard.stateMachine(from: 0)
}
}
catch { throw RiveModelError.invalidStateMachine("Index \(index ?? 0) not found") }
}
open func setAnimation(_ name: String) throws {
guard animation?.name() != name else { return }
do { animation = try artboard.animation(fromName: name) }
catch { throw RiveModelError.invalidAnimation(name: name) }
catch { throw RiveModelError.invalidAnimation("Name \(name) not found") }
}
open func setAnimation(_ index: Int? = nil) throws {
// Defaults to 0 as it's assumed to be the first element in the collection
let index = index ?? 0
do { animation = try artboard.animation(from: index) }
catch { throw RiveModelError.invalidAnimation(index: index) }
catch { throw RiveModelError.invalidAnimation("Index \(index) not found") }
}
// MARK: -
@@ -86,8 +99,8 @@ open class RiveModel: ObservableObject {
}
enum RiveModelError: Error {
case invalidStateMachine(name: String), invalidStateMachine(index: Int)
case invalidAnimation(name: String), invalidAnimation(index: Int)
case invalidArtboard(name: String), invalidArtboard(index: Int), invalidArtboard(message: String)
case invalidStateMachine(_ message: String)
case invalidAnimation(_ message: String)
case invalidArtboard(_ message: String)
}
}

View File

@@ -226,28 +226,35 @@ open class RiveViewModel: NSObject, ObservableObject, RiveFileDelegate, RiveStat
/// Instantiates elements in the model needed to play in a `RiveView`
private func configureModel(artboardName: String? = nil, stateMachineName: String? = nil, animationName: String? = nil) throws {
guard let model = riveModel else { fatalError("Cannot configure nil RiveModel") }
if let name = artboardName {
try riveModel?.setArtboard(name)
try model.setArtboard(name)
} else {
// Keep current Artboard if there is one
if riveModel?.artboard == nil {
if model.artboard == nil {
// Set default Artboard if not
try riveModel?.setArtboard()
try model.setArtboard()
}
}
riveModel?.animation = nil
riveModel?.stateMachine = nil
model.animation = nil
model.stateMachine = nil
if let name = stateMachineName {
try riveModel?.setStateMachine(name)
try model.setStateMachine(name)
}
else if let name = animationName {
try riveModel?.setAnimation(name)
try model.setAnimation(name)
}
// Find defaults
else {
// Set default Animation
try riveModel?.setAnimation()
// Attempts to set a default StateMachine first
if ((try? model.setStateMachine()) == nil) {
// If it fails, attempts a default Animation
try model.setAnimation()
}
}
}

View File

@@ -114,6 +114,15 @@ static int artInstanceCount = 0;
return [[RiveStateMachineInstance alloc] initWithStateMachine: machine];
}
- (RiveStateMachineInstance *)defaultStateMachine {
rive::StateMachineInstance *machine = _artboardInstance->defaultStateMachine().release();
if (machine == nullptr) {
// *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No default State Machine found."], @"name": @"NoStateMachineFound"}];
return nil;
}
return [[RiveStateMachineInstance alloc] initWithStateMachine:machine];
}
- (NSArray *)stateMachineNames{
NSMutableArray *stateMachineNames = [NSMutableArray array];
for (NSUInteger i=0; i<[self stateMachineCount]; i++){

View File

@@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSArray<NSString *> *)stateMachineNames;
- (RiveStateMachineInstance * __nullable)stateMachineFromIndex:(NSInteger)index error:(NSError **)error;
- (RiveStateMachineInstance * __nullable)stateMachineFromName:(NSString *)name error:(NSError **)error;
- (RiveStateMachineInstance * __nullable)defaultStateMachine;
- (void)advanceBy:(double)elapsedSeconds;
- (void)draw:(RiveRenderer *)renderer;