Getting instancing working.

This commit is contained in:
Luigi Rosso
2021-05-28 18:08:04 -07:00
parent a832d55f07
commit e8d9f59947
61 changed files with 456 additions and 8 deletions

View File

@ -35,7 +35,7 @@ class _ExampleAnimationState extends State<ExampleAnimation> {
// The artboard is the root of the animation and gets drawn in the
// Rive widget.
final artboard = file.mainArtboard;
final artboard = file.mainArtboard.instance();
// Add a controller to play back a known animation on the main/default
// artboard. We store a reference to it so we can toggle playback.
artboard.addController(_controller = SimpleAnimation('idle'));

View File

@ -1,5 +1,6 @@
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:rive/src/rive_core/runtime/exceptions/rive_format_error_exception.dart';
export 'package:rive/src/animation_list.dart';
export 'package:rive/src/state_machine_components.dart';
@ -37,6 +38,21 @@ abstract class Core<T extends CoreContext> {
bool import(ImportStack stack) => true;
bool validate() => true;
/// Make a duplicate of this core object, N.B. that all properties including
/// id's are copied.
K? clone<K extends Core>() {
var object = context.makeCoreInstance(coreType);
object?.copy(this);
return object is K ? object : null;
}
/// Copies property values, currently doesn't trigger change callbacks. It's
/// meant to be a helper for [clone].
@protected
void copy(covariant Core source) {
id = source.id;
}
}
class InternalCoreHelper {

View File

@ -34,4 +34,9 @@ abstract class AnimationBase<T extends CoreContext> extends Core<T> {
}
void nameChanged(String from, String to);
@override
void copy(AnimationBase source) {
_name = source._name;
}
}

View File

@ -41,4 +41,10 @@ abstract class AnimationStateBase extends LayerState {
}
void animationIdChanged(int from, int to);
@override
void copy(AnimationStateBase source) {
super.copy(source);
_animationId = source._animationId;
}
}

View File

@ -34,4 +34,10 @@ abstract class BlendAnimation1DBase extends BlendAnimation {
}
void valueChanged(double from, double to);
@override
void copy(BlendAnimation1DBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -35,4 +35,9 @@ abstract class BlendAnimationBase<T extends CoreContext> extends Core<T> {
}
void animationIdChanged(int from, int to);
@override
void copy(BlendAnimationBase source) {
_animationId = source._animationId;
}
}

View File

@ -36,4 +36,10 @@ abstract class BlendAnimationDirectBase extends BlendAnimation {
}
void inputIdChanged(int from, int to);
@override
void copy(BlendAnimationDirectBase source) {
super.copy(source);
_inputId = source._inputId;
}
}

View File

@ -43,4 +43,10 @@ abstract class BlendState1DBase extends BlendState<BlendAnimation1D> {
}
void inputIdChanged(int from, int to);
@override
void copy(BlendState1DBase source) {
super.copy(source);
_inputId = source._inputId;
}
}

View File

@ -41,4 +41,10 @@ abstract class BlendStateTransitionBase extends StateTransition {
}
void exitBlendAnimationIdChanged(int from, int to);
@override
void copy(BlendStateTransitionBase source) {
super.copy(source);
_exitBlendAnimationId = source._exitBlendAnimationId;
}
}

View File

@ -98,4 +98,12 @@ abstract class CubicInterpolatorBase<T extends CoreContext> extends Core<T> {
}
void y2Changed(double from, double to);
@override
void copy(CubicInterpolatorBase source) {
_x1 = source._x1;
_y1 = source._y1;
_x2 = source._x2;
_y2 = source._y2;
}
}

View File

@ -34,4 +34,9 @@ abstract class KeyedObjectBase<T extends CoreContext> extends Core<T> {
}
void objectIdChanged(int from, int to);
@override
void copy(KeyedObjectBase source) {
_objectId = source._objectId;
}
}

View File

@ -35,4 +35,9 @@ abstract class KeyedPropertyBase<T extends CoreContext> extends Core<T> {
}
void propertyKeyChanged(int from, int to);
@override
void copy(KeyedPropertyBase source) {
_propertyKey = source._propertyKey;
}
}

