From 2ac6bccb9ebd8ca541047f0884da1c7e26d9392a Mon Sep 17 00:00:00 2001 From: Luigi Rosso Date: Fri, 26 Mar 2021 14:51:28 -0700 Subject: [PATCH] Updating with latest generated code. --- lib/src/core/core.dart | 2 +- lib/src/core/importers/artboard_importer.dart | 2 +- lib/src/generated/rive_core_context.dart | 4 -- lib/src/rive_core/animation/keyed_object.dart | 23 +++++++- .../rive_core/animation/keyed_property.dart | 1 - lib/src/rive_core/animation/layer_state.dart | 3 -- .../rive_core/animation/linear_animation.dart | 9 +++- .../animation/state_machine_layer.dart | 12 ++--- .../rive_core/animation/state_transition.dart | 4 +- .../rive_core/bones/skeletal_component.dart | 12 +---- lib/src/rive_core/bones/skin.dart | 13 +++-- lib/src/rive_core/bones/tendon.dart | 6 +-- lib/src/rive_core/component.dart | 4 +- lib/src/rive_core/runtime/runtime_header.dart | 3 ++ .../shapes/paint/linear_gradient.dart | 11 +++- .../rive_core/shapes/paint/shape_paint.dart | 13 ++++- lib/src/rive_core/shapes/path_composer.dart | 54 +++++-------------- lib/src/rive_core/shapes/shape.dart | 28 +++++----- .../rive_core/state_machine_controller.dart | 12 +++-- lib/src/rive_file.dart | 11 +++- lib/src/runtime_artboard.dart | 6 +-- 21 files changed, 128 insertions(+), 105 deletions(-) diff --git a/lib/src/core/core.dart b/lib/src/core/core.dart index fb8e784..8635b7c 100644 --- a/lib/src/core/core.dart +++ b/lib/src/core/core.dart @@ -53,7 +53,7 @@ abstract class CoreContext { void markDependencyOrderDirty(); bool markDependenciesDirty(covariant Core rootObject); void removeObject(T object); - T addObject(T object); + T? addObject(T? object); void markNeedsAdvance(); void dirty(void Function() dirt); } diff --git a/lib/src/core/importers/artboard_importer.dart b/lib/src/core/importers/artboard_importer.dart index 2757717..79c847c 100644 --- a/lib/src/core/importers/artboard_importer.dart +++ b/lib/src/core/importers/artboard_importer.dart @@ -9,7 +9,7 @@ class ArtboardImporter extends ImportStackObject { ArtboardImporter(this.artboard); final List animations = []; - void addComponent(Core object) => artboard.addObject(object); + void addComponent(Core? object) => artboard.addObject(object); void addAnimation(Animation animation) { if (animation is LinearAnimation) { diff --git a/lib/src/generated/rive_core_context.dart b/lib/src/generated/rive_core_context.dart index a31c6fd..097df3d 100644 --- a/lib/src/generated/rive_core_context.dart +++ b/lib/src/generated/rive_core_context.dart @@ -58,7 +58,6 @@ 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'; import 'package:rive/src/generated/shapes/polygon_base.dart'; @@ -112,7 +111,6 @@ import 'package:rive/src/rive_core/shapes/paint/radial_gradient.dart'; import 'package:rive/src/rive_core/shapes/paint/solid_color.dart'; import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; import 'package:rive/src/rive_core/shapes/paint/trim_path.dart'; -import 'package:rive/src/rive_core/shapes/path_composer.dart'; import 'package:rive/src/rive_core/shapes/points_path.dart'; import 'package:rive/src/rive_core/shapes/polygon.dart'; import 'package:rive/src/rive_core/shapes/rectangle.dart'; @@ -211,8 +209,6 @@ class RiveCoreContext { return Polygon(); case StarBase.typeKey: return Star(); - case PathComposerBase.typeKey: - return PathComposer(); case CubicDetachedVertexBase.typeKey: return CubicDetachedVertex(); case DrawRulesBase.typeKey: diff --git a/lib/src/rive_core/animation/keyed_object.dart b/lib/src/rive_core/animation/keyed_object.dart index c182738..d752b70 100644 --- a/lib/src/rive_core/animation/keyed_object.dart +++ b/lib/src/rive_core/animation/keyed_object.dart @@ -1,6 +1,7 @@ import 'dart:collection'; import 'package:rive/src/core/core.dart'; import 'package:rive/src/rive_core/animation/keyed_property.dart'; +import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/generated/animation/keyed_object_base.dart'; import 'linear_animation.dart'; export 'package:rive/src/generated/animation/keyed_object_base.dart'; @@ -10,14 +11,34 @@ class KeyedObject extends KeyedObjectBase { HashMap(); Iterable get keyedProperties => _keyedProperties.values; @override + void onAddedDirty() {} + @override void onAdded() {} @override - void onAddedDirty() {} + bool validate() { + if (!super.validate()) { + return false; + } + var component = context.resolve(objectId); + if (component == null) { + return false; + } + return true; + } + @override void onRemoved() { super.onRemoved(); } + bool isValidKeyedProperty(KeyedProperty property) { + var value = _keyedProperties[property.propertyKey]; + if (value != null && value != property) { + return false; + } + return true; + } + bool internalAddKeyedProperty(KeyedProperty property) { var value = _keyedProperties[property.propertyKey]; if (value != null && value != property) { diff --git a/lib/src/rive_core/animation/keyed_property.dart b/lib/src/rive_core/animation/keyed_property.dart index 3d88c31..5a9cec8 100644 --- a/lib/src/rive_core/animation/keyed_property.dart +++ b/lib/src/rive_core/animation/keyed_property.dart @@ -84,7 +84,6 @@ class KeyedProperty extends KeyedPropertyBase } void _sortAndValidateKeyFrames() { - assert(hasValidated); sort(); for (int i = 0; i < _keyframes.length - 1; i++) { var a = _keyframes[i]; diff --git a/lib/src/rive_core/animation/layer_state.dart b/lib/src/rive_core/animation/layer_state.dart index 7f81f87..324c175 100644 --- a/lib/src/rive_core/animation/layer_state.dart +++ b/lib/src/rive_core/animation/layer_state.dart @@ -4,12 +4,9 @@ import 'package:rive/src/rive_core/animation/state_transition.dart'; import 'package:rive/src/generated/animation/layer_state_base.dart'; export 'package:rive/src/generated/animation/layer_state_base.dart'; -class _UnknownLayerState extends LayerState {} - abstract class LayerState extends LayerStateBase { final Set _transitions = {}; Iterable get transitions => _transitions; - static final LayerState unknown = _UnknownLayerState(); @override void onAdded() {} @override diff --git a/lib/src/rive_core/animation/linear_animation.dart b/lib/src/rive_core/animation/linear_animation.dart index d912250..9c6c239 100644 --- a/lib/src/rive_core/animation/linear_animation.dart +++ b/lib/src/rive_core/animation/linear_animation.dart @@ -10,11 +10,18 @@ class LinearAnimation extends LinearAnimationBase { final _keyedObjects = HashMap(); Iterable get keyedObjects => _keyedObjects.values; bool internalAddKeyedObject(KeyedObject object) { + if (internalCheckAddKeyedObject(object)) { + _keyedObjects[object.objectId] = object; + return true; + } + return false; + } + + bool internalCheckAddKeyedObject(KeyedObject object) { var value = _keyedObjects[object.objectId]; if (value != null && value != object) { return false; } - _keyedObjects[object.objectId] = object; return true; } diff --git a/lib/src/rive_core/animation/state_machine_layer.dart b/lib/src/rive_core/animation/state_machine_layer.dart index 7c7f3a0..f9caa2c 100644 --- a/lib/src/rive_core/animation/state_machine_layer.dart +++ b/lib/src/rive_core/animation/state_machine_layer.dart @@ -10,12 +10,12 @@ import 'package:rive/src/generated/animation/state_machine_layer_base.dart'; export 'package:rive/src/generated/animation/state_machine_layer_base.dart'; class StateMachineLayer extends StateMachineLayerBase { - LayerState _entryState = LayerState.unknown; - LayerState _anyState = LayerState.unknown; - LayerState _exitState = LayerState.unknown; - LayerState get entryState => _entryState; - LayerState get anyState => _anyState; - LayerState get exitState => _exitState; + LayerState? _entryState; + LayerState? _anyState; + LayerState? _exitState; + LayerState? get entryState => _entryState; + LayerState? get anyState => _anyState; + LayerState? get exitState => _exitState; @override ListBase machineComponentList(StateMachine machine) => machine.layers; diff --git a/lib/src/rive_core/animation/state_transition.dart b/lib/src/rive_core/animation/state_transition.dart index 32c5e12..10a5ba0 100644 --- a/lib/src/rive_core/animation/state_transition.dart +++ b/lib/src/rive_core/animation/state_transition.dart @@ -7,11 +7,11 @@ export 'package:rive/src/generated/animation/state_transition_base.dart'; class StateTransition extends StateTransitionBase { final StateTransitionConditions conditions = StateTransitionConditions(); - LayerState stateTo = LayerState.unknown; + LayerState? stateTo; static final StateTransition unknown = StateTransition(); @override bool validate() { - return super.validate() && stateTo != LayerState.unknown; + return super.validate() && stateTo != null; } @override diff --git a/lib/src/rive_core/bones/skeletal_component.dart b/lib/src/rive_core/bones/skeletal_component.dart index 531e709..159005e 100644 --- a/lib/src/rive_core/bones/skeletal_component.dart +++ b/lib/src/rive_core/bones/skeletal_component.dart @@ -1,14 +1,4 @@ import 'package:rive/src/generated/bones/skeletal_component_base.dart'; export 'package:rive/src/generated/bones/skeletal_component_base.dart'; -class _UnknownSkeletalComponent extends SkeletalComponent { - @override - double x = 0; - @override - double y = 0; -} - -// ignore: avoid_classes_with_only_static_members -abstract class SkeletalComponent extends SkeletalComponentBase { - static final SkeletalComponent unknown = _UnknownSkeletalComponent(); -} +abstract class SkeletalComponent extends SkeletalComponentBase {} diff --git a/lib/src/rive_core/bones/skin.dart b/lib/src/rive_core/bones/skin.dart index a16bab5..1f8fba6 100644 --- a/lib/src/rive_core/bones/skin.dart +++ b/lib/src/rive_core/bones/skin.dart @@ -32,7 +32,10 @@ class Skin extends SkinBase { var temp = Mat2D(); var bidx = 6; for (final tendon in _tendons) { - var boneWorld = tendon.bone.worldTransform; + if (tendon.bone == null) { + continue; + } + var boneWorld = tendon.bone!.worldTransform; var wt = Mat2D.multiply(temp, boneWorld, tendon.inverseBind); _boneTransforms[bidx++] = wt[0]; _boneTransforms[bidx++] = wt[1]; @@ -77,7 +80,7 @@ class Skin extends SkinBase { void buildDependencies() { super.buildDependencies(); for (final tendon in _tendons) { - tendon.bone.addDependent(this); + tendon.bone?.addDependent(this); } } @@ -88,7 +91,9 @@ class Skin extends SkinBase { case TendonBase.typeKey: _tendons.add(child as Tendon); markRebuildDependencies(); - parent!.markRebuildDependencies(); + if (parent is Skinnable) { + parent!.markRebuildDependencies(); + } break; } } @@ -104,7 +109,7 @@ class Skin extends SkinBase { } else { markRebuildDependencies(); } - parent!.markRebuildDependencies(); + parent?.markRebuildDependencies(); break; } } diff --git a/lib/src/rive_core/bones/tendon.dart b/lib/src/rive_core/bones/tendon.dart index b332714..05466a1 100644 --- a/lib/src/rive_core/bones/tendon.dart +++ b/lib/src/rive_core/bones/tendon.dart @@ -6,8 +6,8 @@ export 'package:rive/src/generated/bones/tendon_base.dart'; class Tendon extends TendonBase { final Mat2D _bind = Mat2D(); Mat2D? _inverseBind; - SkeletalComponent _bone = SkeletalComponent.unknown; - SkeletalComponent get bone => _bone; + SkeletalComponent? _bone; + SkeletalComponent? get bone => _bone; Mat2D get inverseBind { if (_inverseBind == null) { _inverseBind = Mat2D(); @@ -21,7 +21,7 @@ class Tendon extends TendonBase { @override void onAddedDirty() { super.onAddedDirty(); - _bone = context.resolveWithDefault(boneId, SkeletalComponent.unknown); + _bone = context.resolve(boneId); _bind[0] = xx; _bind[1] = xy; _bind[2] = yx; diff --git a/lib/src/rive_core/component.dart b/lib/src/rive_core/component.dart index e9b6170..abe65ef 100644 --- a/lib/src/rive_core/component.dart +++ b/lib/src/rive_core/component.dart @@ -135,7 +135,9 @@ abstract class Component extends ComponentBase void onAdded() {} @override void onAddedDirty() { - parent = context.resolve(parentId); + if (parentId != Core.missingId) { + parent = context.resolve(parentId); + } } @override diff --git a/lib/src/rive_core/runtime/runtime_header.dart b/lib/src/rive_core/runtime/runtime_header.dart index 0eefc8b..b5c6565 100644 --- a/lib/src/rive_core/runtime/runtime_header.dart +++ b/lib/src/rive_core/runtime/runtime_header.dart @@ -36,6 +36,9 @@ class RuntimeHeader { throw RiveUnsupportedVersionException(riveVersion.major, riveVersion.minor, readMajorVersion, readMinorVersion); } + if (readMajorVersion == 6) { + reader.readVarUint(); + } int fileId = reader.readVarUint(); var propertyFields = HashMap(); var propertyKeys = []; diff --git a/lib/src/rive_core/shapes/paint/linear_gradient.dart b/lib/src/rive_core/shapes/paint/linear_gradient.dart index c9d73a2..28535de 100644 --- a/lib/src/rive_core/shapes/paint/linear_gradient.dart +++ b/lib/src/rive_core/shapes/paint/linear_gradient.dart @@ -105,6 +105,12 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator { addDirt(ComponentDirt.transform); } + @override + void onAdded() { + super.onAdded(); + syncColor(); + } + @override void opacityChanged(double from, double to) { syncColor(); @@ -118,5 +124,8 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator { } @override - bool validate() => super.validate() && shapePaintContainer != null; + bool validate() { + print("${super.validate()} $shapePaintContainer"); + return super.validate() && shapePaintContainer != null; + } } diff --git a/lib/src/rive_core/shapes/paint/shape_paint.dart b/lib/src/rive_core/shapes/paint/shape_paint.dart index 9524930..c5b0ea4 100644 --- a/lib/src/rive_core/shapes/paint/shape_paint.dart +++ b/lib/src/rive_core/shapes/paint/shape_paint.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:meta/meta.dart'; import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; +import 'package:rive/src/rive_core/container_component.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/generated/shapes/paint/shape_paint_base.dart'; @@ -12,7 +13,7 @@ abstract class ShapePaint extends ShapePaintBase { Paint get paint => _paint; ShapePaintMutator? _paintMutator; ShapePaintContainer? get shapePaintContainer => - parent as ShapePaintContainer?; + parent is ShapePaintContainer ? parent as ShapePaintContainer : null; ShapePaint() { _paint = makePaint(); } @@ -33,6 +34,16 @@ abstract class ShapePaint extends ShapePaintBase { super.childAdded(child); if (child is ShapePaintMutator) { _changeMutator(child as ShapePaintMutator); + if (shapePaintContainer != null) { + _initMutator(); + } + } + } + + @override + void parentChanged(ContainerComponent? from, ContainerComponent? to) { + super.parentChanged(from, to); + if (shapePaintContainer != null) { _initMutator(); } } diff --git a/lib/src/rive_core/shapes/path_composer.dart b/lib/src/rive_core/shapes/path_composer.dart index c7ea7cb..59e31c5 100644 --- a/lib/src/rive_core/shapes/path_composer.dart +++ b/lib/src/rive_core/shapes/path_composer.dart @@ -1,39 +1,28 @@ import 'dart:ui' as ui; +import 'package:rive/src/rive_core/artboard.dart'; import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/generated/shapes/path_composer_base.dart'; -class PathComposer extends PathComposerBase { - static final PathComposer unknown = PathComposer(); - Shape? _shape; - Shape? get shape => _shape; +class PathComposer extends Component { + final Shape shape; + PathComposer(this.shape); + @override + Artboard? get artboard => shape.artboard; final ui.Path worldPath = ui.Path(); final ui.Path localPath = ui.Path(); ui.Path _fillPath = ui.Path(); ui.Path get fillPath => _fillPath; - void _changeShape(Shape? value) { - if (value == _shape) { - return; - } - if (_shape != null && _shape!.pathComposer == this) { - _shape!.pathComposer = PathComposer.unknown; - } - value?.pathComposer = this; - _shape = value; - } - void _recomputePath() { - assert(_shape != null); - var buildLocalPath = _shape!.wantLocalPath; - var buildWorldPath = _shape!.wantWorldPath || !buildLocalPath; + var buildLocalPath = shape.wantLocalPath; + var buildWorldPath = shape.wantWorldPath || !buildLocalPath; if (buildLocalPath) { localPath.reset(); - var world = _shape!.worldTransform; + var world = shape.worldTransform; Mat2D inverseWorld = Mat2D(); if (Mat2D.invert(inverseWorld, world)) { - for (final path in _shape!.paths) { + for (final path in shape.paths) { if (path.isHidden) { continue; } @@ -46,7 +35,7 @@ class PathComposer extends PathComposerBase { } if (buildWorldPath) { worldPath.reset(); - for (final path in _shape!.paths) { + for (final path in shape.paths) { if (path.isHidden) { continue; } @@ -54,15 +43,14 @@ class PathComposer extends PathComposerBase { matrix4: path.pathTransform.mat4); } } - _fillPath = _shape!.fillInWorld ? worldPath : localPath; + _fillPath = shape.fillInWorld ? worldPath : localPath; } @override void buildDependencies() { - assert(_shape != null); super.buildDependencies(); - _shape!.addDependent(this); - for (final path in _shape!.paths) { + shape.addDependent(this); + for (final path in shape.paths) { path.addDependent(this); } } @@ -73,18 +61,4 @@ class PathComposer extends PathComposerBase { _recomputePath(); } } - - @override - bool resolveArtboard() { - _changeShape(null); - return super.resolveArtboard(); - } - - @override - void visitAncestor(Component ancestor) { - super.visitAncestor(ancestor); - if (_shape == null && ancestor is Shape) { - _changeShape(ancestor); - } - } } diff --git a/lib/src/rive_core/shapes/shape.dart b/lib/src/rive_core/shapes/shape.dart index e92a5af..f1c9231 100644 --- a/lib/src/rive_core/shapes/shape.dart +++ b/lib/src/rive_core/shapes/shape.dart @@ -18,24 +18,18 @@ class Shape extends ShapeBase with ShapePaintContainer { bool get wantLocalPath => _wantLocalPath; bool _fillInWorld = false; bool get fillInWorld => _fillInWorld; - PathComposer _pathComposer = PathComposer.unknown; - PathComposer get pathComposer => _pathComposer; - set pathComposer(PathComposer value) { - if (_pathComposer == value) { - return; - } - _pathComposer = value; - paintChanged(); + late PathComposer pathComposer; + Shape() { + pathComposer = PathComposer(this); } - - ui.Path get fillPath => _pathComposer.fillPath; + ui.Path get fillPath => pathComposer.fillPath; bool addPath(Path path) { paintChanged(); return paths.add(path); } void _markComposerDirty() { - _pathComposer.addDirt(ComponentDirt.path, recurse: true); + pathComposer.addDirt(ComponentDirt.path, recurse: true); invalidateStrokeEffects(); } @@ -123,9 +117,8 @@ class Shape extends ShapeBase with ShapePaintContainer { void blendModeValueChanged(int from, int to) => _markBlendModeDirty(); @override void draw(ui.Canvas canvas) { - assert(_pathComposer != PathComposer.unknown); bool clipped = clip(canvas); - var path = _pathComposer.fillPath; + var path = pathComposer.fillPath; if (!_fillInWorld) { canvas.save(); canvas.transform(worldTransform.mat4); @@ -139,8 +132,8 @@ class Shape extends ShapeBase with ShapePaintContainer { for (final stroke in strokes) { var transformAffectsStroke = stroke.transformAffectsStroke; var path = transformAffectsStroke - ? _pathComposer.localPath - : _pathComposer.worldPath; + ? pathComposer.localPath + : pathComposer.worldPath; if (transformAffectsStroke) { canvas.save(); canvas.transform(worldTransform.mat4); @@ -166,4 +159,9 @@ class Shape extends ShapeBase with ShapePaintContainer { void onStrokesChanged() => paintChanged(); @override void onFillsChanged() => paintChanged(); + @override + void buildDependencies() { + super.buildDependencies(); + pathComposer.buildDependencies(); + } } diff --git a/lib/src/rive_core/state_machine_controller.dart b/lib/src/rive_core/state_machine_controller.dart index b32d2bb..16d7c5c 100644 --- a/lib/src/rive_core/state_machine_controller.dart +++ b/lib/src/rive_core/state_machine_controller.dart @@ -10,7 +10,7 @@ import 'package:rive/src/rive_core/rive_animation_controller.dart'; class LayerController { final StateMachineLayer layer; - LayerState _currentState = LayerState.unknown; + LayerState? _currentState; LinearAnimationInstance? _animationInstanceFrom; StateTransition? _transition; double _mix = 1.0; @@ -18,7 +18,7 @@ class LayerController { LayerController(this.layer) { _changeState(layer.entryState); } - bool _changeState(LayerState state) { + bool _changeState(LayerState? state) { if (state == _currentState) { return false; } @@ -27,7 +27,7 @@ class LayerController { } void dispose() { - _changeState(LayerState.unknown); + _changeState(null); } bool apply(CoreContext core, double elapsedSeconds, @@ -71,7 +71,11 @@ class LayerController { return tryChangeState(_currentState, inputValues); } - bool tryChangeState(LayerState stateFrom, HashMap inputValues) { + bool tryChangeState( + LayerState? stateFrom, HashMap inputValues) { + if (stateFrom == null) { + return false; + } for (final transition in stateFrom.transitions) { bool valid = true; for (final condition in transition.conditions) { diff --git a/lib/src/rive_file.dart b/lib/src/rive_file.dart index 6eb2a89..3018e32 100644 --- a/lib/src/rive_file.dart +++ b/lib/src/rive_file.dart @@ -102,6 +102,13 @@ class RiveFile { while (!reader.isEOF) { final object = _readRuntimeObject(reader, propertyToField); if (object == null) { + // See if there's an artboard on the stack, need to track the null + // object as it'll still hold an id. + var artboardImporter = + importStack.latest(ArtboardBase.typeKey); + if (artboardImporter != null) { + artboardImporter.addComponent(null); + } continue; } @@ -191,8 +198,8 @@ class RiveFile { for (final artboard in _artboards) { var runtimeArtboard = artboard as RuntimeArtboard; - for (final object in runtimeArtboard.objects) { - if (object != null && object.validate()) { + for (final object in runtimeArtboard.objects.whereNotNull()) { + if (object.validate()) { InternalCoreHelper.markValid(object); } else { throw RiveFormatErrorException( diff --git a/lib/src/runtime_artboard.dart b/lib/src/runtime_artboard.dart index 5acfda0..969d5ce 100644 --- a/lib/src/runtime_artboard.dart +++ b/lib/src/runtime_artboard.dart @@ -19,9 +19,9 @@ class RuntimeArtboard extends Artboard implements CoreContext { final Set _needDependenciesBuilt = {}; @override - T addObject(T object) { - object.context = this; - object.id = _objects.length; + T? addObject(T? object) { + object?.context = this; + object?.id = _objects.length; _objects.add(object); return object;