Skip to content

Commit

Permalink
Making sure actor widget is disposed of properly.
Browse files Browse the repository at this point in the history
  • Loading branch information
luigi-rosso committed Apr 9, 2019
1 parent 85493fe commit 1d2146b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [1.0.3] - 2019-04-09 09:50:41

* Making sure the Nima Actor widget is disposed of properly when the leaf render widet is unmounted or the render box is detached.

## [1.0.0] - 5/5/2018

* Initial release with an example NimaActor widget that implements a LeafRenderObjectWidget that can render a Nima actor. Alignment is done based on the setup axis aligned bounding box.
29 changes: 29 additions & 0 deletions example/hop/test/hop_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.

import 'package:example/main.dart';
//import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';


void main() {
testWidgets('Start the game', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());

// Find the start text
expect(find.text('Attack'), findsOneWidget);

// // Start the game.
// expect(find.byType(FlatButton), findsNWidgets(2));
// await tester.tap(find.text('Start'));
// await tester.pumpAndSettle();

// // We made it to the game screen.
// expect(find.text('Tasks'), findsOneWidget);
});
}
72 changes: 52 additions & 20 deletions lib/nima_actor.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:nima/nima.dart';
import 'package:nima/nima/math/aabb.dart';
import 'package:nima/nima/animation/actor_animation.dart';
Expand Down Expand Up @@ -66,6 +67,11 @@ class NimaActor extends LeafRenderObjectWidget {
..isPlaying = !paused && animation != null
..clip = clip;
}

@override
void didUnmountRenderObject(covariant NimaActorRenderObject renderObject) {
renderObject.dispose();
}
}

class NimaAnimationLayer {
Expand All @@ -81,31 +87,55 @@ class NimaActorRenderObject extends RenderBox {
Alignment _alignment;
String _animationName;
double _mixSeconds = 0.2;
int _frameCallbackID;
double _lastFrameTime = 0.0;
NimaAnimationCompleted _completedCallback;
NimaController _controller;
bool _isFrameScheduled = false;

List<NimaAnimationLayer> _animationLayers = List<NimaAnimationLayer>();
bool _isPlaying;

FlutterActor _actor;
AABB _setupAABB;

void dispose() {
_isPlaying = false;
_updatePlayState();
_controller = null;
}

@override
void detach() {
super.detach();
dispose();
}

@override
void attach(PipelineOwner owner) {
super.attach(owner);
_updatePlayState();
}

void _updatePlayState() {
if (_isPlaying && attached) {
_frameCallbackID ??=
SchedulerBinding.instance.scheduleFrameCallback(_beginFrame);
} else {
if (_frameCallbackID != null) {
SchedulerBinding.instance.cancelFrameCallbackWithId(_frameCallbackID);
_frameCallbackID = null;
}
_lastFrameTime = 0.0;
}
}

NimaAnimationCompleted get completed => _completedCallback;
set completed(NimaAnimationCompleted value) {
if (_completedCallback != value) {
_completedCallback = value;
}
}

void scheduleFrame() {
if (!_isFrameScheduled) {
_isFrameScheduled = true;
SchedulerBinding.instance.scheduleFrameCallback(beginFrame);
}
}

BoxFit get fit => _fit;
set fit(BoxFit value) {
if (value == _fit) {
Expand All @@ -121,9 +151,7 @@ class NimaActorRenderObject extends RenderBox {
return;
}
_isPlaying = value;
if (_isPlaying) {
scheduleFrame();
}
_updatePlayState();
}

bool _clip = true;
Expand Down Expand Up @@ -233,19 +261,27 @@ class NimaActorRenderObject extends RenderBox {
super.performLayout();
}

void beginFrame(Duration timeStamp) {
void _beginFrame(Duration timeStamp) {
_frameCallbackID = null;
final double t =
timeStamp.inMicroseconds / Duration.microsecondsPerMillisecond / 1000.0;
_isFrameScheduled = false;
if (_lastFrameTime == 0 || _actor == null) {
if (_lastFrameTime == 0) {
_lastFrameTime = t;
scheduleFrame();
_updatePlayState();
return;
}

double elapsedSeconds = t - _lastFrameTime;
_lastFrameTime = t;

if (_advance(elapsedSeconds)) {
_updatePlayState();
}

markNeedsPaint();
}

bool _advance(double elapsedSeconds) {
int lastFullyMixed = -1;
double lastMix = 0.0;

Expand Down Expand Up @@ -295,13 +331,9 @@ class NimaActorRenderObject extends RenderBox {
_controller.advance(_actor, elapsedSeconds);
}

if (_isPlaying) {
scheduleFrame();
}

_actor.advance(elapsedSeconds);

markNeedsPaint();
return _isPlaying;
}

@override
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: nima
description: Nima runtime for flutter.
version: 1.0.2
version: 1.0.3
author: "2Dimensions Team <[email protected]>"
homepage: https://github.com/2d-inc/Nima-Flutter
environment:
Expand Down

0 comments on commit 1d2146b

Please sign in to comment.