View File

@ -85,4 +85,11 @@ abstract class KeyFrameBase<T extends CoreContext> extends Core<T> {
}
void interpolatorIdChanged(int from, int to);
@override
void copy(KeyFrameBase source) {
_frame = source._frame;
_interpolationType = source._interpolationType;
_interpolatorId = source._interpolatorId;
}
}

View File

@ -33,4 +33,10 @@ abstract class KeyFrameColorBase extends KeyFrame {
}
void valueChanged(int from, int to);
@override
void copy(KeyFrameColorBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -33,4 +33,10 @@ abstract class KeyFrameDoubleBase extends KeyFrame {
}
void valueChanged(double from, double to);
@override
void copy(KeyFrameDoubleBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -33,4 +33,10 @@ abstract class KeyFrameIdBase extends KeyFrame {
}
void valueChanged(int from, int to);
@override
void copy(KeyFrameIdBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -182,4 +182,16 @@ abstract class LinearAnimationBase extends Animation {
}
void enableWorkAreaChanged(bool from, bool to);
@override
void copy(LinearAnimationBase source) {
super.copy(source);
_fps = source._fps;
_duration = source._duration;
_speed = source._speed;
_loopValue = source._loopValue;
_workStart = source._workStart;
_workEnd = source._workEnd;
_enableWorkArea = source._enableWorkArea;
}
}

View File

@ -38,4 +38,10 @@ abstract class StateMachineBoolBase extends StateMachineInput {
}
void valueChanged(bool from, bool to);
@override
void copy(StateMachineBoolBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -36,4 +36,9 @@ abstract class StateMachineComponentBase<T extends CoreContext>
}
void nameChanged(String from, String to);
@override
void copy(StateMachineComponentBase source) {
_name = source._name;
}
}

View File

@ -38,4 +38,10 @@ abstract class StateMachineNumberBase extends StateMachineInput {
}
void valueChanged(double from, double to);
@override
void copy(StateMachineNumberBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -109,4 +109,13 @@ abstract class StateTransitionBase extends StateMachineLayerComponent {
}
void exitTimeChanged(int from, int to);
@override
void copy(StateTransitionBase source) {
super.copy(source);
_stateToId = source._stateToId;
_flags = source._flags;
_duration = source._duration;
_exitTime = source._exitTime;
}
}

View File

@ -34,4 +34,9 @@ abstract class TransitionConditionBase<T extends CoreContext> extends Core<T> {
}
void inputIdChanged(int from, int to);
@override
void copy(TransitionConditionBase source) {
_inputId = source._inputId;
}
}

View File

@ -38,4 +38,10 @@ abstract class TransitionNumberConditionBase extends TransitionValueCondition {
}
void valueChanged(double from, double to);
@override
void copy(TransitionNumberConditionBase source) {
super.copy(source);
_value = source._value;
}
}

View File

@ -36,4 +36,10 @@ abstract class TransitionValueConditionBase extends TransitionCondition {
}
void opValueChanged(int from, int to);
@override
void copy(TransitionValueConditionBase source) {
super.copy(source);
_opValue = source._opValue;
}
}

View File

@ -159,4 +159,15 @@ abstract class ArtboardBase extends ContainerComponent {
}
void originYChanged(double from, double to);
@override
void copy(ArtboardBase source) {
super.copy(source);
_width = source._width;
_height = source._height;
_x = source._x;
_y = source._y;
_originX = source._originX;
_originY = source._originY;
}
}

View File

@ -41,4 +41,10 @@ abstract class BoneBase extends SkeletalComponent {
}
void lengthChanged(double from, double to);
@override
void copy(BoneBase source) {
super.copy(source);
_length = source._length;
}
}

View File

@ -100,4 +100,13 @@ abstract class CubicWeightBase extends Weight {
}
void outIndicesChanged(int from, int to);
@override
void copy(CubicWeightBase source) {
super.copy(source);
_inValues = source._inValues;
_inIndices = source._inIndices;
_outValues = source._outValues;
_outIndices = source._outIndices;
}
}

View File

