1
0
mirror of https://github.com/rive-app/rive-flutter.git synced 2025-07-12 13:18:00 +08:00

More nnbd work

This commit is contained in:
Luigi Rosso
2021-03-22 21:29:26 -07:00
parent 33ad1c9ac8
commit 88541f1596
87 changed files with 563 additions and 366 deletions
example
lib/src
animation_list.dartcontainer_children.dart
controllers
generated
rive.dart
rive_core
rive_file.dartrive_render_box.dart
utilities

@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
import 'package:rive/rive.dart'; import 'package:rive/rive.dart';
class ExampleAnimation extends StatefulWidget { class ExampleAnimation extends StatefulWidget {
const ExampleAnimation({Key key}) : super(key: key); const ExampleAnimation({Key? key}) : super(key: key);
@override @override
_ExampleAnimationState createState() => _ExampleAnimationState(); _ExampleAnimationState createState() => _ExampleAnimationState();
@ -12,14 +12,17 @@ class ExampleAnimation extends StatefulWidget {
class _ExampleAnimationState extends State<ExampleAnimation> { class _ExampleAnimationState extends State<ExampleAnimation> {
void _togglePlay() { void _togglePlay() {
setState(() => _controller.isActive = !_controller.isActive); if (_controller == null) {
return;
}
setState(() => _controller!.isActive = !_controller!.isActive);
} }
/// Tracks if the animation is playing by whether controller is running. /// Tracks if the animation is playing by whether controller is running.
bool get isPlaying => _controller?.isActive ?? false; bool get isPlaying => _controller?.isActive ?? false;
Artboard _riveArtboard; Artboard? _riveArtboard;
RiveAnimationController _controller; RiveAnimationController? _controller;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -51,7 +54,7 @@ class _ExampleAnimationState extends State<ExampleAnimation> {
body: Center( body: Center(
child: _riveArtboard == null child: _riveArtboard == null
? const SizedBox() ? const SizedBox()
: Rive(artboard: _riveArtboard), : Rive(artboard: _riveArtboard!),
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: _togglePlay, onPressed: _togglePlay,

@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
import 'package:rive/rive.dart'; import 'package:rive/rive.dart';
class ExampleStateMachine extends StatefulWidget { class ExampleStateMachine extends StatefulWidget {
const ExampleStateMachine({Key key}) : super(key: key); const ExampleStateMachine({Key? key}) : super(key: key);
@override @override
_ExampleStateMachineState createState() => _ExampleStateMachineState(); _ExampleStateMachineState createState() => _ExampleStateMachineState();
@ -14,10 +14,10 @@ class _ExampleStateMachineState extends State<ExampleStateMachine> {
/// Tracks if the animation is playing by whether controller is running. /// Tracks if the animation is playing by whether controller is running.
bool get isPlaying => _controller?.isActive ?? false; bool get isPlaying => _controller?.isActive ?? false;
Artboard _riveArtboard; Artboard? _riveArtboard;
StateMachineController _controller; StateMachineController? _controller;
StateMachineInput<bool> _hoverInput; StateMachineInput<bool>? _hoverInput;
StateMachineInput<bool> _pressInput; StateMachineInput<bool>? _pressInput;
@override @override
void initState() { void initState() {
@ -56,17 +56,17 @@ class _ExampleStateMachineState extends State<ExampleStateMachine> {
child: _riveArtboard == null child: _riveArtboard == null
? const SizedBox() ? const SizedBox()
: MouseRegion( : MouseRegion(
onEnter: (_) => _hoverInput.value = true, onEnter: (_) => _hoverInput?.value = true,
onExit: (_) => _hoverInput.value = false, onExit: (_) => _hoverInput?.value = false,
child: GestureDetector( child: GestureDetector(
onTapDown: (_) => _pressInput.value = true, onTapDown: (_) => _pressInput?.value = true,
onTapCancel: () => _pressInput.value = false, onTapCancel: () => _pressInput?.value = false,
onTapUp: (_) => _pressInput.value = false, onTapUp: (_) => _pressInput?.value = false,
child: SizedBox( child: SizedBox(
width: 250, width: 250,
height: 250, height: 250,
child: Rive( child: Rive(
artboard: _riveArtboard, artboard: _riveArtboard!,
), ),
), ),
), ),

@ -1,12 +1,12 @@
name: rive_example name: rive_example
description: A new Flutter project. description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
dependencies: dependencies:
flutter: flutter:

@ -1,10 +1,10 @@
import 'dart:collection'; import 'dart:collection';
import 'package:rive/src/rive_core/animation/animation.dart'; import 'package:rive/src/rive_core/animation/animation.dart';
// TODO: figure out how to make this cleaner.
class AnimationList extends ListBase<Animation> { class AnimationList extends ListBase<Animation> {
final List<Animation> _values = []; // Lame way to do this due to how ListBase needs to expand a nullable list.
List<Animation> get values => _values; final List<Animation?> _values = [];
List<Animation> get values => _values.cast<Animation>();
@override @override
int get length => _values.length; int get length => _values.length;
@ -13,7 +13,7 @@ class AnimationList extends ListBase<Animation> {
set length(int value) => _values.length = value; set length(int value) => _values.length = value;
@override @override
Animation operator [](int index) => _values[index]; Animation operator [](int index) => _values[index]!;
@override @override
void operator []=(int index, Animation value) => _values[index] = value; void operator []=(int index, Animation value) => _values[index] = value;

@ -3,8 +3,8 @@ import 'package:rive/src/rive_core/component.dart';
// TODO: figure out how to make this cleaner. // TODO: figure out how to make this cleaner.
class ContainerChildren extends ListBase<Component> { class ContainerChildren extends ListBase<Component> {
final List<Component> _values = []; final List<Component?> _values = [];
List<Component> get values => _values; List<Component> get values => _values.cast<Component>();
@override @override
int get length => _values.length; int get length => _values.length;
@ -13,7 +13,7 @@ class ContainerChildren extends ListBase<Component> {
set length(int value) => _values.length = value; set length(int value) => _values.length = value;
@override @override
Component operator [](int index) => _values[index]; Component operator [](int index) => _values[index]!;
@override @override
void operator []=(int index, Component value) => _values[index] = value; void operator []=(int index, Component value) => _values[index] = value;

@ -1,5 +1,4 @@
import 'package:rive/src/extensions.dart'; import 'package:rive/src/extensions.dart';
import 'package:rive/src/rive_core/animation/linear_animation.dart';
import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; import 'package:rive/src/rive_core/animation/linear_animation_instance.dart';
import 'package:rive/src/rive_core/rive_animation_controller.dart'; import 'package:rive/src/rive_core/rive_animation_controller.dart';
import 'package:rive/src/runtime_artboard.dart'; import 'package:rive/src/runtime_artboard.dart';
@ -51,10 +50,7 @@ class SimpleAnimation extends RiveAnimationController<RuntimeArtboard> {
@override @override
bool init(RuntimeArtboard artboard) { bool init(RuntimeArtboard artboard) {
var animation = artboard.animationByName(animationName); _instance = artboard.animationByName(animationName);
if (animation != null) {
_instance = LinearAnimationInstance(animation as LinearAnimation);
}
isActive = true; isActive = true;
return _instance != null; return _instance != null;
} }

@ -28,7 +28,9 @@ abstract class AnimationBase<T extends CoreContext> extends Core<T> {
} }
String from = _name; String from = _name;
_name = value; _name = value;
nameChanged(from, value); if (hasValidated) {
nameChanged(from, value);
}
} }
void nameChanged(String from, String to); void nameChanged(String from, String to);

@ -35,7 +35,9 @@ abstract class AnimationStateBase extends LayerState {
} }
int from = _animationId; int from = _animationId;
_animationId = value; _animationId = value;
animationIdChanged(from, value); if (hasValidated) {
animationIdChanged(from, value);
}
} }
void animationIdChanged(int from, int to); void animationIdChanged(int from, int to);

@ -26,7 +26,9 @@ abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
} }
double from = _x1; double from = _x1;
_x1 = value; _x1 = value;
x1Changed(from, value); if (hasValidated) {
x1Changed(from, value);
}
} }
void x1Changed(double from, double to); void x1Changed(double from, double to);
@ -46,7 +48,9 @@ abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
} }
double from = _y1; double from = _y1;
_y1 = value; _y1 = value;
y1Changed(from, value); if (hasValidated) {
y1Changed(from, value);
}
} }
void y1Changed(double from, double to); void y1Changed(double from, double to);
@ -66,7 +70,9 @@ abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
} }
double from = _x2; double from = _x2;
_x2 = value; _x2 = value;
x2Changed(from, value); if (hasValidated) {
x2Changed(from, value);
}
} }
void x2Changed(double from, double to); void x2Changed(double from, double to);
@ -86,7 +92,9 @@ abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
} }
double from = _y2; double from = _y2;
_y2 = value; _y2 = value;
y2Changed(from, value); if (hasValidated) {
y2Changed(from, value);
}
} }
void y2Changed(double from, double to); void y2Changed(double from, double to);

@ -28,7 +28,9 @@ abstract class KeyedObjectBase<T extends CoreContext> extends Core<T> {
} }
int from = _objectId; int from = _objectId;
_objectId = value; _objectId = value;
objectIdChanged(from, value); if (hasValidated) {
objectIdChanged(from, value);
}
} }
void objectIdChanged(int from, int to); void objectIdChanged(int from, int to);

@ -29,7 +29,9 @@ abstract class KeyedPropertyBase<T extends CoreContext> extends Core<T> {
} }
int from = _propertyKey; int from = _propertyKey;
_propertyKey = value; _propertyKey = value;
propertyKeyChanged(from, value); if (hasValidated) {
propertyKeyChanged(from, value);
}
} }
void propertyKeyChanged(int from, int to); void propertyKeyChanged(int from, int to);

@ -28,7 +28,9 @@ abstract class KeyFrameBase<T extends CoreContext> extends Core<T> {
} }
int from = _frame; int from = _frame;
_frame = value; _frame = value;
frameChanged(from, value); if (hasValidated) {
frameChanged(from, value);
}
} }
void frameChanged(int from, int to); void frameChanged(int from, int to);
@ -52,7 +54,9 @@ abstract class KeyFrameBase<T extends CoreContext> extends Core<T> {
} }
int from = _interpolationType; int from = _interpolationType;
_interpolationType = value; _interpolationType = value;
interpolationTypeChanged(from, value); if (hasValidated) {
interpolationTypeChanged(from, value);
}
} }
void interpolationTypeChanged(int from, int to); void interpolationTypeChanged(int from, int to);
@ -75,7 +79,9 @@ abstract class KeyFrameBase<T extends CoreContext> extends Core<T> {
} }
int from = _interpolatorId; int from = _interpolatorId;
_interpolatorId = value; _interpolatorId = value;
interpolatorIdChanged(from, value); if (hasValidated) {
interpolatorIdChanged(from, value);
}
} }
void interpolatorIdChanged(int from, int to); void interpolatorIdChanged(int from, int to);

@ -27,7 +27,9 @@ abstract class KeyFrameColorBase extends KeyFrame {
} }
int from = _value; int from = _value;
_value = value; _value = value;
valueChanged(from, value); if (hasValidated) {
valueChanged(from, value);
}
} }
void valueChanged(int from, int to); void valueChanged(int from, int to);

@ -27,7 +27,9 @@ abstract class KeyFrameDoubleBase extends KeyFrame {
} }
double from = _value; double from = _value;
_value = value; _value = value;
valueChanged(from, value); if (hasValidated) {
valueChanged(from, value);
}
} }
void valueChanged(double from, double to); void valueChanged(double from, double to);

