From 79b2aed22f0eb1f758235b6eaedd49aaa2b75ddf Mon Sep 17 00:00:00 2001 From: Luigi Rosso Date: Tue, 22 Dec 2020 16:59:35 -0800 Subject: [PATCH] Adding visibility toggles and prepping for 0.6.5. --- CHANGELOG.md | 6 +++++ lib/src/generated/drawable_base.dart | 20 ++++++++++++++++ lib/src/generated/rive_core_context.dart | 23 +++++++++++++++++++ lib/src/generated/shapes/path_base.dart | 19 +++++++++++++++ lib/src/rive_core/artboard.dart | 3 +++ lib/src/rive_core/component_flags.dart | 4 ++++ lib/src/rive_core/drawable.dart | 5 ++++ lib/src/rive_core/math/aabb.dart | 13 ++++++++++- lib/src/rive_core/math/vec2d.dart | 9 +++++++- lib/src/rive_core/runtime/runtime_header.dart | 8 +++---- lib/src/rive_core/shapes/path.dart | 5 ++++ lib/src/rive_core/shapes/path_composer.dart | 6 +++++ lib/src/rive_core/shapes/polygon.dart | 2 +- lib/src/rive_core/shapes/star.dart | 3 ++- lib/src/rive_file.dart | 6 ++--- lib/src/utilities/utilities.dart | 9 ++++++++ pubspec.yaml | 2 +- 17 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 lib/src/rive_core/component_flags.dart create mode 100644 lib/src/utilities/utilities.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index a224f76..a79343a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [0.6.5] - 2020-12-22 16:49:39 + +- Fixing issue with older minor versions crashing when newer minor files included objects with unknown keys. The runtime can now read beyond those. +- Shapes and paths hidden in the editor will not show up at runtime. +- Runtime header now exposes Rive project id. + ## [0.6.4] - 2020-12-11 15:43:01 - Adding support for parametric polygon and star shapes. diff --git a/lib/src/generated/drawable_base.dart b/lib/src/generated/drawable_base.dart index 1b03ee6..7fe29be 100644 --- a/lib/src/generated/drawable_base.dart +++ b/lib/src/generated/drawable_base.dart @@ -39,4 +39,24 @@ abstract class DrawableBase extends Node { } void blendModeValueChanged(int from, int to); + + /// -------------------------------------------------------------------------- + /// DrawableFlags field with key 129. + int _drawableFlags = 0; + static const int drawableFlagsPropertyKey = 129; + int get drawableFlags => _drawableFlags; + + /// Change the [_drawableFlags] field value. + /// [drawableFlagsChanged] will be invoked only if the field's value has + /// changed. + set drawableFlags(int value) { + if (_drawableFlags == value) { + return; + } + int from = _drawableFlags; + _drawableFlags = value; + drawableFlagsChanged(from, value); + } + + void drawableFlagsChanged(int from, int to); } diff --git a/lib/src/generated/rive_core_context.dart b/lib/src/generated/rive_core_context.dart index 1286070..d58f922 100644 --- a/lib/src/generated/rive_core_context.dart +++ b/lib/src/generated/rive_core_context.dart @@ -41,6 +41,7 @@ import 'package:rive/src/generated/shapes/paint/solid_color_base.dart'; import 'package:rive/src/generated/shapes/paint/stroke_base.dart'; import 'package:rive/src/generated/shapes/paint/trim_path_base.dart'; import 'package:rive/src/generated/shapes/parametric_path_base.dart'; +import 'package:rive/src/generated/shapes/path_base.dart'; import 'package:rive/src/generated/shapes/path_composer_base.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; import 'package:rive/src/generated/shapes/points_path_base.dart'; @@ -428,11 +429,21 @@ class RiveCoreContext { object.y = value; } break; + case PathBase.pathFlagsPropertyKey: + if (object is PathBase && value is int) { + object.pathFlags = value; + } + break; case DrawableBase.blendModeValuePropertyKey: if (object is DrawableBase && value is int) { object.blendModeValue = value; } break; + case DrawableBase.drawableFlagsPropertyKey: + if (object is DrawableBase && value is int) { + object.drawableFlags = value; + } + break; case PathVertexBase.xPropertyKey: if (object is PathVertexBase && value is double) { object.x = value; @@ -729,7 +740,9 @@ class RiveCoreContext { case StrokeBase.joinPropertyKey: case TrimPathBase.modeValuePropertyKey: case FillBase.fillRulePropertyKey: + case PathBase.pathFlagsPropertyKey: case DrawableBase.blendModeValuePropertyKey: + case DrawableBase.drawableFlagsPropertyKey: case WeightBase.valuesPropertyKey: case WeightBase.indicesPropertyKey: case CubicWeightBase.inValuesPropertyKey: @@ -868,8 +881,12 @@ class RiveCoreContext { return (object as TrimPathBase).modeValue; case FillBase.fillRulePropertyKey: return (object as FillBase).fillRule; + case PathBase.pathFlagsPropertyKey: + return (object as PathBase).pathFlags; case DrawableBase.blendModeValuePropertyKey: return (object as DrawableBase).blendModeValue; + case DrawableBase.drawableFlagsPropertyKey: + return (object as DrawableBase).drawableFlags; case WeightBase.valuesPropertyKey: return (object as WeightBase).values; case WeightBase.indicesPropertyKey: @@ -1121,9 +1138,15 @@ class RiveCoreContext { case FillBase.fillRulePropertyKey: (object as FillBase).fillRule = value; break; + case PathBase.pathFlagsPropertyKey: + (object as PathBase).pathFlags = value; + break; case DrawableBase.blendModeValuePropertyKey: (object as DrawableBase).blendModeValue = value; break; + case DrawableBase.drawableFlagsPropertyKey: + (object as DrawableBase).drawableFlags = value; + break; case WeightBase.valuesPropertyKey: (object as WeightBase).values = value; break; diff --git a/lib/src/generated/shapes/path_base.dart b/lib/src/generated/shapes/path_base.dart index 4af6ae9..affe8e7 100644 --- a/lib/src/generated/shapes/path_base.dart +++ b/lib/src/generated/shapes/path_base.dart @@ -19,4 +19,23 @@ abstract class PathBase extends Node { ContainerComponentBase.typeKey, ComponentBase.typeKey }; + + /// -------------------------------------------------------------------------- + /// PathFlags field with key 128. + int _pathFlags = 0; + static const int pathFlagsPropertyKey = 128; + int get pathFlags => _pathFlags; + + /// Change the [_pathFlags] field value. + /// [pathFlagsChanged] will be invoked only if the field's value has changed. + set pathFlags(int value) { + if (_pathFlags == value) { + return; + } + int from = _pathFlags; + _pathFlags = value; + pathFlagsChanged(from, value); + } + + void pathFlagsChanged(int from, int to); } diff --git a/lib/src/rive_core/artboard.dart b/lib/src/rive_core/artboard.dart index 4dfd522..d3d1e43 100644 --- a/lib/src/rive_core/artboard.dart +++ b/lib/src/rive_core/artboard.dart @@ -172,6 +172,9 @@ class Artboard extends ArtboardBase with ShapePaintContainer { for (var drawable = _firstDrawable; drawable != null; drawable = drawable.prev) { + if (drawable.isHidden) { + continue; + } drawable.draw(canvas); } canvas.restore(); diff --git a/lib/src/rive_core/component_flags.dart b/lib/src/rive_core/component_flags.dart new file mode 100644 index 0000000..a999c6b --- /dev/null +++ b/lib/src/rive_core/component_flags.dart @@ -0,0 +1,4 @@ +class ComponentFlags { + static const int hidden = 1 << 0; + static const int locked = 1 << 1; +} diff --git a/lib/src/rive_core/drawable.dart b/lib/src/rive_core/drawable.dart index 2b3f7b6..8d66249 100644 --- a/lib/src/rive_core/drawable.dart +++ b/lib/src/rive_core/drawable.dart @@ -1,5 +1,6 @@ import 'dart:ui'; import 'package:rive/src/rive_core/component_dirt.dart'; +import 'package:rive/src/rive_core/component_flags.dart'; import 'package:rive/src/rive_core/container_component.dart'; import 'package:rive/src/rive_core/draw_rules.dart'; import 'package:rive/src/rive_core/shapes/clipping_shape.dart'; @@ -60,4 +61,8 @@ abstract class Drawable extends DrawableBase { _clippingShapes = clippingShapes.isEmpty ? null : clippingShapes; } } + + @override + void drawableFlagsChanged(int from, int to) => addDirt(ComponentDirt.paint); + bool get isHidden => (drawableFlags & ComponentFlags.hidden) != 0; } diff --git a/lib/src/rive_core/math/aabb.dart b/lib/src/rive_core/math/aabb.dart index a84d0fb..4c796dc 100644 --- a/lib/src/rive_core/math/aabb.dart +++ b/lib/src/rive_core/math/aabb.dart @@ -44,7 +44,18 @@ class AABB { -double.maxFinite ]); } - double get area => width * height; + factory AABB.expand(AABB from, double amount) { + var aabb = AABB.clone(from); + if (aabb.width < amount) { + aabb[0] -= amount / 2; + aabb[2] += amount / 2; + } + if (aabb.height < amount) { + aabb[1] -= amount / 2; + aabb[3] += amount / 2; + } + return aabb; + } bool get isEmpty => !AABB.isValid(this); Vec2D includePoint(Vec2D point, Mat2D transform) { var transformedPoint = transform == null diff --git a/lib/src/rive_core/math/vec2d.dart b/lib/src/rive_core/math/vec2d.dart index ec26993..fff56f4 100644 --- a/lib/src/rive_core/math/vec2d.dart +++ b/lib/src/rive_core/math/vec2d.dart @@ -1,5 +1,6 @@ import 'dart:math'; import 'dart:typed_data'; +import 'package:rive/src/utilities/utilities.dart'; import 'mat2d.dart'; class Vec2D { @@ -163,7 +164,13 @@ class Vec2D { @override String toString() { - String v = _buffer[0].toString() + ", "; + String v = _buffer[0].toString() + ', '; return v + _buffer[1].toString(); } + + @override + bool operator ==(Object o) => + o is Vec2D && _buffer[0] == o[0] && _buffer[1] == o[1]; + @override + int get hashCode => szudzik(_buffer[0].hashCode, _buffer[1].hashCode); } diff --git a/lib/src/rive_core/runtime/runtime_header.dart b/lib/src/rive_core/runtime/runtime_header.dart index 3b46362..3e5b01c 100644 --- a/lib/src/rive_core/runtime/runtime_header.dart +++ b/lib/src/rive_core/runtime/runtime_header.dart @@ -15,11 +15,11 @@ const riveVersion = RuntimeVersion(6, 3); class RuntimeHeader { static const String fingerprint = 'RIVE'; final RuntimeVersion version; - final int ownerId; + final int projectId; final int fileId; final HashMap propertyToFieldIndex; RuntimeHeader( - {@required this.ownerId, + {@required this.projectId, @required this.fileId, @required this.version, this.propertyToFieldIndex}); @@ -36,7 +36,7 @@ class RuntimeHeader { throw RiveUnsupportedVersionException(riveVersion.major, riveVersion.minor, readMajorVersion, readMinorVersion); } - int ownerId = reader.readVarUint(); + int projectId = reader.readVarUint(); int fileId = reader.readVarUint(); var propertyFields = HashMap(); var propertyKeys = []; @@ -57,7 +57,7 @@ class RuntimeHeader { currentBit += 2; } return RuntimeHeader( - ownerId: ownerId, + projectId: projectId, fileId: fileId, version: RuntimeVersion(readMajorVersion, readMinorVersion), propertyToFieldIndex: propertyFields); diff --git a/lib/src/rive_core/shapes/path.dart b/lib/src/rive_core/shapes/path.dart index 9be6849..2f0434d 100644 --- a/lib/src/rive_core/shapes/path.dart +++ b/lib/src/rive_core/shapes/path.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'dart:ui' as ui; import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; +import 'package:rive/src/rive_core/component_flags.dart'; import 'package:rive/src/rive_core/math/circle_constant.dart'; import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart'; @@ -215,6 +216,10 @@ abstract class Path extends PathBase { } return true; } + + @override + void pathFlagsChanged(int from, int to) => markPathDirty(); + bool get isHidden => (pathFlags & ComponentFlags.hidden) != 0; } class RenderPath { diff --git a/lib/src/rive_core/shapes/path_composer.dart b/lib/src/rive_core/shapes/path_composer.dart index b6bd4b3..00a481c 100644 --- a/lib/src/rive_core/shapes/path_composer.dart +++ b/lib/src/rive_core/shapes/path_composer.dart @@ -32,6 +32,9 @@ class PathComposer extends PathComposerBase { Mat2D inverseWorld = Mat2D(); if (Mat2D.invert(inverseWorld, world)) { for (final path in _shape.paths) { + if (path.isHidden) { + continue; + } Mat2D localTransform; var transform = path.pathTransform; if (transform != null) { @@ -46,6 +49,9 @@ class PathComposer extends PathComposerBase { if (buildWorldPath) { worldPath.reset(); for (final path in _shape.paths) { + if (path.isHidden) { + continue; + } worldPath.addPath(path.uiPath, ui.Offset.zero, matrix4: path.pathTransform?.mat4); } diff --git a/lib/src/rive_core/shapes/polygon.dart b/lib/src/rive_core/shapes/polygon.dart index 41d2da2..589bcbb 100644 --- a/lib/src/rive_core/shapes/polygon.dart +++ b/lib/src/rive_core/shapes/polygon.dart @@ -12,7 +12,7 @@ class Polygon extends PolygonBase { void pointsChanged(int from, int to) => markPathDirty(); @override List> get vertices { - var vertexList = List(points); + var vertexList = List.filled(points, null); var halfWidth = width / 2; var halfHeight = height / 2; var angle = -pi / 2; diff --git a/lib/src/rive_core/shapes/star.dart b/lib/src/rive_core/shapes/star.dart index fad61c9..f309bcf 100644 --- a/lib/src/rive_core/shapes/star.dart +++ b/lib/src/rive_core/shapes/star.dart @@ -11,7 +11,8 @@ class Star extends StarBase { @override List> get vertices { var actualPoints = points * 2; - var vertexList = List(actualPoints); + var vertexList = + List.filled(actualPoints, null, growable: false); var halfWidth = width / 2; var halfHeight = height / 2; var innerHalfWidth = width * innerRadius / 2; diff --git a/lib/src/rive_file.dart b/lib/src/rive_file.dart index 2d02fbf..cef8b95 100644 --- a/lib/src/rive_file.dart +++ b/lib/src/rive_file.dart @@ -100,7 +100,7 @@ class RiveFile { animation.artboard = artboard; if (animation is LinearAnimation) { var numKeyedObjects = reader.readVarUint(); - var keyedObjects = List(numKeyedObjects); + var keyedObjects = List.filled(numKeyedObjects, null); for (int j = 0; j < numKeyedObjects; j++) { var keyedObject = _readRuntimeObject(reader, propertyToField); @@ -153,8 +153,8 @@ class RiveFile { assert(!artboard.children.contains(artboard), 'artboard should never contain itself as a child'); - for (final object in artboard.objects.toList(growable:false)) { - if(object == null) { + for (final object in artboard.objects.toList(growable: false)) { + if (object == null) { continue; } object.onAdded(); diff --git a/lib/src/utilities/utilities.dart b/lib/src/utilities/utilities.dart new file mode 100644 index 0000000..7411003 --- /dev/null +++ b/lib/src/utilities/utilities.dart @@ -0,0 +1,9 @@ +/// Szudzik's function for hashing two ints together +int szudzik(int a, int b) { + assert(a != null && b != null); + // a and b must be >= 0 + + int x = a.abs(); + int y = b.abs(); + return x >= y ? x * x + x + y : x + y * y; +} diff --git a/pubspec.yaml b/pubspec.yaml index 8fe421a..9e1ae2a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: rive description: Rive 2 Flutter Runtime. This package provides runtime functionality for playing back and interacting with animations built with the Rive editor available at https://rive.app. -version: 0.6.4 +version: 0.6.5 repository: https://github.com/rive-app/rive-flutter homepage: https://rive.app