@ -69,4 +69,11 @@ abstract class RootBoneBase extends Bone {
}
void yChanged(double from, double to);
@override
void copy(RootBoneBase source) {
super.copy(source);
_x = source._x;
_y = source._y;
}
}

View File

@ -156,4 +156,15 @@ abstract class SkinBase extends ContainerComponent {
}
void tyChanged(double from, double to);
@override
void copy(SkinBase source) {
super.copy(source);
_xx = source._xx;
_yx = source._yx;
_xy = source._xy;
_yy = source._yy;
_tx = source._tx;
_ty = source._ty;
}
}

View File

@ -178,4 +178,16 @@ abstract class TendonBase extends Component {
}
void tyChanged(double from, double to);
@override
void copy(TendonBase source) {
super.copy(source);
_boneId = source._boneId;
_xx = source._xx;
_yx = source._yx;
_xy = source._xy;
_yy = source._yy;
_tx = source._tx;
_ty = source._ty;
}
}

View File

@ -54,4 +54,11 @@ abstract class WeightBase extends Component {
}
void indicesChanged(int from, int to);
@override
void copy(WeightBase source) {
super.copy(source);
_values = source._values;
_indices = source._indices;
}
}

View File

@ -58,4 +58,10 @@ abstract class ComponentBase<T extends CoreContext> extends Core<T> {
}
void parentIdChanged(int from, int to);
@override
void copy(ComponentBase source) {
_name = source._name;
_parentId = source._parentId;
}
}

View File

@ -40,4 +40,10 @@ abstract class DrawRulesBase extends ContainerComponent {
}
void drawTargetIdChanged(int from, int to);
@override
void copy(DrawRulesBase source) {
super.copy(source);
_drawTargetId = source._drawTargetId;
}
}

View File

@ -59,4 +59,11 @@ abstract class DrawTargetBase extends Component {
}
void placementValueChanged(int from, int to);
@override
void copy(DrawTargetBase source) {
super.copy(source);
_drawableId = source._drawableId;
_placementValue = source._placementValue;
}
}

View File

@ -65,4 +65,11 @@ abstract class DrawableBase extends Node {
}
void drawableFlagsChanged(int from, int to);
@override
void copy(DrawableBase source) {
super.copy(source);
_blendModeValue = source._blendModeValue;
_drawableFlags = source._drawableFlags;
}
}

View File

@ -65,4 +65,11 @@ abstract class NodeBase extends TransformComponent {
}
void yChanged(double from, double to);
@override
void copy(NodeBase source) {
super.copy(source);
_x = source._x;
_y = source._y;
}
}

View File

@ -81,4 +81,12 @@ abstract class ClippingShapeBase extends Component {
}
void isVisibleChanged(bool from, bool to);
@override
void copy(ClippingShapeBase source) {
super.copy(source);
_sourceId = source._sourceId;
_fillRule = source._fillRule;
_isVisible = source._isVisible;
}
}

View File

@ -93,4 +93,12 @@ abstract class CubicAsymmetricVertexBase extends CubicVertex {
}
void outDistanceChanged(double from, double to);
@override
void copy(CubicAsymmetricVertexBase source) {
super.copy(source);
_rotation = source._rotation;
_inDistance = source._inDistance;
_outDistance = source._outDistance;
}
}

View File

@ -118,4 +118,13 @@ abstract class CubicDetachedVertexBase extends CubicVertex {
}
void outDistanceChanged(double from, double to);
@override
void copy(CubicDetachedVertexBase source) {
super.copy(source);
_inRotation = source._inRotation;
_inDistance = source._inDistance;
_outRotation = source._outRotation;
_outDistance = source._outDistance;
}
}

View File

@ -68,4 +68,11 @@ abstract class CubicMirroredVertexBase extends CubicVertex {
}
void distanceChanged(double from, double to);
@override
void copy(CubicMirroredVertexBase source) {
super.copy(source);
_rotation = source._rotation;
_distance = source._distance;
}
}

View File

@ -39,4 +39,10 @@ abstract class FillBase extends ShapePaint {
}
void fillRuleChanged(int from, int to);
@override
void copy(FillBase source) {
super.copy(source);
_fillRule = source._fillRule;
}
}