@ -27,7 +27,9 @@ abstract class KeyFrameIdBase extends KeyFrame {
} }
int from = _value; int from = _value;
_value = value; _value = value;
valueChanged(from, value); if (hasValidated) {
valueChanged(from, value);
}
} }
void valueChanged(int from, int to); void valueChanged(int from, int to);

@ -31,7 +31,9 @@ abstract class LinearAnimationBase extends Animation {
} }
int from = _fps; int from = _fps;
_fps = value; _fps = value;
fpsChanged(from, value); if (hasValidated) {
fpsChanged(from, value);
}
} }
void fpsChanged(int from, int to); void fpsChanged(int from, int to);
@ -53,7 +55,9 @@ abstract class LinearAnimationBase extends Animation {
} }
int from = _duration; int from = _duration;
_duration = value; _duration = value;
durationChanged(from, value); if (hasValidated) {
durationChanged(from, value);
}
} }
void durationChanged(int from, int to); void durationChanged(int from, int to);
@ -75,7 +79,9 @@ abstract class LinearAnimationBase extends Animation {
} }
double from = _speed; double from = _speed;
_speed = value; _speed = value;
speedChanged(from, value); if (hasValidated) {
speedChanged(from, value);
}
} }
void speedChanged(double from, double to); void speedChanged(double from, double to);
@ -97,7 +103,9 @@ abstract class LinearAnimationBase extends Animation {
} }
int from = _loopValue; int from = _loopValue;
_loopValue = value; _loopValue = value;
loopValueChanged(from, value); if (hasValidated) {
loopValueChanged(from, value);
}
} }
void loopValueChanged(int from, int to); void loopValueChanged(int from, int to);
@ -119,7 +127,9 @@ abstract class LinearAnimationBase extends Animation {
} }
int from = _workStart; int from = _workStart;
_workStart = value; _workStart = value;
workStartChanged(from, value); if (hasValidated) {
workStartChanged(from, value);
}
} }
void workStartChanged(int from, int to); void workStartChanged(int from, int to);
@ -141,7 +151,9 @@ abstract class LinearAnimationBase extends Animation {
} }
int from = _workEnd; int from = _workEnd;
_workEnd = value; _workEnd = value;
workEndChanged(from, value); if (hasValidated) {
workEndChanged(from, value);
}
} }
void workEndChanged(int from, int to); void workEndChanged(int from, int to);
@ -164,7 +176,9 @@ abstract class LinearAnimationBase extends Animation {
} }
bool from = _enableWorkArea; bool from = _enableWorkArea;
_enableWorkArea = value; _enableWorkArea = value;
enableWorkAreaChanged(from, value); if (hasValidated) {
enableWorkAreaChanged(from, value);
}
} }
void enableWorkAreaChanged(bool from, bool to); void enableWorkAreaChanged(bool from, bool to);

@ -32,7 +32,9 @@ abstract class StateMachineBoolBase extends StateMachineInput {
} }
bool from = _value; bool from = _value;
_value = value; _value = value;
valueChanged(from, value); if (hasValidated) {
valueChanged(from, value);
}
} }
void valueChanged(bool from, bool to); void valueChanged(bool from, bool to);

@ -30,7 +30,9 @@ abstract class StateMachineComponentBase<T extends CoreContext>
} }
String from = _name; String from = _name;
_name = value; _name = value;
nameChanged(from, value); if (hasValidated) {
nameChanged(from, value);
}
} }
void nameChanged(String from, String to); void nameChanged(String from, String to);

@ -32,7 +32,9 @@ abstract class StateMachineDoubleBase extends StateMachineInput {
} }
double from = _value; double from = _value;
_value = value; _value = value;
valueChanged(from, value); if (hasValidated) {
valueChanged(from, value);
}
} }
void valueChanged(double from, double to); void valueChanged(double from, double to);

@ -30,7 +30,9 @@ abstract class StateTransitionBase extends StateMachineLayerComponent {
} }
int from = _stateToId; int from = _stateToId;
_stateToId = value; _stateToId = value;
stateToIdChanged(from, value); if (hasValidated) {
stateToIdChanged(from, value);
}
} }
void stateToIdChanged(int from, int to); void stateToIdChanged(int from, int to);
@ -50,7 +52,9 @@ abstract class StateTransitionBase extends StateMachineLayerComponent {
} }
int from = _flags; int from = _flags;
_flags = value; _flags = value;
flagsChanged(from, value); if (hasValidated) {
flagsChanged(from, value);
}
} }
void flagsChanged(int from, int to); void flagsChanged(int from, int to);
@ -72,7 +76,9 @@ abstract class StateTransitionBase extends StateMachineLayerComponent {
} }
int from = _duration; int from = _duration;
_duration = value; _duration = value;
durationChanged(from, value); if (hasValidated) {
durationChanged(from, value);
}
} }
void durationChanged(int from, int to); void durationChanged(int from, int to);

@ -28,7 +28,9 @@ abstract class TransitionConditionBase<T extends CoreContext> extends Core<T> {
} }
int from = _inputId; int from = _inputId;
_inputId = value; _inputId = value;
inputIdChanged(from, value); if (hasValidated) {
inputIdChanged(from, value);
}
} }
void inputIdChanged(int from, int to); void inputIdChanged(int from, int to);

@ -32,7 +32,9 @@ abstract class TransitionDoubleConditionBase extends TransitionValueCondition {
} }
double from = _value; double from = _value;
_value = value; _value = value;
valueChanged(from, value); if (hasValidated) {
valueChanged(from, value);
}
} }
void valueChanged(double from, double to); void valueChanged(double from, double to);

@ -30,7 +30,9 @@ abstract class TransitionValueConditionBase extends TransitionCondition {
} }
int from = _opValue; int from = _opValue;
_opValue = value; _opValue = value;
opValueChanged(from, value); if (hasValidated) {
opValueChanged(from, value);
}
} }
void opValueChanged(int from, int to); void opValueChanged(int from, int to);

@ -33,7 +33,9 @@ abstract class ArtboardBase extends ContainerComponent {
} }
double from = _width; double from = _width;
_width = value; _width = value;
widthChanged(from, value); if (hasValidated) {
widthChanged(from, value);
}
} }
void widthChanged(double from, double to); void widthChanged(double from, double to);
@ -55,7 +57,9 @@ abstract class ArtboardBase extends ContainerComponent {
} }
double from = _height; double from = _height;
_height = value; _height = value;
heightChanged(from, value); if (hasValidated) {
heightChanged(from, value);
}
} }
void heightChanged(double from, double to); void heightChanged(double from, double to);
@ -77,7 +81,9 @@ abstract class ArtboardBase extends ContainerComponent {
} }
double from = _x; double from = _x;
_x = value; _x = value;
xChanged(from, value); if (hasValidated) {
xChanged(from, value);
}
} }
void xChanged(double from, double to); void xChanged(double from, double to);
@ -99,7 +105,9 @@ abstract class ArtboardBase extends ContainerComponent {
} }
double from = _y; double from = _y;
_y = value; _y = value;
yChanged(from, value); if (hasValidated) {
yChanged(from, value);
}
} }
void yChanged(double from, double to); void yChanged(double from, double to);
@ -121,7 +129,9 @@ abstract class ArtboardBase extends ContainerComponent {
} }
double from = _originX; double from = _originX;
_originX = value; _originX = value;
originXChanged(from, value); if (hasValidated) {
originXChanged(from, value);
}
} }
void originXChanged(double from, double to); void originXChanged(double from, double to);
@ -143,7 +153,9 @@ abstract class ArtboardBase extends ContainerComponent {
} }
double from = _originY; double from = _originY;
_originY = value; _originY = value;
originYChanged(from, value); if (hasValidated) {
originYChanged(from, value);
}
} }
void originYChanged(double from, double to); void originYChanged(double from, double to);

@ -35,7 +35,9 @@ abstract class BoneBase extends SkeletalComponent {
} }
double from = _length; double from = _length;
_length = value; _length = value;
lengthChanged(from, value); if (hasValidated) {
lengthChanged(from, value);
}
} }
void lengthChanged(double from, double to); void lengthChanged(double from, double to);

@ -28,7 +28,9 @@ abstract class CubicWeightBase extends Weight {
} }
int from = _inValues; int from = _inValues;
_inValues = value; _inValues = value;
inValuesChanged(from, value); if (hasValidated) {
inValuesChanged(from, value);
}
} }
void inValuesChanged(int from, int to); void inValuesChanged(int from, int to);
@ -48,7 +50,9 @@ abstract class CubicWeightBase extends Weight {
} }
int from = _inIndices; int from = _inIndices;
_inIndices = value; _inIndices = value;
inIndicesChanged(from, value); if (hasValidated) {
inIndicesChanged(from, value);
}
} }
void inIndicesChanged(int from, int to); void inIndicesChanged(int from, int to);
@ -68,7 +72,9 @@ abstract class CubicWeightBase extends Weight {
} }
int from = _outValues; int from = _outValues;
_outValues = value; _outValues = value;
outValuesChanged(from, value); if (hasValidated) {
outValuesChanged(from, value);
}
} }
void outValuesChanged(int from, int to); void outValuesChanged(int from, int to);
@ -88,7 +94,9 @@ abstract class CubicWeightBase extends Weight {
} }
int from = _outIndices; int from = _outIndices;
_outIndices = value; _outIndices = value;
outIndicesChanged(from, value); if (hasValidated) {
outIndicesChanged(from, value);
}
} }
void outIndicesChanged(int from, int to); void outIndicesChanged(int from, int to);

@ -39,7 +39,9 @@ abstract class RootBoneBase extends Bone {
} }
double from = _x; double from = _x;
_x = value; _x = value;
xChanged(from, value); if (hasValidated) {
xChanged(from, value);
}
} }
void xChanged(double from, double to); void xChanged(double from, double to);
@ -61,7 +63,9 @@ abstract class RootBoneBase extends Bone {
} }
double from = _y; double from = _y;
_y = value; _y = value;
yChanged(from, value); if (hasValidated) {
yChanged(from, value);
}
} }
void yChanged(double from, double to); void yChanged(double from, double to);

@ -30,7 +30,9 @@ abstract class SkinBase extends ContainerComponent {
} }
double from = _xx; double from = _xx;
_xx = value; _xx = value;
xxChanged(from, value); if (hasValidated) {
xxChanged(from, value);
}
} }
void xxChanged(double from, double to); void xxChanged(double from, double to);
@ -52,7 +54,9 @@ abstract class SkinBase extends ContainerComponent {
} }
double from = _yx; double from = _yx;
_yx = value; _yx = value;
yxChanged(from, value); if (hasValidated) {
yxChanged(from, value);
}
} }
void yxChanged(double from, double to); void yxChanged(double from, double to);
@ -74,7 +78,9 @@ abstract class SkinBase extends ContainerComponent {
} }
double from = _xy; double from = _xy;
_xy = value; _xy = value;
xyChanged(from, value); if (hasValidated) {
xyChanged(from, value);
}
} }
void xyChanged(double from, double to); void xyChanged(double from, double to);
@ -96,7 +102,9 @@ abstract class SkinBase extends ContainerComponent {
} }
double from = _yy; double from = _yy;
_yy = value; _yy = value;
yyChanged(from, value); if (hasValidated) {
yyChanged(from, value);
}
} }
void yyChanged(double from, double to); void yyChanged(double from, double to);
@ -118,7 +126,9 @@ abstract class SkinBase extends ContainerComponent {
} }
double from = _tx; double from = _tx;
_tx = value; _tx = value;
txChanged(from, value); if (hasValidated) {
txChanged(from, value);
}
} }
void txChanged(double from, double to); void txChanged(double from, double to);
@ -140,7 +150,9 @@ abstract class SkinBase extends ContainerComponent {
} }
double from = _ty; double from = _ty;
_ty = value; _ty = value;
tyChanged(from, value); if (hasValidated) {
tyChanged(from, value);
}
} }
void tyChanged(double from, double to); void tyChanged(double from, double to);

