mirror of
https://github.com/rive-app/rive-ios.git
synced 2026-01-18 17:11:28 +01:00
RiveScene no longer maintains an instance of rive::Scene
This commit is contained in:
@@ -17,7 +17,7 @@ struct SwiftLayout: DismissableView {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
RiveViewModel(fileName: "off_road_car_blog", fit: fit, alignment: alignment).view()
|
||||
RiveViewModel(fileName: "truck_v7", fit: fit, alignment: alignment).view()
|
||||
}
|
||||
HStack {
|
||||
Text("Fit")
|
||||
|
||||
@@ -12,12 +12,12 @@ import RiveRuntime
|
||||
struct SwiftTouchEvents: DismissableView {
|
||||
var dismiss: () -> Void = {}
|
||||
@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 {
|
||||
|
||||
@@ -153,8 +153,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
046FB7E7264EAA5F000129B1 /* RiveFile.h */,
|
||||
C39E7647285AE42500D30612 /* RiveScene.hpp */,
|
||||
046FB7EC264EAA60000129B1 /* RiveArtboard.h */,
|
||||
C39E7647285AE42500D30612 /* RiveScene.hpp */,
|
||||
046FB7E1264EAA5E000129B1 /* RiveLinearAnimationInstance.h */,
|
||||
046FB7F0264EAA60000129B1 /* RiveStateMachineInstance.h */,
|
||||
046FB7EB264EAA60000129B1 /* RiveSMIInput.h */,
|
||||
@@ -210,8 +210,8 @@
|
||||
children = (
|
||||
046FB801264EB632000129B1 /* include */,
|
||||
046FB7EF264EAA60000129B1 /* RiveFile.mm */,
|
||||
C39E764A285AE51900D30612 /* RiveScene.mm */,
|
||||
046FB7E2264EAA5E000129B1 /* RiveArtboard.mm */,
|
||||
C39E764A285AE51900D30612 /* RiveScene.mm */,
|
||||
046FB7E4264EAA5F000129B1 /* RiveLinearAnimationInstance.mm */,
|
||||
046FB7E8264EAA5F000129B1 /* RiveStateMachineInstance.mm */,
|
||||
046FB7E5264EAA5F000129B1 /* RiveSMIInput.mm */,
|
||||
|
||||
@@ -11,17 +11,9 @@ import Foundation
|
||||
open class RiveModel: ObservableObject {
|
||||
internal private(set) var riveFile: RiveFile
|
||||
public private(set) var artboard: RiveArtboard!
|
||||
public internal(set) var scene: RiveScene!
|
||||
public internal(set) var stateMachine: RiveStateMachineInstance? {
|
||||
didSet {
|
||||
scene = stateMachine ?? scene
|
||||
}
|
||||
}
|
||||
public internal(set) var animation: RiveLinearAnimationInstance? {
|
||||
didSet {
|
||||
scene = animation ?? scene
|
||||
}
|
||||
}
|
||||
public internal(set) var stateMachine: RiveStateMachineInstance?
|
||||
public internal(set) var animation: RiveLinearAnimationInstance?
|
||||
public weak var scene: RiveScene? { stateMachine ?? animation }
|
||||
|
||||
public init(riveFile: RiveFile) {
|
||||
self.riveFile = riveFile
|
||||
@@ -38,49 +30,68 @@ open class RiveModel: ObservableObject {
|
||||
// MARK: - Setters
|
||||
|
||||
open func setArtboard(_ name: String) throws {
|
||||
artboard = try riveFile.artboard(fromName: name)
|
||||
do { artboard = try riveFile.artboard(fromName: name) }
|
||||
catch { throw RiveModelError.invalidArtboard("Name \(name) not found") }
|
||||
}
|
||||
|
||||
open func setArtboard(_ index: Int? = nil) throws {
|
||||
if let index = index {
|
||||
artboard = try riveFile.artboard(from: index)
|
||||
}
|
||||
else {
|
||||
// Tries to find the 'default' Artboard
|
||||
artboard = try riveFile.defaultArtboard()
|
||||
}
|
||||
}
|
||||
|
||||
open func setStateMachine(_ name: String) throws {
|
||||
stateMachine = try artboard.stateMachine(fromName: name)
|
||||
}
|
||||
|
||||
open func setStateMachine(_ index: Int? = nil) throws {
|
||||
if let index = index {
|
||||
stateMachine = try artboard.stateMachine(from: index)
|
||||
do { artboard = try riveFile.artboard(from: index) }
|
||||
catch { throw RiveModelError.invalidArtboard("Index \(index) not found") }
|
||||
} else {
|
||||
// Tries to find the 'default' StateMachine
|
||||
stateMachine = try artboard.defaultStateMachine()
|
||||
// This tries to find the 'default' Artboard
|
||||
do { artboard = try riveFile.defaultArtboard() }
|
||||
catch { throw RiveModelError.invalidArtboard("No Default Artboard") }
|
||||
}
|
||||
}
|
||||
|
||||
open func setDefaultScene() throws {
|
||||
let newScene = try artboard.defaultScene()
|
||||
if newScene is RiveStateMachineInstance {
|
||||
stateMachine = newScene as? RiveStateMachineInstance
|
||||
} else {
|
||||
animation = newScene as? RiveLinearAnimationInstance
|
||||
let scene = try artboard.defaultScene()
|
||||
|
||||
if scene is RiveStateMachineInstance {
|
||||
stateMachine = scene as? RiveStateMachineInstance
|
||||
}
|
||||
else {
|
||||
animation = scene as? RiveLinearAnimationInstance
|
||||
}
|
||||
}
|
||||
|
||||
open func setStateMachine(_ name: String) throws {
|
||||
do { stateMachine = try artboard.stateMachine(fromName: name) }
|
||||
catch { throw RiveModelError.invalidStateMachine("Name \(name) not found") }
|
||||
}
|
||||
|
||||
open func setStateMachine(_ index: Int? = nil) throws {
|
||||
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 {
|
||||
animation = try artboard.animation(fromName: name)
|
||||
guard animation?.name() != name else { return }
|
||||
do { animation = try artboard.animation(fromName: 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
|
||||
animation = try artboard.animation(from: index)
|
||||
do { animation = try artboard.animation(from: index) }
|
||||
catch { throw RiveModelError.invalidAnimation("Index \(index) not found") }
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
@@ -98,4 +109,10 @@ open class RiveModel: ObservableObject {
|
||||
return art + "]"
|
||||
}
|
||||
}
|
||||
|
||||
enum RiveModelError: Error {
|
||||
case invalidStateMachine(_ message: String)
|
||||
case invalidAnimation(_ message: String)
|
||||
case invalidArtboard(_ message: String)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ 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("Attempting to configure nil RiveModel") }
|
||||
guard let model = riveModel else { fatalError("Cannot configure nil RiveModel") }
|
||||
|
||||
if let name = artboardName {
|
||||
try model.setArtboard(name)
|
||||
@@ -238,7 +238,6 @@ open class RiveViewModel: NSObject, ObservableObject, RiveFileDelegate, RiveStat
|
||||
}
|
||||
}
|
||||
|
||||
model.scene = nil
|
||||
model.animation = nil
|
||||
model.stateMachine = nil
|
||||
|
||||
@@ -249,7 +248,6 @@ open class RiveViewModel: NSObject, ObservableObject, RiveFileDelegate, RiveStat
|
||||
try model.setAnimation(name)
|
||||
}
|
||||
else {
|
||||
// Set either a default Animation or default StateMachine
|
||||
try model.setDefaultScene()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,22 @@
|
||||
|
||||
- (RiveScene *)defaultScene:(NSError **)error {
|
||||
auto scene = _instance->defaultScene();
|
||||
|
||||
if (scene == nullptr) {
|
||||
*error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No default Scene found."], @"name": @"NoSceneFound"}];
|
||||
return nil;
|
||||
}
|
||||
return [[RiveScene alloc] initWithScene:scene.release()];
|
||||
|
||||
// TODO: Fix this disgusting hack
|
||||
// -1 is a magic number that scene gives for
|
||||
// the duration when it represents a state machine
|
||||
if (scene->durationSeconds() == -1) {
|
||||
rive::StateMachineInstance *machineInstance = (rive::StateMachineInstance *)scene.release();
|
||||
return [[RiveStateMachineInstance alloc] initWithStateMachine:machineInstance];
|
||||
} else {
|
||||
rive::LinearAnimationInstance *animInstance = (rive::LinearAnimationInstance *)scene.release();
|
||||
return [[RiveLinearAnimationInstance alloc] initWithAnimation:animInstance];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)animationCount {
|
||||
@@ -66,10 +77,9 @@
|
||||
return _instance->stateMachineCount();
|
||||
}
|
||||
|
||||
- (RiveStateMachineInstance *)defaultStateMachine:(NSError **)error {
|
||||
- (RiveStateMachineInstance *)defaultStateMachine {
|
||||
rive::StateMachineInstance *machine = _instance->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];
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (rive::Scene *)instance {
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (float)time {
|
||||
return instance->time();
|
||||
}
|
||||
|
||||
@@ -9,39 +9,31 @@
|
||||
#import <Rive.h>
|
||||
#import <RivePrivateHeaders.h>
|
||||
|
||||
@implementation RiveScene {
|
||||
rive::Scene *instance;
|
||||
}
|
||||
@implementation RiveScene
|
||||
|
||||
- (instancetype)initWithScene:(rive::Scene *)scene {
|
||||
if (self = [super init]) {
|
||||
instance = scene;
|
||||
return self;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
|
||||
/// StateMachine and Animation instance classes must override this
|
||||
- (rive::Scene *)instance {
|
||||
[NSException raise:@"NotImplemented" format:@"Scene implementation must be overriden"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)name {
|
||||
std::string str = instance->name();
|
||||
std::string str = [self instance]->name();
|
||||
return [NSString stringWithCString:str.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
}
|
||||
|
||||
- (CGRect)bounds {
|
||||
rive::AABB aabb = instance->bounds();
|
||||
rive::AABB aabb = [self instance]->bounds();
|
||||
return CGRectMake(aabb.minX, aabb.minY, aabb.width(), aabb.height());
|
||||
}
|
||||
|
||||
- (bool)advanceBy:(double)elapsedSeconds {
|
||||
return instance->advanceAndApply(elapsedSeconds);
|
||||
return [self instance]->advanceAndApply(elapsedSeconds);
|
||||
}
|
||||
|
||||
- (void)draw:(rive::Renderer *)renderer {
|
||||
instance->draw(renderer);
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
delete instance;
|
||||
[self instance]->draw(renderer);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (rive::Scene *)instance {
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (RiveSMIBool *)getBool:(NSString *)name {
|
||||
// Create a unique dictionary name for numbers;
|
||||
// this lets us use one dictionary for the three different types
|
||||
|
||||
@@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (NSInteger)stateMachineCount;
|
||||
- (NSArray<NSString *> *)stateMachineNames;
|
||||
- (RiveStateMachineInstance * __nullable)defaultStateMachine:(NSError **)error;
|
||||
- (RiveStateMachineInstance * __nullable)defaultStateMachine;
|
||||
- (RiveStateMachineInstance * __nullable)stateMachineFromIndex:(NSInteger)index error:(NSError **)error;
|
||||
- (RiveStateMachineInstance * __nullable)stateMachineFromName:(NSString *)name error:(NSError **)error;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* RiveScene interface
|
||||
*/
|
||||
@interface RiveScene ()
|
||||
- (instancetype)initWithScene:(rive::Scene *)scene;
|
||||
- (rive::Scene *)instance;
|
||||
- (void)draw:(rive::Renderer *)renderer;
|
||||
@end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user