diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bc7191..5e9a5bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [0.0.4] - 2020-07-28 18:35:44 + +- Fundamental changes to runtime format enabling smaller file sizes. Format bumps to version 3.0 as it breaks backwards compatibility. + ## [0.0.3] - 2020-07-19 18:18:50 - Support shorter string encoding. Format bumps to version 2.0 as it breaks backwards compatibility. diff --git a/example/assets/teeny_tiny.riv b/example/assets/teeny_tiny.riv index 14c920e..e9b3a5b 100644 Binary files a/example/assets/teeny_tiny.riv and b/example/assets/teeny_tiny.riv differ diff --git a/example/pubspec.lock b/example/pubspec.lock index dd5e36d..45a6529 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -21,7 +21,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.0-nullsafety" charcode: dependency: transitive description: @@ -42,7 +42,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.13" + version: "1.15.0-nullsafety" fake_async: dependency: transitive description: @@ -80,7 +80,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0-nullsafety" path: dependency: transitive description: @@ -94,7 +94,7 @@ packages: path: ".." relative: true source: path - version: "0.0.3" + version: "0.0.4" sky_engine: dependency: transitive description: flutter @@ -148,13 +148,13 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0-nullsafety" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0-nullsafety" sdks: - dart: ">=2.9.0-14.0.dev <3.0.0" + dart: ">=2.9.0-18.0 <2.9.0" diff --git a/lib/src/core/field_types/core_bool_type.dart b/lib/src/core/field_types/core_bool_type.dart index 8c5b8e5..70bb679 100644 --- a/lib/src/core/field_types/core_bool_type.dart +++ b/lib/src/core/field_types/core_bool_type.dart @@ -1,11 +1,7 @@ import 'package:rive/src/core/field_types/core_field_type.dart'; import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; - class CoreBoolType extends CoreFieldType { @override bool deserialize(BinaryReader reader) => reader.readInt8() == 1; - - @override - bool lerp(bool from, bool to, double f) => from; } diff --git a/lib/src/core/field_types/core_color_type.dart b/lib/src/core/field_types/core_color_type.dart new file mode 100644 index 0000000..321942f --- /dev/null +++ b/lib/src/core/field_types/core_color_type.dart @@ -0,0 +1,7 @@ +import 'package:rive/src/core/field_types/core_field_type.dart'; +import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; + +class CoreColorType extends CoreFieldType { + @override + int deserialize(BinaryReader reader) => reader.readUint32(); +} diff --git a/lib/src/core/field_types/core_double_type.dart b/lib/src/core/field_types/core_double_type.dart index 8722d30..71f8784 100644 --- a/lib/src/core/field_types/core_double_type.dart +++ b/lib/src/core/field_types/core_double_type.dart @@ -3,10 +3,5 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; class CoreDoubleType extends CoreFieldType { @override - double deserialize(BinaryReader reader) => reader.buffer.lengthInBytes == 4 - ? reader.readFloat32() - : reader.readFloat64(); - - @override - double lerp(double from, double to, double f) => from + (to - from) * f; + double deserialize(BinaryReader reader) => reader.readFloat32(); } diff --git a/lib/src/core/field_types/core_field_type.dart b/lib/src/core/field_types/core_field_type.dart index c9e3f7d..a123e05 100644 --- a/lib/src/core/field_types/core_field_type.dart +++ b/lib/src/core/field_types/core_field_type.dart @@ -1,6 +1,6 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; +// ignore: one_member_abstracts abstract class CoreFieldType { T deserialize(BinaryReader reader); - T lerp(T from, T to, double f); } diff --git a/lib/src/core/field_types/core_fractional_index_type.dart b/lib/src/core/field_types/core_fractional_index_type.dart deleted file mode 100644 index 9ecb79a..0000000 --- a/lib/src/core/field_types/core_fractional_index_type.dart +++ /dev/null @@ -1,18 +0,0 @@ - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; - - -class CoreFractionalIndexType extends CoreFieldType { - @override - FractionalIndex deserialize(BinaryReader reader) { - var numerator = reader.readVarInt(); - var denominator = reader.readVarInt(); - return FractionalIndex(numerator, denominator); - } - - @override - FractionalIndex lerp(FractionalIndex from, FractionalIndex to, double f) => - from; -} diff --git a/lib/src/core/field_types/core_int_type.dart b/lib/src/core/field_types/core_int_type.dart index 056a0f0..5642bb1 100644 --- a/lib/src/core/field_types/core_int_type.dart +++ b/lib/src/core/field_types/core_int_type.dart @@ -1,11 +1,7 @@ import 'package:rive/src/core/field_types/core_field_type.dart'; import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; - class CoreIntType extends CoreFieldType { @override int deserialize(BinaryReader reader) => reader.readVarInt(); - - @override - int lerp(int from, int to, double f) => (from + (to - from) * f).round(); } diff --git a/lib/src/core/field_types/core_string_type.dart b/lib/src/core/field_types/core_string_type.dart index cec1892..80c3317 100644 --- a/lib/src/core/field_types/core_string_type.dart +++ b/lib/src/core/field_types/core_string_type.dart @@ -4,8 +4,5 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; class CoreStringType extends CoreFieldType { @override String deserialize(BinaryReader reader) => - reader.readString(explicitLength: false); - - @override - String lerp(String from, String to, double f) => from; + reader.readString(explicitLength: true); } diff --git a/lib/src/core/field_types/core_uint_type.dart b/lib/src/core/field_types/core_uint_type.dart new file mode 100644 index 0000000..cf4bdb1 --- /dev/null +++ b/lib/src/core/field_types/core_uint_type.dart @@ -0,0 +1,7 @@ +import 'package:rive/src/core/field_types/core_field_type.dart'; +import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; + +class CoreUintType extends CoreFieldType { + @override + int deserialize(BinaryReader reader) => reader.readVarUint(); +} diff --git a/lib/src/generated/rive_core_context.dart b/lib/src/generated/rive_core_context.dart index 976a017..5459e8b 100644 --- a/lib/src/generated/rive_core_context.dart +++ b/lib/src/generated/rive_core_context.dart @@ -1,9 +1,11 @@ import 'package:rive/src/core/core.dart'; import 'package:rive/src/core/field_types/core_bool_type.dart'; +import 'package:rive/src/core/field_types/core_color_type.dart'; import 'package:rive/src/core/field_types/core_double_type.dart'; import 'package:rive/src/core/field_types/core_field_type.dart'; import 'package:rive/src/core/field_types/core_int_type.dart'; import 'package:rive/src/core/field_types/core_string_type.dart'; +import 'package:rive/src/core/field_types/core_uint_type.dart'; import 'package:rive/src/generated/animation/animation_base.dart'; import 'package:rive/src/generated/animation/cubic_interpolator_base.dart'; import 'package:rive/src/generated/animation/keyed_object_base.dart'; @@ -476,30 +478,32 @@ class RiveCoreContext { } } + static CoreFieldType uintType = CoreUintType(); static CoreFieldType intType = CoreIntType(); static CoreFieldType stringType = CoreStringType(); static CoreFieldType doubleType = CoreDoubleType(); - static CoreFieldType colorType = CoreIntType(); + static CoreFieldType colorType = CoreColorType(); static CoreFieldType boolType = CoreBoolType(); static CoreFieldType coreType(int propertyKey) { switch (propertyKey) { case KeyedObjectBase.objectIdPropertyKey: + case KeyFrameBase.interpolatorIdPropertyKey: + case KeyFrameDrawOrderValueBase.drawableIdPropertyKey: + case KeyFrameDrawOrderValueBase.valuePropertyKey: + case ComponentBase.parentIdPropertyKey: + case DrawableBase.drawOrderPropertyKey: + return uintType; case KeyedPropertyBase.propertyKeyPropertyKey: case KeyFrameBase.framePropertyKey: case KeyFrameBase.interpolationTypePropertyKey: - case KeyFrameBase.interpolatorIdPropertyKey: case LinearAnimationBase.fpsPropertyKey: case LinearAnimationBase.durationPropertyKey: case LinearAnimationBase.loopValuePropertyKey: case LinearAnimationBase.workStartPropertyKey: case LinearAnimationBase.workEndPropertyKey: - case KeyFrameDrawOrderValueBase.drawableIdPropertyKey: - case KeyFrameDrawOrderValueBase.valuePropertyKey: - case ComponentBase.parentIdPropertyKey: case StrokeBase.capPropertyKey: case StrokeBase.joinPropertyKey: case FillBase.fillRulePropertyKey: - case DrawableBase.drawOrderPropertyKey: case DrawableBase.blendModeValuePropertyKey: return intType; case AnimationBase.namePropertyKey: @@ -560,18 +564,32 @@ class RiveCoreContext { } } - static int getInt(Core object, int propertyKey) { + static int getUint(Core object, int propertyKey) { switch (propertyKey) { case KeyedObjectBase.objectIdPropertyKey: return (object as KeyedObjectBase).objectId; + case KeyFrameBase.interpolatorIdPropertyKey: + return (object as KeyFrameBase).interpolatorId; + case KeyFrameDrawOrderValueBase.drawableIdPropertyKey: + return (object as KeyFrameDrawOrderValueBase).drawableId; + case KeyFrameDrawOrderValueBase.valuePropertyKey: + return (object as KeyFrameDrawOrderValueBase).value; + case ComponentBase.parentIdPropertyKey: + return (object as ComponentBase).parentId; + case DrawableBase.drawOrderPropertyKey: + return (object as DrawableBase).drawOrder; + } + return 0; + } + + static int getInt(Core object, int propertyKey) { + switch (propertyKey) { case KeyedPropertyBase.propertyKeyPropertyKey: return (object as KeyedPropertyBase).propertyKey; case KeyFrameBase.framePropertyKey: return (object as KeyFrameBase).frame; case KeyFrameBase.interpolationTypePropertyKey: return (object as KeyFrameBase).interpolationType; - case KeyFrameBase.interpolatorIdPropertyKey: - return (object as KeyFrameBase).interpolatorId; case LinearAnimationBase.fpsPropertyKey: return (object as LinearAnimationBase).fps; case LinearAnimationBase.durationPropertyKey: @@ -582,20 +600,12 @@ class RiveCoreContext { return (object as LinearAnimationBase).workStart; case LinearAnimationBase.workEndPropertyKey: return (object as LinearAnimationBase).workEnd; - case KeyFrameDrawOrderValueBase.drawableIdPropertyKey: - return (object as KeyFrameDrawOrderValueBase).drawableId; - case KeyFrameDrawOrderValueBase.valuePropertyKey: - return (object as KeyFrameDrawOrderValueBase).value; - case ComponentBase.parentIdPropertyKey: - return (object as ComponentBase).parentId; case StrokeBase.capPropertyKey: return (object as StrokeBase).cap; case StrokeBase.joinPropertyKey: return (object as StrokeBase).join; case FillBase.fillRulePropertyKey: return (object as FillBase).fillRule; - case DrawableBase.drawOrderPropertyKey: - return (object as DrawableBase).drawOrder; case DrawableBase.blendModeValuePropertyKey: return (object as DrawableBase).blendModeValue; } @@ -724,11 +734,31 @@ class RiveCoreContext { return false; } - static void setInt(Core object, int propertyKey, int value) { + static void setUint(Core object, int propertyKey, int value) { switch (propertyKey) { case KeyedObjectBase.objectIdPropertyKey: (object as KeyedObjectBase).objectId = value; break; + case KeyFrameBase.interpolatorIdPropertyKey: + (object as KeyFrameBase).interpolatorId = value; + break; + case KeyFrameDrawOrderValueBase.drawableIdPropertyKey: + (object as KeyFrameDrawOrderValueBase).drawableId = value; + break; + case KeyFrameDrawOrderValueBase.valuePropertyKey: + (object as KeyFrameDrawOrderValueBase).value = value; + break; + case ComponentBase.parentIdPropertyKey: + (object as ComponentBase).parentId = value; + break; + case DrawableBase.drawOrderPropertyKey: + (object as DrawableBase).drawOrder = value; + break; + } + } + + static void setInt(Core object, int propertyKey, int value) { + switch (propertyKey) { case KeyedPropertyBase.propertyKeyPropertyKey: (object as KeyedPropertyBase).propertyKey = value; break; @@ -738,9 +768,6 @@ class RiveCoreContext { case KeyFrameBase.interpolationTypePropertyKey: (object as KeyFrameBase).interpolationType = value; break; - case KeyFrameBase.interpolatorIdPropertyKey: - (object as KeyFrameBase).interpolatorId = value; - break; case LinearAnimationBase.fpsPropertyKey: (object as LinearAnimationBase).fps = value; break; @@ -756,15 +783,6 @@ class RiveCoreContext { case LinearAnimationBase.workEndPropertyKey: (object as LinearAnimationBase).workEnd = value; break; - case KeyFrameDrawOrderValueBase.drawableIdPropertyKey: - (object as KeyFrameDrawOrderValueBase).drawableId = value; - break; - case KeyFrameDrawOrderValueBase.valuePropertyKey: - (object as KeyFrameDrawOrderValueBase).value = value; - break; - case ComponentBase.parentIdPropertyKey: - (object as ComponentBase).parentId = value; - break; case StrokeBase.capPropertyKey: (object as StrokeBase).cap = value; break; @@ -774,9 +792,6 @@ class RiveCoreContext { case FillBase.fillRulePropertyKey: (object as FillBase).fillRule = value; break; - case DrawableBase.drawOrderPropertyKey: - (object as DrawableBase).drawOrder = value; - break; case DrawableBase.blendModeValuePropertyKey: (object as DrawableBase).blendModeValue = value; break; diff --git a/lib/src/generated/shapes/rectangle_base.dart b/lib/src/generated/shapes/rectangle_base.dart index ddda4fc..60d1de4 100644 --- a/lib/src/generated/shapes/rectangle_base.dart +++ b/lib/src/generated/shapes/rectangle_base.dart @@ -24,7 +24,7 @@ abstract class RectangleBase extends ParametricPath { /// -------------------------------------------------------------------------- /// CornerRadius field with key 31. - double _cornerRadius; + double _cornerRadius = 0; static const int cornerRadiusPropertyKey = 31; /// Radius of the corners of this rectangle diff --git a/lib/src/rive_core/math/circle_constant.dart b/lib/src/rive_core/math/circle_constant.dart index 08aee37..67f3041 100644 --- a/lib/src/rive_core/math/circle_constant.dart +++ b/lib/src/rive_core/math/circle_constant.dart @@ -1 +1 @@ -double circleConstant = 0.552284749831; +const circleConstant = 0.552284749831; diff --git a/lib/src/rive_core/math/mat2d.dart b/lib/src/rive_core/math/mat2d.dart index cab0418..ac86869 100644 --- a/lib/src/rive_core/math/mat2d.dart +++ b/lib/src/rive_core/math/mat2d.dart @@ -48,6 +48,10 @@ class Mat2D { Mat2D.fromScaling(Vec2D scaling) { _buffer = Float32List.fromList([scaling[0], 0, 0, scaling[1], 0, 0]); } + Mat2D.fromMat4(Float64List mat4) { + _buffer = Float32List.fromList( + [mat4[0], mat4[1], mat4[4], mat4[5], mat4[12], mat4[13]]); + } Mat2D.clone(Mat2D copy) { _buffer = Float32List.fromList(copy.values); } diff --git a/lib/src/rive_core/runtime/runtime_header.dart b/lib/src/rive_core/runtime/runtime_header.dart index 333bb35..00ce8ee 100644 --- a/lib/src/rive_core/runtime/runtime_header.dart +++ b/lib/src/rive_core/runtime/runtime_header.dart @@ -4,7 +4,7 @@ import 'package:rive/src/utilities/binary_buffer/binary_reader.dart'; import 'exceptions/rive_format_error_exception.dart'; class RuntimeHeader { - static const int majorVersion = 2; + static const int majorVersion = 3; static const int minorVersion = 0; static const String fingerprint = 'RIVE'; final int ownerId; diff --git a/lib/src/rive_core/shapes/ellipse.dart b/lib/src/rive_core/shapes/ellipse.dart index 9b4f935..2e934a7 100644 --- a/lib/src/rive_core/shapes/ellipse.dart +++ b/lib/src/rive_core/shapes/ellipse.dart @@ -1,10 +1,9 @@ +import 'package:rive/src/rive_core/math/circle_constant.dart'; import 'package:rive/src/rive_core/shapes/cubic_detached_vertex.dart'; import 'package:rive/src/rive_core/shapes/path_vertex.dart'; import 'package:rive/src/generated/shapes/ellipse_base.dart'; export 'package:rive/src/generated/shapes/ellipse_base.dart'; -const double circleConstant = 0.55; - class Ellipse extends EllipseBase { @override List get vertices => [ diff --git a/lib/src/rive_core/shapes/path.dart b/lib/src/rive_core/shapes/path.dart index b575381..280deaa 100644 --- a/lib/src/rive_core/shapes/path.dart +++ b/lib/src/rive_core/shapes/path.dart @@ -3,6 +3,7 @@ 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/math/aabb.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'; import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; @@ -98,7 +99,7 @@ abstract class Path extends PathBase { } List renderPoints = []; int pl = pts.length; - const double arcConstant = 0.55; + const arcConstant = circleConstant; const double iarcConstant = 1.0 - arcConstant; PathVertex previous = isClosed ? pts[pl - 1] : null; for (int i = 0; i < pl; i++) { diff --git a/lib/src/rive_file.dart b/lib/src/rive_file.dart index a3d159c..871d51b 100644 --- a/lib/src/rive_file.dart +++ b/lib/src/rive_file.dart @@ -99,7 +99,7 @@ class RiveFile { int numValues = reader.readVarUint(); for (int m = 0; m < numValues; m++) { var valueObject = KeyFrameDrawOrderValue(); - valueObject.drawableId = reader.readVarInt(); + valueObject.drawableId = reader.readVarUint(); valueObject.value = m; keyframe.internalAddValue(valueObject); } @@ -153,30 +153,15 @@ T readRuntimeObject>(BinaryReader reader, // Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif break; } - int propertyLength = reader.readVarUint(); - Uint8List valueBytes = reader.read(propertyLength); var fieldType = RiveCoreContext.coreType(propertyKey); if (fieldType == null) { - // This is considered an acceptable failure. A runtime may not support - // the same properties that were exported. The older object could still - // function without them, however, so it's up to the implementation to - // make sure that major versions are revved when breaking properties are - // added. Note that we intentionally first read the entire value bytes - // for the property so we can advance as expected even if we are - // skipping this value. - continue; + throw UnsupportedError('Unsupported property key $propertyKey. ' + 'A new runtime is likely necessary to play this file.'); } - // We know what to expect, let's try to read the value. We instance a new - // reader here so that we don't overflow the exact length we're allowed to - // read. - var valueReader = BinaryReader.fromList(valueBytes); - - // This will attempt to set the object property, but failure here is - // acceptable. RiveCoreContext.setObjectProperty( - object, propertyKey, fieldType.deserialize(valueReader)); + object, propertyKey, fieldType.deserialize(reader)); } return object as T; } diff --git a/lib/src/utilities/binary_buffer/binary_reader.dart b/lib/src/utilities/binary_buffer/binary_reader.dart index f2006c9..b5b85e7 100644 --- a/lib/src/utilities/binary_buffer/binary_reader.dart +++ b/lib/src/utilities/binary_buffer/binary_reader.dart @@ -7,6 +7,7 @@ class BinaryReader { final ByteData buffer; final Endian endian; int _readIndex = 0; + int get position => _readIndex; BinaryReader(this.buffer, {this.endian = Endian.little}); diff --git a/pubspec.lock b/pubspec.lock index efae536..13bf620 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -73,7 +73,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.9" + version: "0.12.8" meta: dependency: "direct main" description: @@ -134,7 +134,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.18" + version: "0.2.17" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c7b4bc4..dd775f9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: rive description: Rive 2 Flutter Runtime -version: 0.0.3 +version: 0.0.4 repository: https://github.com/rive-app/rive-flutter homepage: https://rive.app