@ -28,7 +28,9 @@ abstract class TendonBase extends Component {
} }
int from = _boneId; int from = _boneId;
_boneId = value; _boneId = value;
boneIdChanged(from, value); if (hasValidated) {
boneIdChanged(from, value);
}
} }
void boneIdChanged(int from, int to); void boneIdChanged(int from, int to);
@ -50,7 +52,9 @@ abstract class TendonBase extends Component {
} }
double from = _xx; double from = _xx;
_xx = value; _xx = value;
xxChanged(from, value); if (hasValidated) {
xxChanged(from, value);
}
} }
void xxChanged(double from, double to); void xxChanged(double from, double to);
@ -72,7 +76,9 @@ abstract class TendonBase extends Component {
} }
double from = _yx; double from = _yx;
_yx = value; _yx = value;
yxChanged(from, value); if (hasValidated) {
yxChanged(from, value);
}
} }
void yxChanged(double from, double to); void yxChanged(double from, double to);
@ -94,7 +100,9 @@ abstract class TendonBase extends Component {
} }
double from = _xy; double from = _xy;
_xy = value; _xy = value;
xyChanged(from, value); if (hasValidated) {
xyChanged(from, value);
}
} }
void xyChanged(double from, double to); void xyChanged(double from, double to);
@ -116,7 +124,9 @@ abstract class TendonBase extends Component {
} }
double from = _yy; double from = _yy;
_yy = value; _yy = value;
yyChanged(from, value); if (hasValidated) {
yyChanged(from, value);
}
} }
void yyChanged(double from, double to); void yyChanged(double from, double to);
@ -138,7 +148,9 @@ abstract class TendonBase extends Component {
} }
double from = _tx; double from = _tx;
_tx = value; _tx = value;
txChanged(from, value); if (hasValidated) {
txChanged(from, value);
}
} }
void txChanged(double from, double to); void txChanged(double from, double to);
@ -160,7 +172,9 @@ abstract class TendonBase extends Component {
} }
double from = _ty; double from = _ty;
_ty = value; _ty = value;
tyChanged(from, value); if (hasValidated) {
tyChanged(from, value);
}
} }
void tyChanged(double from, double to); void tyChanged(double from, double to);

@ -26,7 +26,9 @@ abstract class WeightBase extends Component {
} }
int from = _values; int from = _values;
_values = value; _values = value;
valuesChanged(from, value); if (hasValidated) {
valuesChanged(from, value);
}
} }
void valuesChanged(int from, int to); void valuesChanged(int from, int to);
@ -46,7 +48,9 @@ abstract class WeightBase extends Component {
} }
int from = _indices; int from = _indices;
_indices = value; _indices = value;
indicesChanged(from, value); if (hasValidated) {
indicesChanged(from, value);
}
} }
void indicesChanged(int from, int to); void indicesChanged(int from, int to);

@ -28,7 +28,9 @@ abstract class ComponentBase<T extends CoreContext> extends Core<T> {
} }
String from = _name; String from = _name;
_name = value; _name = value;
nameChanged(from, value); if (hasValidated) {
nameChanged(from, value);
}
} }
void nameChanged(String from, String to); void nameChanged(String from, String to);
@ -50,7 +52,9 @@ abstract class ComponentBase<T extends CoreContext> extends Core<T> {
} }
int from = _parentId; int from = _parentId;
_parentId = value; _parentId = value;
parentIdChanged(from, value); if (hasValidated) {
parentIdChanged(from, value);
}
} }
void parentIdChanged(int from, int to); void parentIdChanged(int from, int to);

@ -34,7 +34,9 @@ abstract class DrawRulesBase extends ContainerComponent {
} }
int from = _drawTargetId; int from = _drawTargetId;
_drawTargetId = value; _drawTargetId = value;
drawTargetIdChanged(from, value); if (hasValidated) {
drawTargetIdChanged(from, value);
}
} }
void drawTargetIdChanged(int from, int to); void drawTargetIdChanged(int from, int to);

@ -28,7 +28,9 @@ abstract class DrawTargetBase extends Component {
} }
int from = _drawableId; int from = _drawableId;
_drawableId = value; _drawableId = value;
drawableIdChanged(from, value); if (hasValidated) {
drawableIdChanged(from, value);
}
} }
void drawableIdChanged(int from, int to); void drawableIdChanged(int from, int to);
@ -51,7 +53,9 @@ abstract class DrawTargetBase extends Component {
} }
int from = _placementValue; int from = _placementValue;
_placementValue = value; _placementValue = value;
placementValueChanged(from, value); if (hasValidated) {
placementValueChanged(from, value);
}
} }
void placementValueChanged(int from, int to); void placementValueChanged(int from, int to);

@ -36,7 +36,9 @@ abstract class DrawableBase extends Node {
} }
int from = _blendModeValue; int from = _blendModeValue;
_blendModeValue = value; _blendModeValue = value;
blendModeValueChanged(from, value); if (hasValidated) {
blendModeValueChanged(from, value);
}
} }
void blendModeValueChanged(int from, int to); void blendModeValueChanged(int from, int to);
@ -57,7 +59,9 @@ abstract class DrawableBase extends Node {
} }
int from = _drawableFlags; int from = _drawableFlags;
_drawableFlags = value; _drawableFlags = value;
drawableFlagsChanged(from, value); if (hasValidated) {
drawableFlagsChanged(from, value);
}
} }
void drawableFlagsChanged(int from, int to); void drawableFlagsChanged(int from, int to);

@ -35,7 +35,9 @@ abstract class NodeBase extends TransformComponent {
} }
double from = _x; double from = _x;
_x = value; _x = value;
xChanged(from, value); if (hasValidated) {
xChanged(from, value);
}
} }
void xChanged(double from, double to); void xChanged(double from, double to);
@ -57,7 +59,9 @@ abstract class NodeBase extends TransformComponent {
} }
double from = _y; double from = _y;
_y = value; _y = value;
yChanged(from, value); if (hasValidated) {
yChanged(from, value);
}
} }
void yChanged(double from, double to); void yChanged(double from, double to);

@ -29,7 +29,9 @@ abstract class ClippingShapeBase extends Component {
} }
int from = _sourceId; int from = _sourceId;
_sourceId = value; _sourceId = value;
sourceIdChanged(from, value); if (hasValidated) {
sourceIdChanged(from, value);
}
} }
void sourceIdChanged(int from, int to); void sourceIdChanged(int from, int to);
@ -51,7 +53,9 @@ abstract class ClippingShapeBase extends Component {
} }
int from = _fillRule; int from = _fillRule;
_fillRule = value; _fillRule = value;
fillRuleChanged(from, value); if (hasValidated) {
fillRuleChanged(from, value);
}
} }
void fillRuleChanged(int from, int to); void fillRuleChanged(int from, int to);
@ -71,7 +75,9 @@ abstract class ClippingShapeBase extends Component {
} }
bool from = _isVisible; bool from = _isVisible;
_isVisible = value; _isVisible = value;
isVisibleChanged(from, value); if (hasValidated) {
isVisibleChanged(from, value);
}
} }
void isVisibleChanged(bool from, bool to); void isVisibleChanged(bool from, bool to);

@ -38,7 +38,9 @@ abstract class CubicAsymmetricVertexBase extends CubicVertex {
} }
double from = _rotation; double from = _rotation;
_rotation = value; _rotation = value;
rotationChanged(from, value); if (hasValidated) {
rotationChanged(from, value);
}
} }
void rotationChanged(double from, double to); void rotationChanged(double from, double to);
@ -60,7 +62,9 @@ abstract class CubicAsymmetricVertexBase extends CubicVertex {
} }
double from = _inDistance; double from = _inDistance;
_inDistance = value; _inDistance = value;
inDistanceChanged(from, value); if (hasValidated) {
inDistanceChanged(from, value);
}
} }
void inDistanceChanged(double from, double to); void inDistanceChanged(double from, double to);
@ -83,7 +87,9 @@ abstract class CubicAsymmetricVertexBase extends CubicVertex {
} }
double from = _outDistance; double from = _outDistance;
_outDistance = value; _outDistance = value;
outDistanceChanged(from, value); if (hasValidated) {
outDistanceChanged(from, value);
}
} }
void outDistanceChanged(double from, double to); void outDistanceChanged(double from, double to);

@ -38,7 +38,9 @@ abstract class CubicDetachedVertexBase extends CubicVertex {
} }
double from = _inRotation; double from = _inRotation;
_inRotation = value; _inRotation = value;
inRotationChanged(from, value); if (hasValidated) {
inRotationChanged(from, value);
}
} }
void inRotationChanged(double from, double to); void inRotationChanged(double from, double to);
@ -60,7 +62,9 @@ abstract class CubicDetachedVertexBase extends CubicVertex {
} }
double from = _inDistance; double from = _inDistance;
_inDistance = value; _inDistance = value;
inDistanceChanged(from, value); if (hasValidated) {
inDistanceChanged(from, value);
}
} }
void inDistanceChanged(double from, double to); void inDistanceChanged(double from, double to);
@ -83,7 +87,9 @@ abstract class CubicDetachedVertexBase extends CubicVertex {
} }
double from = _outRotation; double from = _outRotation;
_outRotation = value; _outRotation = value;
outRotationChanged(from, value); if (hasValidated) {
outRotationChanged(from, value);
}
} }
void outRotationChanged(double from, double to); void outRotationChanged(double from, double to);
@ -106,7 +112,9 @@ abstract class CubicDetachedVertexBase extends CubicVertex {
} }
double from = _outDistance; double from = _outDistance;
_outDistance = value; _outDistance = value;
outDistanceChanged(from, value); if (hasValidated) {
outDistanceChanged(from, value);
}
} }
void outDistanceChanged(double from, double to); void outDistanceChanged(double from, double to);

@ -38,7 +38,9 @@ abstract class CubicMirroredVertexBase extends CubicVertex {
} }
double from = _rotation; double from = _rotation;
_rotation = value; _rotation = value;
rotationChanged(from, value); if (hasValidated) {
rotationChanged(from, value);
}
} }
void rotationChanged(double from, double to); void rotationChanged(double from, double to);
@ -60,7 +62,9 @@ abstract class CubicMirroredVertexBase extends CubicVertex {
} }
double from = _distance; double from = _distance;
_distance = value; _distance = value;
distanceChanged(from, value); if (hasValidated) {
distanceChanged(from, value);
}
} }
void distanceChanged(double from, double to); void distanceChanged(double from, double to);

@ -33,7 +33,9 @@ abstract class FillBase extends ShapePaint {
} }
int from = _fillRule; int from = _fillRule;
_fillRule = value; _fillRule = value;
fillRuleChanged(from, value); if (hasValidated) {
fillRuleChanged(from, value);
}
} }
void fillRuleChanged(int from, int to); void fillRuleChanged(int from, int to);