View File

@ -55,4 +55,11 @@ abstract class GradientStopBase extends Component {
}
void positionChanged(double from, double to);
@override
void copy(GradientStopBase source) {
super.copy(source);
_colorValue = source._colorValue;
_position = source._position;
}
}

View File

@ -126,4 +126,14 @@ abstract class LinearGradientBase extends ContainerComponent {
}
void opacityChanged(double from, double to);
@override
void copy(LinearGradientBase source) {
super.copy(source);
_startX = source._startX;
_startY = source._startY;
_endX = source._endX;
_endY = source._endY;
_opacity = source._opacity;
}
}

View File

@ -38,4 +38,10 @@ abstract class ShapePaintBase extends ContainerComponent {
}
void isVisibleChanged(bool from, bool to);
@override
void copy(ShapePaintBase source) {
super.copy(source);
_isVisible = source._isVisible;
}
}

View File

@ -33,4 +33,10 @@ abstract class SolidColorBase extends Component {
}
void colorValueChanged(int from, int to);
@override
void copy(SolidColorBase source) {
super.copy(source);
_colorValue = source._colorValue;
}
}

View File

@ -107,4 +107,13 @@ abstract class StrokeBase extends ShapePaint {
}
void transformAffectsStrokeChanged(bool from, bool to);
@override
void copy(StrokeBase source) {
super.copy(source);
_thickness = source._thickness;
_cap = source._cap;
_join = source._join;
_transformAffectsStroke = source._transformAffectsStroke;
}
}

View File

@ -99,4 +99,13 @@ abstract class TrimPathBase extends Component {
}
void modeValueChanged(int from, int to);
@override
void copy(TrimPathBase source) {
super.copy(source);
_start = source._start;
_end = source._end;
_offset = source._offset;
_modeValue = source._modeValue;
}
}

View File

@ -118,4 +118,13 @@ abstract class ParametricPathBase extends Path {
}
void originYChanged(double from, double to);
@override
void copy(ParametricPathBase source) {
super.copy(source);
_width = source._width;
_height = source._height;
_originX = source._originX;
_originY = source._originY;
}
}

View File

@ -41,4 +41,10 @@ abstract class PathBase extends Node {
}
void pathFlagsChanged(int from, int to);
@override
void copy(PathBase source) {
super.copy(source);
_pathFlags = source._pathFlags;
}
}

View File

@ -63,4 +63,11 @@ abstract class PathVertexBase extends ContainerComponent {
}
void yChanged(double from, double to);
@override
void copy(PathVertexBase source) {
super.copy(source);
_x = source._x;
_y = source._y;
}
}

View File

@ -46,4 +46,10 @@ abstract class PointsPathBase extends Path {
}
void isClosedChanged(bool from, bool to);
@override
void copy(PointsPathBase source) {
super.copy(source);
_isClosed = source._isClosed;
}
}

View File

@ -72,4 +72,11 @@ abstract class PolygonBase extends ParametricPath {
}
void cornerRadiusChanged(double from, double to);
@override
void copy(PolygonBase source) {
super.copy(source);
_points = source._points;
_cornerRadius = source._cornerRadius;
}
}

View File

@ -148,4 +148,14 @@ abstract class RectangleBase extends ParametricPath {
}
void cornerRadiusBRChanged(double from, double to);
@override
void copy(RectangleBase source) {
super.copy(source);
_linkCornerRadius = source._linkCornerRadius;
_cornerRadiusTL = source._cornerRadiusTL;
_cornerRadiusTR = source._cornerRadiusTR;
_cornerRadiusBL = source._cornerRadiusBL;
_cornerRadiusBR = source._cornerRadiusBR;
}
}

View File

@ -50,4 +50,10 @@ abstract class StarBase extends Polygon {
}
void innerRadiusChanged(double from, double to);
@override
void copy(StarBase source) {
super.copy(source);
_innerRadius = source._innerRadius;
}
}

View File