@ -27,7 +27,9 @@ abstract class GradientStopBase extends Component {
} }
int from = _colorValue; int from = _colorValue;
_colorValue = value; _colorValue = value;
colorValueChanged(from, value); if (hasValidated) {
colorValueChanged(from, value);
}
} }
void colorValueChanged(int from, int to); void colorValueChanged(int from, int to);
@ -47,7 +49,9 @@ abstract class GradientStopBase extends Component {
} }
double from = _position; double from = _position;
_position = value; _position = value;
positionChanged(from, value); if (hasValidated) {
positionChanged(from, value);
}
} }
void positionChanged(double from, double to); void positionChanged(double from, double to);

@ -32,7 +32,9 @@ abstract class LinearGradientBase extends ContainerComponent {
} }
double from = _startX; double from = _startX;
_startX = value; _startX = value;
startXChanged(from, value); if (hasValidated) {
startXChanged(from, value);
}
} }
void startXChanged(double from, double to); void startXChanged(double from, double to);
@ -52,7 +54,9 @@ abstract class LinearGradientBase extends ContainerComponent {
} }
double from = _startY; double from = _startY;
_startY = value; _startY = value;
startYChanged(from, value); if (hasValidated) {
startYChanged(from, value);
}
} }
void startYChanged(double from, double to); void startYChanged(double from, double to);
@ -72,7 +76,9 @@ abstract class LinearGradientBase extends ContainerComponent {
} }
double from = _endX; double from = _endX;
_endX = value; _endX = value;
endXChanged(from, value); if (hasValidated) {
endXChanged(from, value);
}
} }
void endXChanged(double from, double to); void endXChanged(double from, double to);
@ -92,7 +98,9 @@ abstract class LinearGradientBase extends ContainerComponent {
} }
double from = _endY; double from = _endY;
_endY = value; _endY = value;
endYChanged(from, value); if (hasValidated) {
endYChanged(from, value);
}
} }
void endYChanged(double from, double to); void endYChanged(double from, double to);
@ -112,7 +120,9 @@ abstract class LinearGradientBase extends ContainerComponent {
} }
double from = _opacity; double from = _opacity;
_opacity = value; _opacity = value;
opacityChanged(from, value); if (hasValidated) {
opacityChanged(from, value);
}
} }
void opacityChanged(double from, double to); void opacityChanged(double from, double to);

@ -32,7 +32,9 @@ abstract class ShapePaintBase extends ContainerComponent {
} }
bool from = _isVisible; bool from = _isVisible;
_isVisible = value; _isVisible = value;
isVisibleChanged(from, value); if (hasValidated) {
isVisibleChanged(from, value);
}
} }
void isVisibleChanged(bool from, bool to); void isVisibleChanged(bool from, bool to);

@ -27,7 +27,9 @@ abstract class SolidColorBase extends Component {
} }
int from = _colorValue; int from = _colorValue;
_colorValue = value; _colorValue = value;
colorValueChanged(from, value); if (hasValidated) {
colorValueChanged(from, value);
}
} }
void colorValueChanged(int from, int to); void colorValueChanged(int from, int to);

@ -34,7 +34,9 @@ abstract class StrokeBase extends ShapePaint {
} }
double from = _thickness; double from = _thickness;
_thickness = value; _thickness = value;
thicknessChanged(from, value); if (hasValidated) {
thicknessChanged(from, value);
}
} }
void thicknessChanged(double from, double to); void thicknessChanged(double from, double to);
@ -54,7 +56,9 @@ abstract class StrokeBase extends ShapePaint {
} }
int from = _cap; int from = _cap;
_cap = value; _cap = value;
capChanged(from, value); if (hasValidated) {
capChanged(from, value);
}
} }
void capChanged(int from, int to); void capChanged(int from, int to);
@ -74,7 +78,9 @@ abstract class StrokeBase extends ShapePaint {
} }
int from = _join; int from = _join;
_join = value; _join = value;
joinChanged(from, value); if (hasValidated) {
joinChanged(from, value);
}
} }
void joinChanged(int from, int to); void joinChanged(int from, int to);
@ -95,7 +101,9 @@ abstract class StrokeBase extends ShapePaint {
} }
bool from = _transformAffectsStroke; bool from = _transformAffectsStroke;
_transformAffectsStroke = value; _transformAffectsStroke = value;
transformAffectsStrokeChanged(from, value); if (hasValidated) {
transformAffectsStrokeChanged(from, value);
}
} }
void transformAffectsStrokeChanged(bool from, bool to); void transformAffectsStrokeChanged(bool from, bool to);

@ -27,7 +27,9 @@ abstract class TrimPathBase extends Component {
} }
double from = _start; double from = _start;
_start = value; _start = value;
startChanged(from, value); if (hasValidated) {
startChanged(from, value);
}
} }
void startChanged(double from, double to); void startChanged(double from, double to);
@ -47,7 +49,9 @@ abstract class TrimPathBase extends Component {
} }
double from = _end; double from = _end;
_end = value; _end = value;
endChanged(from, value); if (hasValidated) {
endChanged(from, value);
}
} }
void endChanged(double from, double to); void endChanged(double from, double to);
@ -67,7 +71,9 @@ abstract class TrimPathBase extends Component {
} }
double from = _offset; double from = _offset;
_offset = value; _offset = value;
offsetChanged(from, value); if (hasValidated) {
offsetChanged(from, value);
}
} }
void offsetChanged(double from, double to); void offsetChanged(double from, double to);
@ -87,7 +93,9 @@ abstract class TrimPathBase extends Component {
} }
int from = _modeValue; int from = _modeValue;
_modeValue = value; _modeValue = value;
modeValueChanged(from, value); if (hasValidated) {
modeValueChanged(from, value);
}
} }
void modeValueChanged(int from, int to); void modeValueChanged(int from, int to);

@ -40,7 +40,9 @@ abstract class ParametricPathBase extends Path {
} }
double from = _width; double from = _width;
_width = value; _width = value;
widthChanged(from, value); if (hasValidated) {
widthChanged(from, value);
}
} }
void widthChanged(double from, double to); void widthChanged(double from, double to);
@ -62,7 +64,9 @@ abstract class ParametricPathBase extends Path {
} }
double from = _height; double from = _height;
_height = value; _height = value;
heightChanged(from, value); if (hasValidated) {
heightChanged(from, value);
}
} }
void heightChanged(double from, double to); void heightChanged(double from, double to);
@ -84,7 +88,9 @@ abstract class ParametricPathBase extends Path {
} }
double from = _originX; double from = _originX;
_originX = value; _originX = value;
originXChanged(from, value); if (hasValidated) {
originXChanged(from, value);
}
} }
void originXChanged(double from, double to); void originXChanged(double from, double to);
@ -106,7 +112,9 @@ abstract class ParametricPathBase extends Path {
} }
double from = _originY; double from = _originY;
_originY = value; _originY = value;
originYChanged(from, value); if (hasValidated) {
originYChanged(from, value);
}
} }
void originYChanged(double from, double to); void originYChanged(double from, double to);

@ -35,7 +35,9 @@ abstract class PathBase extends Node {
} }
int from = _pathFlags; int from = _pathFlags;
_pathFlags = value; _pathFlags = value;
pathFlagsChanged(from, value); if (hasValidated) {
pathFlagsChanged(from, value);
}
} }
void pathFlagsChanged(int from, int to); void pathFlagsChanged(int from, int to);

@ -33,7 +33,9 @@ abstract class PathVertexBase extends ContainerComponent {
} }
double from = _x; double from = _x;
_x = value; _x = value;
xChanged(from, value); if (hasValidated) {
xChanged(from, value);
}
} }
void xChanged(double from, double to); void xChanged(double from, double to);
@ -55,7 +57,9 @@ abstract class PathVertexBase extends ContainerComponent {
} }
double from = _y; double from = _y;
_y = value; _y = value;
yChanged(from, value); if (hasValidated) {
yChanged(from, value);
}
} }
void yChanged(double from, double to); void yChanged(double from, double to);

@ -40,7 +40,9 @@ abstract class PointsPathBase extends Path {
} }
bool from = _isClosed; bool from = _isClosed;
_isClosed = value; _isClosed = value;
isClosedChanged(from, value); if (hasValidated) {
isClosedChanged(from, value);
}
} }
void isClosedChanged(bool from, bool to); void isClosedChanged(bool from, bool to);

@ -41,7 +41,9 @@ abstract class PolygonBase extends ParametricPath {
} }
int from = _points; int from = _points;
_points = value; _points = value;
pointsChanged(from, value); if (hasValidated) {
pointsChanged(from, value);
}
} }
void pointsChanged(int from, int to); void pointsChanged(int from, int to);
@ -64,7 +66,9 @@ abstract class PolygonBase extends ParametricPath {
} }
double from = _cornerRadius; double from = _cornerRadius;
_cornerRadius = value; _cornerRadius = value;
cornerRadiusChanged(from, value); if (hasValidated) {
cornerRadiusChanged(from, value);
}
} }
void cornerRadiusChanged(double from, double to); void cornerRadiusChanged(double from, double to);

@ -42,7 +42,9 @@ abstract class RectangleBase extends ParametricPath {
} }
double from = _cornerRadius; double from = _cornerRadius;
_cornerRadius = value; _cornerRadius = value;
cornerRadiusChanged(from, value); if (hasValidated) {
cornerRadiusChanged(from, value);
}
} }
void cornerRadiusChanged(double from, double to); void cornerRadiusChanged(double from, double to);

@ -44,7 +44,9 @@ abstract class StarBase extends Polygon {
} }
double from = _innerRadius; double from = _innerRadius;
_innerRadius = value; _innerRadius = value;
innerRadiusChanged(from, value); if (hasValidated) {
innerRadiusChanged(from, value);
}
} }
void innerRadiusChanged(double from, double to); void innerRadiusChanged(double from, double to);

@ -37,7 +37,9 @@ abstract class StraightVertexBase extends PathVertex<Weight> {
} }
double from = _radius; double from = _radius;
_radius = value; _radius = value;
radiusChanged(from, value); if (hasValidated) {
radiusChanged(from, value);
}
} }
void radiusChanged(double from, double to); void radiusChanged(double from, double to);

@ -32,7 +32,9 @@ abstract class TransformComponentBase extends ContainerComponent {
} }
double from = _rotation; double from = _rotation;
_rotation = value; _rotation = value;
rotationChanged(from, value); if (hasValidated) {
rotationChanged(from, value);
}
} }
void rotationChanged(double from, double to); void rotationChanged(double from, double to);
@ -52,7 +54,9 @@ abstract class TransformComponentBase extends ContainerComponent {
} }
double from = _scaleX; double from = _scaleX;
_scaleX = value; _scaleX = value;
scaleXChanged(from, value); if (hasValidated) {
scaleXChanged(from, value);
}
} }
void scaleXChanged(double from, double to); void scaleXChanged(double from, double to);
@ -72,7 +76,9 @@ abstract class TransformComponentBase extends ContainerComponent {
} }
double from = _scaleY; double from = _scaleY;
_scaleY = value; _scaleY = value;
scaleYChanged(from, value); if (hasValidated) {
scaleYChanged(from, value);
}
} }
void scaleYChanged(double from, double to); void scaleYChanged(double from, double to);
@ -92,7 +98,9 @@ abstract class TransformComponentBase extends ContainerComponent {
} }
double from = _opacity; double from = _opacity;
_opacity = value; _opacity = value;
opacityChanged(from, value); if (hasValidated) {
opacityChanged(from, value);
}
} }
void opacityChanged(double from, double to); void opacityChanged(double from, double to);

@ -39,8 +39,7 @@ class Rive extends LeafRenderObjectWidget {
@override @override
RenderObject createRenderObject(BuildContext context) { RenderObject createRenderObject(BuildContext context) {
return RiveRenderObject() return RiveRenderObject(artboard as RuntimeArtboard)
..artboard = artboard
..fit = fit ..fit = fit
..alignment = alignment ..alignment = alignment
..artboardSize = Size(artboard.width, artboard.height) ..artboardSize = Size(artboard.width, artboard.height)
@ -65,7 +64,10 @@ class Rive extends LeafRenderObjectWidget {
} }
class RiveRenderObject extends RiveRenderBox { class RiveRenderObject extends RiveRenderBox {
late RuntimeArtboard _artboard; RuntimeArtboard _artboard;
RiveRenderObject(this._artboard) {
_artboard.redraw.addListener(scheduleRepaint);
}
RuntimeArtboard get artboard => _artboard; RuntimeArtboard get artboard => _artboard;

@ -4,15 +4,15 @@ import 'package:rive/src/generated/animation/animation_base.dart';
export 'package:rive/src/generated/animation/animation_base.dart'; export 'package:rive/src/generated/animation/animation_base.dart';
class Animation extends AnimationBase<RuntimeArtboard> { class Animation extends AnimationBase<RuntimeArtboard> {
late Artboard _artboard; Artboard? _artboard;
Artboard get artboard => _artboard; Artboard? get artboard => _artboard;
set artboard(Artboard value) { set artboard(Artboard? value) {
if (_artboard == value) { if (_artboard == value) {
return; return;
} }
_artboard.internalRemoveAnimation(this); _artboard?.internalRemoveAnimation(this);
_artboard = value; _artboard = value;
_artboard.internalAddAnimation(this); _artboard?.internalAddAnimation(this);
} }
@override @override
@ -20,5 +20,7 @@ class Animation extends AnimationBase<RuntimeArtboard> {
@override @override
void onAdded() {} void onAdded() {}
@override @override
bool validate() => super.validate() && _artboard != null;
@override
void nameChanged(String from, String to) {} void nameChanged(String from, String to) {}
} }

@ -15,10 +15,7 @@ import 'package:rive/src/utilities/dependency_sorter.dart';
import 'package:rive/src/generated/artboard_base.dart'; import 'package:rive/src/generated/artboard_base.dart';
export 'package:rive/src/generated/artboard_base.dart'; export 'package:rive/src/generated/artboard_base.dart';
class _UnknownArtboard extends Artboard {}
class Artboard extends ArtboardBase with ShapePaintContainer { class Artboard extends ArtboardBase with ShapePaintContainer {
static final Artboard unknown = _UnknownArtboard();
@override @override
bool get canBeOrphaned => true; bool get canBeOrphaned => true;
final Path path = Path(); final Path path = Path();
@ -173,7 +170,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
fill.draw(canvas, path); fill.draw(canvas, path);
} }
for (var drawable = _firstDrawable; for (var drawable = _firstDrawable;
drawable != Drawable.unknown; drawable != null;
drawable = drawable.prev) { drawable = drawable.prev) {
if (drawable.isHidden) { if (drawable.isHidden) {
continue; continue;
@ -240,7 +237,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
void onStrokesChanged() {} void onStrokesChanged() {}
@override @override
Vec2D get worldTranslation => Vec2D(); Vec2D get worldTranslation => Vec2D();
Drawable _firstDrawable = Drawable.unknown; Drawable? _firstDrawable;
void computeDrawOrder() { void computeDrawOrder() {
_drawables.clear(); _drawables.clear();
_rules.clear(); _rules.clear();
@ -254,7 +251,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
for (final nodeRules in _rules) { for (final nodeRules in _rules) {
for (final target in nodeRules.targets) { for (final target in nodeRules.targets) {
root.dependents.add(target); root.dependents.add(target);
var dependentRules = target.drawable.flattenedDrawRules; var dependentRules = target.drawable?.flattenedDrawRules;
if (dependentRules != null) { if (dependentRules != null) {
for (final dependentRule in dependentRules.targets) { for (final dependentRule in dependentRules.targets) {
dependentRule.dependents.add(target); dependentRule.dependents.add(target);
@ -269,27 +266,27 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
void sortDrawOrder() { void sortDrawOrder() {
for (final rule in _sortedDrawRules) { for (final rule in _sortedDrawRules) {
rule.first = rule.last = Drawable.unknown; rule.first = rule.last = null;
} }
_firstDrawable = Drawable.unknown; _firstDrawable = null;
Drawable lastDrawable = Drawable.unknown; Drawable? lastDrawable;
for (final drawable in _drawables) { for (final drawable in _drawables) {
var rules = drawable.flattenedDrawRules; var rules = drawable.flattenedDrawRules;
var target = rules?.activeTarget; var target = rules?.activeTarget;
if (target != null) { if (target != null) {
if (target.first == Drawable.unknown) { if (target.first == null) {
target.first = target.last = drawable; target.first = target.last = drawable;
drawable.prev = drawable.next = Drawable.unknown; drawable.prev = drawable.next = null;
} else { } else {
target.last.next = drawable; target.last?.next = drawable;
drawable.prev = target.last; drawable.prev = target.last;
target.last = drawable; target.last = drawable;
drawable.next = Drawable.unknown; drawable.next = null;
} }
} else { } else {
drawable.prev = lastDrawable; drawable.prev = lastDrawable;
drawable.next = Drawable.unknown; drawable.next = null;
if (lastDrawable == Drawable.unknown) { if (lastDrawable == null) {
lastDrawable = _firstDrawable = drawable; lastDrawable = _firstDrawable = drawable;
} else { } else {
lastDrawable.next = drawable; lastDrawable.next = drawable;
@ -298,31 +295,31 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
} }
} }
for (final rule in _sortedDrawRules) { for (final rule in _sortedDrawRules) {
if (rule.first == Drawable.unknown) { if (rule.first == null) {
continue; continue;
} }
switch (rule.placement) { switch (rule.placement) {
case DrawTargetPlacement.before: case DrawTargetPlacement.before:
if (rule.drawable.prev != Drawable.unknown) { if (rule.drawable?.prev != null) {
rule.drawable.prev.next = rule.first; rule.drawable!.prev?.next = rule.first;
rule.first.prev = rule.drawable.prev; rule.first?.prev = rule.drawable!.prev;
} }
if (rule.drawable == _firstDrawable) { if (rule.drawable == _firstDrawable) {
_firstDrawable = rule.first; _firstDrawable = rule.first;
} }
rule.drawable.prev = rule.last; rule.drawable?.prev = rule.last;
rule.last.next = rule.drawable; rule.last?.next = rule.drawable;
break; break;
case DrawTargetPlacement.after: case DrawTargetPlacement.after:
if (rule.drawable.next != Drawable.unknown) { if (rule.drawable?.next != null) {
rule.drawable.next.prev = rule.last; rule.drawable!.next!.prev = rule.last;
rule.last.next = rule.drawable.next; rule.last?.next = rule.drawable?.next;
} }
if (rule.drawable == lastDrawable) { if (rule.drawable == lastDrawable) {
lastDrawable = rule.last; lastDrawable = rule.last;
} }
rule.drawable.next = rule.first; rule.drawable?.next = rule.first;
rule.first.prev = rule.drawable; rule.first?.prev = rule.drawable;
break; break;
} }
} }

@ -54,7 +54,7 @@ class Skin extends SkinBase {
super.onAddedDirty(); super.onAddedDirty();
if (parent is Skinnable) { if (parent is Skinnable) {
(parent as Skinnable).addSkin(this); (parent as Skinnable).addSkin(this);
parent.markRebuildDependencies(); parent!.markRebuildDependencies();
} }
} }
@ -62,7 +62,7 @@ class Skin extends SkinBase {
void onRemoved() { void onRemoved() {
if (parent is Skinnable) { if (parent is Skinnable) {
(parent as Skinnable).removeSkin(this); (parent as Skinnable).removeSkin(this);
parent.markRebuildDependencies(); parent!.markRebuildDependencies();
} }
super.onRemoved(); super.onRemoved();
} }
@ -82,7 +82,7 @@ class Skin extends SkinBase {
case TendonBase.typeKey: case TendonBase.typeKey:
_tendons.add(child as Tendon); _tendons.add(child as Tendon);
markRebuildDependencies(); markRebuildDependencies();
parent.markRebuildDependencies(); parent!.markRebuildDependencies();
break; break;
} }
} }
@ -98,7 +98,7 @@ class Skin extends SkinBase {
} else { } else {
markRebuildDependencies(); markRebuildDependencies();
} }
parent.markRebuildDependencies(); parent!.markRebuildDependencies();
break; break;
} }
} }

@ -9,7 +9,7 @@ export 'package:rive/src/generated/component_base.dart';
abstract class Component extends ComponentBase<RuntimeArtboard> abstract class Component extends ComponentBase<RuntimeArtboard>
implements DependencyGraphNode<Component>, Parentable<Component> { implements DependencyGraphNode<Component>, Parentable<Component> {
Artboard _artboard = Artboard.unknown; Artboard? _artboard;
dynamic _userData; dynamic _userData;
bool get canBeOrphaned => false; bool get canBeOrphaned => false;
int graphOrder = 0; int graphOrder = 0;
@ -21,7 +21,7 @@ abstract class Component extends ComponentBase<RuntimeArtboard>
} }
dirt |= value; dirt |= value;
onDirty(dirt); onDirty(dirt);
artboard.onComponentDirty(this); artboard?.onComponentDirty(this);
if (!recurse) { if (!recurse) {
return true; return true;
} }
@ -33,22 +33,22 @@ abstract class Component extends ComponentBase<RuntimeArtboard>
void onDirty(int mask) {} void onDirty(int mask) {}
void update(int dirt); void update(int dirt);
Artboard get artboard => _artboard; Artboard? get artboard => _artboard;
void _changeArtboard(Artboard value) { void _changeArtboard(Artboard? value) {
if (_artboard == value) { if (_artboard == value) {
return; return;
} }
_artboard.removeComponent(this); _artboard?.removeComponent(this);
_artboard = value; _artboard = value;
_artboard.addComponent(this); _artboard?.addComponent(this);
} }
@mustCallSuper @mustCallSuper
void visitAncestor(Component ancestor) {} void visitAncestor(Component ancestor) {}
bool resolveArtboard() { bool resolveArtboard() {
int sanity = maxTreeDepth; int sanity = maxTreeDepth;
for (Component curr = this; for (Component? curr = this;
curr != ContainerComponent.unknown && sanity > 0; curr != null && sanity > 0;
curr = curr.parent, sanity--) { curr = curr.parent, sanity--) {
visitAncestor(curr); visitAncestor(curr);
if (curr is Artboard) { if (curr is Artboard) {
@ -56,7 +56,7 @@ abstract class Component extends ComponentBase<RuntimeArtboard>
return true; return true;
} }
} }
_changeArtboard(Artboard.unknown); _changeArtboard(null);
return false; return false;
} }
@ -72,27 +72,29 @@ abstract class Component extends ComponentBase<RuntimeArtboard>
void userDataChanged(dynamic from, dynamic to) {} void userDataChanged(dynamic from, dynamic to) {}
@override @override
void parentIdChanged(int from, int to) => void parentIdChanged(int from, int to) {
parent = context.resolveWithDefault(to, ContainerComponent.unknown); parent = context.resolve(to);
ContainerComponent _parent = ContainerComponent.unknown; }
ContainerComponent? _parent;
@override @override
ContainerComponent get parent => _parent; ContainerComponent? get parent => _parent;
set parent(ContainerComponent value) { set parent(ContainerComponent? value) {
if (_parent == value) { if (_parent == value) {
return; return;
} }
var old = _parent; var old = _parent;
_parent = value; _parent = value;
parentId = value.id; parentId = value?.id ?? Core.missingId;
parentChanged(old, value); parentChanged(old, value);
} }
@protected @protected
void parentChanged(ContainerComponent from, ContainerComponent to) { void parentChanged(ContainerComponent? from, ContainerComponent? to) {
from.children.remove(this); from?.children.remove(this);
from.childRemoved(this); from?.childRemoved(this);
to.children.add(this); to?.children.add(this);
to.childAdded(this); to?.childAdded(this);
markRebuildDependencies(); markRebuildDependencies();
} }
@ -133,7 +135,7 @@ abstract class Component extends ComponentBase<RuntimeArtboard>
void onAdded() {} void onAdded() {}
@override @override
void onAddedDirty() { void onAddedDirty() {
parent = context.resolveWithDefault(parentId, ContainerComponent.unknown); parent = context.resolve(parentId);
} }
@override @override
@ -148,12 +150,14 @@ abstract class Component extends ComponentBase<RuntimeArtboard>
dependent.onDependencyRemoved(this); dependent.onDependencyRemoved(this);
} }
_dependents.clear(); _dependents.clear();
if (parent != ContainerComponent.unknown) { if (parent != null) {
parent.children.remove(this); parent!.children.remove(this);
parent.childRemoved(this); parent!.childRemoved(this);
}
if (artboard != null) {
context.markDependencyOrderDirty();
_changeArtboard(null);
} }
context.markDependencyOrderDirty();
_changeArtboard(Artboard.unknown);
} }
@override @override

@ -7,15 +7,8 @@ import 'package:rive/src/generated/container_component_base.dart';
typedef bool DescentCallback(Component component); typedef bool DescentCallback(Component component);
class _UnknownParent extends ContainerComponent {
@override
void update(int dirt) => throw UnsupportedError(
'Something is incorrectly referencing an unknown parent');
}
abstract class ContainerComponent extends ContainerComponentBase { abstract class ContainerComponent extends ContainerComponentBase {
final ContainerChildren children = ContainerChildren(); final ContainerChildren children = ContainerChildren();
static final unknown = _UnknownParent();
void appendChild(Component child) { void appendChild(Component child) {
child.parent = this; child.parent = this;
} }

@ -14,7 +14,7 @@ class DrawRules extends DrawRulesBase {
@override @override
void drawTargetIdChanged(int from, int to) { void drawTargetIdChanged(int from, int to) {
_activeTarget = context.resolve(to); _activeTarget = context.resolve(to);
artboard.markDrawOrderDirty(); artboard?.markDrawOrderDirty();
} }
@override @override

@ -1,3 +1,4 @@
import 'package:rive/src/core/core.dart';
import 'package:rive/src/rive_core/drawable.dart'; import 'package:rive/src/rive_core/drawable.dart';
import 'package:rive/src/generated/draw_target_base.dart'; import 'package:rive/src/generated/draw_target_base.dart';
export 'package:rive/src/generated/draw_target_base.dart'; export 'package:rive/src/generated/draw_target_base.dart';
@ -5,16 +6,16 @@ export 'package:rive/src/generated/draw_target_base.dart';
enum DrawTargetPlacement { before, after } enum DrawTargetPlacement { before, after }
class DrawTarget extends DrawTargetBase { class DrawTarget extends DrawTargetBase {
Drawable first = Drawable.unknown; Drawable? first;
Drawable last = Drawable.unknown; Drawable? last;
Drawable _drawable = Drawable.unknown; Drawable? _drawable;
Drawable get drawable => _drawable; Drawable? get drawable => _drawable;
set drawable(Drawable value) { set drawable(Drawable? value) {
if (_drawable == value) { if (_drawable == value) {
return; return;
} }
_drawable = value; _drawable = value;
drawableId = value.id; drawableId = value?.id ?? Core.missingId;
} }
DrawTargetPlacement get placement => DrawTargetPlacement get placement =>
@ -22,18 +23,18 @@ class DrawTarget extends DrawTargetBase {
set placement(DrawTargetPlacement value) => placementValue = value.index; set placement(DrawTargetPlacement value) => placementValue = value.index;
@override @override
void drawableIdChanged(int from, int to) { void drawableIdChanged(int from, int to) {
drawable = context.resolveWithDefault(to, Drawable.unknown); drawable = context.resolve(to);
} }
@override @override
void onAddedDirty() { void onAddedDirty() {
super.onAddedDirty(); super.onAddedDirty();
drawable = context.resolveWithDefault(drawableId, Drawable.unknown); drawable = context.resolve(drawableId);
} }
@override @override
void placementValueChanged(int from, int to) { void placementValueChanged(int from, int to) {
artboard.markDrawOrderDirty(); artboard?.markDrawOrderDirty();
} }
@override @override

@ -8,17 +8,10 @@ import 'package:rive/src/generated/drawable_base.dart';
import 'package:rive/src/rive_core/transform_component.dart'; import 'package:rive/src/rive_core/transform_component.dart';
export 'package:rive/src/generated/drawable_base.dart'; export 'package:rive/src/generated/drawable_base.dart';
class _UnknownDrawable extends Drawable {
@override
void draw(Canvas canvas) =>
throw UnsupportedError('Cannot draw an unknown drawable.');
}
abstract class Drawable extends DrawableBase { abstract class Drawable extends DrawableBase {
static final Drawable unknown = _UnknownDrawable();
DrawRules? flattenedDrawRules; DrawRules? flattenedDrawRules;
Drawable prev = Drawable.unknown; Drawable? prev;
Drawable next = Drawable.unknown; Drawable? next;
@override @override
void buildDrawOrder( void buildDrawOrder(
List<Drawable> drawables, DrawRules? rules, List<DrawRules> allRules) { List<Drawable> drawables, DrawRules? rules, List<DrawRules> allRules) {
@ -48,7 +41,7 @@ abstract class Drawable extends DrawableBase {
} }
@override @override
void parentChanged(ContainerComponent from, ContainerComponent to) { void parentChanged(ContainerComponent? from, ContainerComponent? to) {
super.parentChanged(from, to); super.parentChanged(from, to);
addDirt(ComponentDirt.clip); addDirt(ComponentDirt.clip);
} }
@ -58,9 +51,7 @@ abstract class Drawable extends DrawableBase {
super.update(dirt); super.update(dirt);
if (dirt & ComponentDirt.clip != 0) { if (dirt & ComponentDirt.clip != 0) {
List<ClippingShape> clippingShapes = []; List<ClippingShape> clippingShapes = [];
for (ContainerComponent p = this; for (ContainerComponent? p = this; p != null; p = p.parent) {
p != ContainerComponent.unknown;
p = p.parent) {
if (p is TransformComponent) { if (p is TransformComponent) {
if (p.clippingShapes.isNotEmpty) { if (p.clippingShapes.isNotEmpty) {
clippingShapes.addAll(p.clippingShapes); clippingShapes.addAll(p.clippingShapes);

@ -22,13 +22,15 @@ class ClippingShape extends ClippingShapeBase {
@override @override
void fillRuleChanged(int from, int to) { void fillRuleChanged(int from, int to) {
parent.addDirt(ComponentDirt.clip, recurse: true); parent?.addDirt(ComponentDirt.clip, recurse: true);
addDirt(ComponentDirt.path); addDirt(ComponentDirt.path);
} }
@override @override
void sourceIdChanged(int from, int to) => void sourceIdChanged(int from, int to) {
source = context.resolveWithDefault(to, Node.unknown); source = context.resolveWithDefault(to, Node.unknown);
}
@override @override
void onAddedDirty() { void onAddedDirty() {
super.onAddedDirty(); super.onAddedDirty();

@ -57,20 +57,20 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase {
void inDistanceChanged(double from, double to) { void inDistanceChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = _outPoint = null; _inPoint = _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void outDistanceChanged(double from, double to) { void outDistanceChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = _outPoint = null; _inPoint = _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void rotationChanged(double from, double to) { void rotationChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = _outPoint = null; _inPoint = _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
} }

@ -67,27 +67,27 @@ class CubicDetachedVertex extends CubicDetachedVertexBase {
void inDistanceChanged(double from, double to) { void inDistanceChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = null; _inPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void inRotationChanged(double from, double to) { void inRotationChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = null; _inPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void outDistanceChanged(double from, double to) { void outDistanceChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_outPoint = null; _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void outRotationChanged(double from, double to) { void outRotationChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_outPoint = null; _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
} }

@ -52,13 +52,13 @@ class CubicMirroredVertex extends CubicMirroredVertexBase {
void distanceChanged(double from, double to) { void distanceChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = _outPoint = null; _inPoint = _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void rotationChanged(double from, double to) { void rotationChanged(double from, double to) {
addDirt(ComponentDirt.worldTransform); addDirt(ComponentDirt.worldTransform);
_inPoint = _outPoint = null; _inPoint = _outPoint = null;
path.markPathDirty(); path?.markPathDirty();
} }
} }

@ -10,7 +10,8 @@ class Fill extends FillBase {
PathFillType get fillType => PathFillType.values[fillRule]; PathFillType get fillType => PathFillType.values[fillRule];
set fillType(PathFillType type) => fillRule = type.index; set fillType(PathFillType type) => fillRule = type.index;
@override @override
void fillRuleChanged(int from, int to) => parent.addDirt(ComponentDirt.paint); void fillRuleChanged(int from, int to) =>
parent?.addDirt(ComponentDirt.paint);
@override @override
void update(int dirt) {} void update(int dirt) {}
@override @override

@ -5,8 +5,8 @@ import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart';
export 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart'; export 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart';
class GradientStop extends GradientStopBase { class GradientStop extends GradientStopBase {
LinearGradient _gradient = LinearGradient.unknown; LinearGradient? _gradient;
LinearGradient get gradient => _gradient; LinearGradient? get gradient => _gradient;
ui.Color get color => ui.Color(colorValue); ui.Color get color => ui.Color(colorValue);
set color(ui.Color c) { set color(ui.Color c) {
colorValue = c.value; colorValue = c.value;
@ -14,23 +14,25 @@ class GradientStop extends GradientStopBase {
@override @override
void positionChanged(double from, double to) { void positionChanged(double from, double to) {
_gradient.markStopsDirty(); _gradient?.markStopsDirty();
} }
@override @override
void colorValueChanged(int from, int to) { void colorValueChanged(int from, int to) {
_gradient.markGradientDirty(); _gradient?.markGradientDirty();
} }
@override @override
void update(int dirt) {} void update(int dirt) {}
@override @override
void parentChanged(ContainerComponent from, ContainerComponent to) { bool validate() => super.validate() && _gradient != null;
@override
void parentChanged(ContainerComponent? from, ContainerComponent? to) {
super.parentChanged(from, to); super.parentChanged(from, to);
if (parent is LinearGradient) { if (parent is LinearGradient) {
_gradient = parent as LinearGradient; _gradient = parent as LinearGradient;
} else { } else {
_gradient = LinearGradient.unknown; _gradient = null;
} }
} }
} }

@ -8,11 +8,8 @@ import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart';
import 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart'; import 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart';
export 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart'; export 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart';
class _UnknownGradient extends LinearGradient {}
class LinearGradient extends LinearGradientBase with ShapePaintMutator { class LinearGradient extends LinearGradientBase with ShapePaintMutator {
final List<GradientStop> gradientStops = []; final List<GradientStop> gradientStops = [];
static final LinearGradient unknown = _UnknownGradient();
bool _paintsInWorldSpace = true; bool _paintsInWorldSpace = true;
bool get paintsInWorldSpace => _paintsInWorldSpace; bool get paintsInWorldSpace => _paintsInWorldSpace;
set paintsInWorldSpace(bool value) { set paintsInWorldSpace(bool value) {
@ -30,7 +27,7 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
@override @override
void buildDependencies() { void buildDependencies() {
super.buildDependencies(); super.buildDependencies();
shapePaintContainer.addDependent(this); shapePaintContainer?.addDependent(this);
} }
@override @override
@ -72,7 +69,7 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
colorPositions.add(stop.position); colorPositions.add(stop.position);
} }
if (paintsInWorldSpace) { if (paintsInWorldSpace) {
var world = shapePaintContainer.worldTransform; var world = shapePaintContainer!.worldTransform;
var worldStart = Vec2D.transformMat2D(Vec2D(), start, world); var worldStart = Vec2D.transformMat2D(Vec2D(), start, world);
var worldEnd = Vec2D.transformMat2D(Vec2D(), end, world); var worldEnd = Vec2D.transformMat2D(Vec2D(), end, world);
paint.shader = makeGradient(ui.Offset(worldStart[0], worldStart[1]), paint.shader = makeGradient(ui.Offset(worldStart[0], worldStart[1]),
@ -111,7 +108,7 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
@override @override
void opacityChanged(double from, double to) { void opacityChanged(double from, double to) {
syncColor(); syncColor();
shapePaintContainer.addDirt(ComponentDirt.paint); shapePaintContainer!.addDirt(ComponentDirt.paint);
} }
@override @override
@ -119,4 +116,7 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
paint.color = const ui.Color(0xFFFFFFFF) paint.color = const ui.Color(0xFFFFFFFF)
.withOpacity((opacity * renderOpacity).clamp(0, 1).toDouble()); .withOpacity((opacity * renderOpacity).clamp(0, 1).toDouble());
} }
@override
bool validate() => super.validate() && shapePaintContainer != null;
} }

@ -10,17 +10,18 @@ export 'package:rive/src/generated/shapes/paint/shape_paint_base.dart';
abstract class ShapePaint extends ShapePaintBase { abstract class ShapePaint extends ShapePaintBase {
late Paint _paint; late Paint _paint;
Paint get paint => _paint; Paint get paint => _paint;
ShapePaintMutator _paintMutator = ShapePaintMutator.unknown; ShapePaintMutator? _paintMutator;
ShapePaintContainer get shapePaintContainer => parent as ShapePaintContainer; ShapePaintContainer? get shapePaintContainer =>
parent as ShapePaintContainer?;
ShapePaint() { ShapePaint() {
_paint = makePaint(); _paint = makePaint();
} }
BlendMode get blendMode => _paint.blendMode; BlendMode get blendMode => _paint.blendMode;
set blendMode(BlendMode value) => _paint.blendMode = value; set blendMode(BlendMode value) => _paint.blendMode = value;
double get renderOpacity => _paintMutator.renderOpacity; double get renderOpacity => _paintMutator!.renderOpacity;
set renderOpacity(double value) => _paintMutator.renderOpacity = value; set renderOpacity(double value) => _paintMutator!.renderOpacity = value;
ShapePaintMutator get paintMutator => _paintMutator; ShapePaintMutator? get paintMutator => _paintMutator;
void _changeMutator(ShapePaintMutator mutator) { void _changeMutator(ShapePaintMutator? mutator) {
_paint = makePaint(); _paint = makePaint();
_paintMutator = mutator; _paintMutator = mutator;
} }
@ -40,12 +41,10 @@ abstract class ShapePaint extends ShapePaintBase {
bool validate() => bool validate() =>
super.validate() && super.validate() &&
parent is ShapePaintContainer && parent is ShapePaintContainer &&
_paintMutator != ShapePaintMutator.unknown; _paintMutator != null;
@override @override
void isVisibleChanged(bool from, bool to) { void isVisibleChanged(bool from, bool to) {
if (hasValidated) { shapePaintContainer?.addDirt(ComponentDirt.paint);
shapePaintContainer.addDirt(ComponentDirt.paint);
}
} }
@override @override
@ -53,15 +52,11 @@ abstract class ShapePaint extends ShapePaintBase {
super.childRemoved(child); super.childRemoved(child);
if (child is ShapePaintMutator && if (child is ShapePaintMutator &&
_paintMutator == child as ShapePaintMutator) { _paintMutator == child as ShapePaintMutator) {
_changeMutator(ShapePaintMutator.unknown); _changeMutator(null);
}
}
void _initMutator() {
if (hasValidated) {
_paintMutator.initializePaintMutator(shapePaintContainer, paint);
} }
} }
void _initMutator() =>
_paintMutator?.initializePaintMutator(shapePaintContainer!, paint);
void draw(Canvas canvas, Path path); void draw(Canvas canvas, Path path);
} }

@ -2,19 +2,10 @@ import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; import 'package:rive/src/rive_core/shapes/shape_paint_container.dart';
class _UnknownMutator extends ShapePaintMutator {
@override
void syncColor() {
throw UnsupportedError(
'Not expected to call sync color on an UnknownMutator.');
}
}
abstract class ShapePaintMutator { abstract class ShapePaintMutator {
ShapePaintContainer _shapePaintContainer = ShapePaintContainer.unknown; ShapePaintContainer? _shapePaintContainer;
late Paint _paint; late Paint _paint;
static final ShapePaintMutator unknown = _UnknownMutator(); ShapePaintContainer? get shapePaintContainer => _shapePaintContainer;
ShapePaintContainer get shapePaintContainer => _shapePaintContainer;
Paint get paint => _paint; Paint get paint => _paint;
double _renderOpacity = 1; double _renderOpacity = 1;
double get renderOpacity => _renderOpacity; double get renderOpacity => _renderOpacity;
@ -31,7 +22,7 @@ abstract class ShapePaintMutator {
void initializePaintMutator(ShapePaintContainer container, Paint paint) { void initializePaintMutator(ShapePaintContainer container, Paint paint) {
_shapePaintContainer = container; _shapePaintContainer = container;
_paint = paint; _paint = paint;
_shapePaintContainer.onPaintMutatorChanged(this); _shapePaintContainer?.onPaintMutatorChanged(this);
syncColor(); syncColor();
} }
} }

@ -1,5 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/component_dirt.dart';
import 'package:rive/src/rive_core/shapes/paint/shape_paint.dart';
import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart';
import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; import 'package:rive/src/rive_core/shapes/shape_paint_container.dart';
import 'package:rive/src/generated/shapes/paint/solid_color_base.dart'; import 'package:rive/src/generated/shapes/paint/solid_color_base.dart';
@ -14,7 +15,7 @@ class SolidColor extends SolidColorBase with ShapePaintMutator {
@override @override
void colorValueChanged(int from, int to) { void colorValueChanged(int from, int to) {
syncColor(); syncColor();
shapePaintContainer.addDirt(ComponentDirt.paint); shapePaintContainer?.addDirt(ComponentDirt.paint);
} }
@override @override
@ -30,4 +31,7 @@ class SolidColor extends SolidColorBase with ShapePaintMutator {
paint.color = color paint.color = color
.withOpacity((color.opacity * renderOpacity).clamp(0, 1).toDouble()); .withOpacity((color.opacity * renderOpacity).clamp(0, 1).toDouble());
} }
@override
bool validate() => super.validate() && parent is ShapePaint;
} }

@ -33,19 +33,19 @@ class Stroke extends StrokeBase {
@override @override
void capChanged(int from, int to) { void capChanged(int from, int to) {
paint.strokeCap = StrokeCap.values[to]; paint.strokeCap = StrokeCap.values[to];
parent.addDirt(ComponentDirt.paint); parent?.addDirt(ComponentDirt.paint);
} }
@override @override
void joinChanged(int from, int to) { void joinChanged(int from, int to) {
paint.strokeJoin = StrokeJoin.values[to]; paint.strokeJoin = StrokeJoin.values[to];
parent.addDirt(ComponentDirt.paint); parent?.addDirt(ComponentDirt.paint);
} }
@override @override
void thicknessChanged(double from, double to) { void thicknessChanged(double from, double to) {
paint.strokeWidth = to; paint.strokeWidth = to;
parent.addDirt(ComponentDirt.paint); parent?.addDirt(ComponentDirt.paint);
} }
@override @override

@ -48,13 +48,13 @@ class TrimPath extends TrimPathBase implements StrokeEffect {
return _renderPath = _trimmedPath; return _renderPath = _trimmedPath;
} }
Stroke get stroke => parent as Stroke; Stroke? get stroke => parent as Stroke?;
TrimPathMode get mode => TrimPathMode.values[modeValue]; TrimPathMode get mode => TrimPathMode.values[modeValue];
set mode(TrimPathMode value) => modeValue = value.index; set mode(TrimPathMode value) => modeValue = value.index;
@override @override
void invalidateEffect() { void invalidateEffect() {
_renderPath = null; _renderPath = null;
stroke.shapePaintContainer.addDirt(ComponentDirt.paint); stroke?.shapePaintContainer?.addDirt(ComponentDirt.paint);
} }
@override @override
@ -70,13 +70,13 @@ class TrimPath extends TrimPathBase implements StrokeEffect {
@override @override
void onAdded() { void onAdded() {
super.onAdded(); super.onAdded();
stroke.addStrokeEffect(this); stroke?.addStrokeEffect(this);
_renderPath = null; _renderPath = null;
} }
@override @override
void onRemoved() { void onRemoved() {
stroke.removeStrokeEffect(this); stroke?.removeStrokeEffect(this);
super.onRemoved(); super.onRemoved();
} }
} }

@ -16,31 +16,31 @@ abstract class ParametricPath extends ParametricPathBase {
@override @override
void xChanged(double from, double to) { void xChanged(double from, double to) {
super.xChanged(from, to); super.xChanged(from, to);
shape.pathChanged(this); shape?.pathChanged(this);
} }
@override @override
void yChanged(double from, double to) { void yChanged(double from, double to) {
super.yChanged(from, to); super.yChanged(from, to);
shape.pathChanged(this); shape?.pathChanged(this);
} }
@override @override
void rotationChanged(double from, double to) { void rotationChanged(double from, double to) {
super.rotationChanged(from, to); super.rotationChanged(from, to);
shape.pathChanged(this); shape?.pathChanged(this);
} }
@override @override
void scaleXChanged(double from, double to) { void scaleXChanged(double from, double to) {
super.scaleXChanged(from, to); super.scaleXChanged(from, to);
shape.pathChanged(this); shape?.pathChanged(this);
} }
@override @override
void scaleYChanged(double from, double to) { void scaleYChanged(double from, double to) {
super.scaleYChanged(from, to); super.scaleYChanged(from, to);
shape.pathChanged(this); shape?.pathChanged(this);
} }
@override @override

@ -25,44 +25,44 @@ abstract class Path extends PathBase {
bool _isValid = false; bool _isValid = false;
bool get isClosed; bool get isClosed;
Shape _shape = Shape.unknown; Shape? _shape;
Shape get shape => _shape; Shape? get shape => _shape;
Mat2D get pathTransform; Mat2D get pathTransform;
Mat2D get inversePathTransform; Mat2D get inversePathTransform;
Mat2D get inverseWorldTransform => _inverseWorldTransform; Mat2D get inverseWorldTransform => _inverseWorldTransform;
@override @override
bool resolveArtboard() { bool resolveArtboard() {
_changeShape(Shape.unknown); _changeShape(null);
return super.resolveArtboard(); return super.resolveArtboard();
} }
@override @override
void visitAncestor(Component ancestor) { void visitAncestor(Component ancestor) {
super.visitAncestor(ancestor); super.visitAncestor(ancestor);
if (_shape != Shape.unknown && ancestor is Shape) { if (_shape != null && ancestor is Shape) {
_changeShape(ancestor); _changeShape(ancestor);
} }
} }
void _changeShape(Shape value) { void _changeShape(Shape? value) {
if (_shape == value) { if (_shape == value) {
return; return;
} }
_shape.removePath(this); _shape?.removePath(this);
value.addPath(this); value?.addPath(this);
_shape = value; _shape = value;
} }
@override @override
void onRemoved() { void onRemoved() {
_changeShape(Shape.unknown); _changeShape(null);
super.onRemoved(); super.onRemoved();
} }
@override @override
void updateWorldTransform() { void updateWorldTransform() {
super.updateWorldTransform(); super.updateWorldTransform();
_shape.pathChanged(this); _shape?.pathChanged(this);
if (!Mat2D.invert(_inverseWorldTransform, pathTransform)) { if (!Mat2D.invert(_inverseWorldTransform, pathTransform)) {
Mat2D.setIdentity(_inverseWorldTransform); Mat2D.setIdentity(_inverseWorldTransform);
} }
@ -79,7 +79,7 @@ abstract class Path extends PathBase {
void markPathDirty() { void markPathDirty() {
addDirt(ComponentDirt.path); addDirt(ComponentDirt.path);
_isValid = false; _isValid = false;
_shape.pathChanged(this); _shape?.pathChanged(this);
} }
List<PathVertex> get vertices; List<PathVertex> get vertices;

@ -7,32 +7,33 @@ import 'package:rive/src/generated/shapes/path_composer_base.dart';
class PathComposer extends PathComposerBase { class PathComposer extends PathComposerBase {
static final PathComposer unknown = PathComposer(); static final PathComposer unknown = PathComposer();
Shape _shape = Shape.unknown; Shape? _shape;
Shape get shape => _shape; Shape? get shape => _shape;
final ui.Path worldPath = ui.Path(); final ui.Path worldPath = ui.Path();
final ui.Path localPath = ui.Path(); final ui.Path localPath = ui.Path();
ui.Path _fillPath = ui.Path(); ui.Path _fillPath = ui.Path();
ui.Path get fillPath => _fillPath; ui.Path get fillPath => _fillPath;
void _changeShape(Shape value) { void _changeShape(Shape? value) {
if (value == _shape) { if (value == _shape) {
return; return;
} }
if (_shape != Shape.unknown && _shape.pathComposer == this) { if (_shape != null && _shape!.pathComposer == this) {
_shape.pathComposer = PathComposer.unknown; _shape!.pathComposer = PathComposer.unknown;
} }
value.pathComposer = this; value?.pathComposer = this;
_shape = value; _shape = value;
} }
void _recomputePath() { void _recomputePath() {
var buildLocalPath = _shape.wantLocalPath; assert(_shape != null);
var buildWorldPath = _shape.wantWorldPath || !buildLocalPath; var buildLocalPath = _shape!.wantLocalPath;
var buildWorldPath = _shape!.wantWorldPath || !buildLocalPath;
if (buildLocalPath) { if (buildLocalPath) {
localPath.reset(); localPath.reset();
var world = _shape.worldTransform; var world = _shape!.worldTransform;
Mat2D inverseWorld = Mat2D(); Mat2D inverseWorld = Mat2D();
if (Mat2D.invert(inverseWorld, world)) { if (Mat2D.invert(inverseWorld, world)) {
for (final path in _shape.paths) { for (final path in _shape!.paths) {
if (path.isHidden) { if (path.isHidden) {
continue; continue;
} }
@ -45,7 +46,7 @@ class PathComposer extends PathComposerBase {
} }
if (buildWorldPath) { if (buildWorldPath) {
worldPath.reset(); worldPath.reset();
for (final path in _shape.paths) { for (final path in _shape!.paths) {
if (path.isHidden) { if (path.isHidden) {
continue; continue;
} }
@ -53,14 +54,15 @@ class PathComposer extends PathComposerBase {
matrix4: path.pathTransform.mat4); matrix4: path.pathTransform.mat4);
} }
} }
_fillPath = _shape.fillInWorld ? worldPath : localPath; _fillPath = _shape!.fillInWorld ? worldPath : localPath;
} }
@override @override
void buildDependencies() { void buildDependencies() {
assert(_shape != null);
super.buildDependencies(); super.buildDependencies();
_shape.addDependent(this); _shape!.addDependent(this);
for (final path in _shape.paths) { for (final path in _shape!.paths) {
path.addDependent(this); path.addDependent(this);
} }
} }
@ -74,14 +76,14 @@ class PathComposer extends PathComposerBase {
@override @override
bool resolveArtboard() { bool resolveArtboard() {
_changeShape(Shape.unknown); _changeShape(null);
return super.resolveArtboard(); return super.resolveArtboard();
} }
@override @override
void visitAncestor(Component ancestor) { void visitAncestor(Component ancestor) {
super.visitAncestor(ancestor); super.visitAncestor(ancestor);
if (_shape == Shape.unknown && ancestor is Shape) { if (_shape == null && ancestor is Shape) {
_changeShape(ancestor); _changeShape(ancestor);
} }
} }

@ -10,7 +10,7 @@ export 'package:rive/src/generated/shapes/path_vertex_base.dart';
abstract class PathVertex<T extends Weight> extends PathVertexBase { abstract class PathVertex<T extends Weight> extends PathVertexBase {
T? _weight; T? _weight;
T? get weight => _weight; T? get weight => _weight;
Path get path => parent as Path; Path? get path => parent as Path?;
@override @override
void update(int dirt) {} void update(int dirt) {}
final Vec2D _renderTranslation = Vec2D(); final Vec2D _renderTranslation = Vec2D();
@ -21,16 +21,23 @@ abstract class PathVertex<T extends Weight> extends PathVertexBase {
y = value[1]; y = value[1];
} }
@override
void onAddedDirty() {
super.onAddedDirty();
_renderTranslation[0] = x;
_renderTranslation[1] = y;
}
@override @override
void xChanged(double from, double to) { void xChanged(double from, double to) {
_renderTranslation[0] = to; _renderTranslation[0] = to;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override
void yChanged(double from, double to) { void yChanged(double from, double to) {
_renderTranslation[1] = to; _renderTranslation[1] = to;
path.markPathDirty(); path?.markPathDirty();
} }
@override @override

@ -10,11 +10,8 @@ import 'package:rive/src/generated/shapes/shape_base.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
export 'package:rive/src/generated/shapes/shape_base.dart'; export 'package:rive/src/generated/shapes/shape_base.dart';
class _UnknownShape extends Shape {}
class Shape extends ShapeBase with ShapePaintContainer { class Shape extends ShapeBase with ShapePaintContainer {
final Set<Path> paths = {}; final Set<Path> paths = {};
static final Shape unknown = _UnknownShape();
bool _wantWorldPath = false; bool _wantWorldPath = false;
bool _wantLocalPath = false; bool _wantLocalPath = false;
bool get wantWorldPath => _wantWorldPath; bool get wantWorldPath => _wantWorldPath;

@ -6,30 +6,7 @@ import 'package:meta/meta.dart';
import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart';
import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; import 'package:rive/src/rive_core/shapes/paint/stroke.dart';
class _UnknownShapePaintContainer extends ShapePaintContainer {
UnsupportedError get _error =>
UnsupportedError('Not expected to use the UnknownShapeContainer.');
@override
bool addDependent(Component dependent) =>
throw UnsupportedError('Not expected to use the UnknownShapeContainer.');
@override
bool addDirt(int value, {bool recurse = false}) => throw _error;
@override
void appendChild(Component child) => throw _error;
@override
void onFillsChanged() => throw _error;
@override
void onPaintMutatorChanged(ShapePaintMutator mutator) => throw _error;
@override
void onStrokesChanged() => throw _error;
@override
Mat2D get worldTransform => throw _error;
@override
Vec2D get worldTranslation => throw _error;
}
abstract class ShapePaintContainer { abstract class ShapePaintContainer {
static final ShapePaintContainer unknown = _UnknownShapePaintContainer();
final Set<Fill> fills = {}; final Set<Fill> fills = {};
final Set<Stroke> strokes = {}; final Set<Stroke> strokes = {};
void onPaintMutatorChanged(ShapePaintMutator mutator); void onPaintMutatorChanged(ShapePaintMutator mutator);

@ -10,7 +10,7 @@ class StraightVertex extends StraightVertexBase {
String toString() => 'x[$x], y[$y], r[$radius]'; String toString() => 'x[$x], y[$y], r[$radius]';
@override @override
void radiusChanged(double from, double to) { void radiusChanged(double from, double to) {
path.markPathDirty(); path?.markPathDirty();
} }
@override @override

@ -70,7 +70,7 @@ abstract class TransformComponent extends TransformComponentBase {
void calculateWorldTransform() { void calculateWorldTransform() {
var parent = this.parent; var parent = this.parent;
final chain = <TransformComponent>[this]; final chain = <TransformComponent>[this];
while (parent != ContainerComponent.unknown) { while (parent != null) {
if (parent is TransformComponent) { if (parent is TransformComponent) {
chain.insert(0, parent); chain.insert(0, parent);
} }
@ -85,7 +85,7 @@ abstract class TransformComponent extends TransformComponentBase {
@override @override
void buildDependencies() { void buildDependencies() {
super.buildDependencies(); super.buildDependencies();
parent.addDependent(this); parent?.addDependent(this);
} }
void markTransformDirty() { void markTransformDirty() {
@ -120,7 +120,7 @@ abstract class TransformComponent extends TransformComponentBase {
} }
@override @override
void parentChanged(ContainerComponent from, ContainerComponent to) { void parentChanged(ContainerComponent? from, ContainerComponent? to) {
super.parentChanged(from, to); super.parentChanged(from, to);
markWorldTransformDirty(); markWorldTransformDirty();
} }

@ -195,7 +195,8 @@ class RiveFile {
if (object != null && object.validate()) { if (object != null && object.validate()) {
InternalCoreHelper.markValid(object); InternalCoreHelper.markValid(object);
} else { } else {
throw const RiveFormatErrorException('Rive file is corrupt.'); throw RiveFormatErrorException(
'Rive file is corrupt. Invalid $object.');
} }
} }
} }

@ -206,6 +206,7 @@ abstract class RiveRenderBox extends RenderBox {
if (contentWidth == 0 || contentHeight == 0) { if (contentWidth == 0 || contentHeight == 0) {
return; return;
} }
double x = -1 * bounds[0] - double x = -1 * bounds[0] -
contentWidth / 2.0 - contentWidth / 2.0 -
(_alignment.x * contentWidth / 2.0); (_alignment.x * contentWidth / 2.0);

@ -1,5 +1,5 @@
abstract class Parentable<T> { abstract class Parentable<T> {
T get parent; T? get parent;
} }
/// Get the top most components (any child that has an ancestor in the set /// Get the top most components (any child that has an ancestor in the set