@ -43,4 +43,10 @@ abstract class StraightVertexBase extends PathVertex<Weight> {
}
void radiusChanged(double from, double to);
@override
void copy(StraightVertexBase source) {
super.copy(source);
_radius = source._radius;
}
}

View File

@ -104,4 +104,13 @@ abstract class TransformComponentBase extends ContainerComponent {
}
void opacityChanged(double from, double to);
@override
void copy(TransformComponentBase source) {
super.copy(source);
_rotation = source._rotation;
_scaleX = source._scaleX;
_scaleY = source._scaleY;
_opacity = source._opacity;
}
}

View File

@ -87,6 +87,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
}
step++;
}
return true;
}
return didUpdate;
@ -411,4 +412,15 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
_firstDrawable = lastDrawable;
}
/// Make a copy of the this [Artboard]. This duplicates internal objects in
/// the hierarchy but shares animations and state machines with the original
/// [Artboard] it is instanced from. Instance an [Artboard] when you want to
/// show it muliptle times on the screen in the different states.
Artboard instance() {
/// Intentionally not implemented in the editor, must be overridden in
/// runtime version of the artboard.
throw UnsupportedError(
'Instancing the artboard in the editor isn\'t supported');
}
}

View File

@ -15,6 +15,8 @@ class Polygon extends PolygonBase {
@override
List<PathVertex<Weight>> get vertices {
double ox = -originX * width + width / 2;
double oy = -originY * height + height / 2;
var vertexList = <PathVertex<Weight>>[];
var halfWidth = width / 2;
var halfHeight = height / 2;
@ -22,8 +24,8 @@ class Polygon extends PolygonBase {
var inc = 2 * pi / points;
for (int i = 0; i < points; i++) {
vertexList.add(StraightVertex.procedural()
..x = cos(angle) * halfWidth
..y = sin(angle) * halfHeight
..x = ox + cos(angle) * halfWidth
..y = oy + sin(angle) * halfHeight
..radius = cornerRadius);
angle += inc;
}

View File

@ -30,7 +30,9 @@ class Shape extends ShapeBase with ShapePaintContainer {
bool addPath(Path path) {
paintChanged();
return paths.add(path);
var added = paths.add(path);
return added;
}
void _markComposerDirty() {

View File

@ -12,6 +12,9 @@ class Star extends StarBase {
@override
List<PathVertex<Weight>> get vertices {
double ox = -originX * width + width / 2;
double oy = -originY * height + height / 2;
var actualPoints = points * 2;
var vertexList = <PathVertex<Weight>>[];
var halfWidth = width / 2;
@ -22,13 +25,13 @@ class Star extends StarBase {
var inc = 2 * pi / actualPoints;
while (vertexList.length < actualPoints) {
vertexList.add(StraightVertex.procedural()
..x = cos(angle) * halfWidth
..y = sin(angle) * halfHeight
..x = ox + cos(angle) * halfWidth
..y = oy + sin(angle) * halfHeight
..radius = cornerRadius);
angle += inc;
vertexList.add(StraightVertex.procedural()
..x = cos(angle) * innerHalfWidth
..y = sin(angle) * innerHalfHeight
..x = ox + cos(angle) * innerHalfWidth
..y = oy + sin(angle) * innerHalfHeight
..radius = cornerRadius);
angle += inc;
}

View File

@ -106,4 +106,32 @@ class RuntimeArtboard extends Artboard implements CoreContext {
void markNeedsAdvance() {
_redraw.notify();
}
Artboard? instance() {
var artboard = RuntimeArtboard();
artboard.copy(this);
artboard._objects.add(artboard);
// First copy the objects ensuring onAddedDirty can later find them in the
// _objects list.
for (final object in _objects.skip(1)) {
Core? clone = object?.clone();
artboard._objects.add(clone);
}
// Then run the onAddedDirty loop.
for (final object in artboard.objects.skip(1)) {
if (object is Component &&
object.parentId == ComponentBase.parentIdInitialValue) {
object.parent = artboard;
}
object?.onAddedDirty();
}
for (final object in artboard.objects.toList(growable: false)) {
if (object == null) {
continue;
}
object.onAdded();
}
artboard.clean();
}
}