add implementation for onDispose to ThermionViewerFFI
This commit is contained in:
@@ -1,15 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/compatibility/compatibility.dart';
|
import 'package:thermion_dart/thermion_dart/compatibility/compatibility.dart';
|
||||||
|
|
||||||
import 'package:thermion_dart/thermion_dart/entities/gizmo.dart';
|
import 'package:thermion_dart/thermion_dart/entities/gizmo.dart';
|
||||||
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
import 'thermion_viewer.dart';
|
import 'thermion_viewer.dart';
|
||||||
import 'scene.dart';
|
import 'scene.dart';
|
||||||
import 'compatibility/compatibility.dart';
|
|
||||||
|
|
||||||
// ignore: constant_identifier_names
|
// ignore: constant_identifier_names
|
||||||
const ThermionEntity _FILAMENT_ASSET_ERROR = 0;
|
const ThermionEntity _FILAMENT_ASSET_ERROR = 0;
|
||||||
@@ -19,8 +15,8 @@ typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
|||||||
class ThermionViewerFFI extends ThermionViewer {
|
class ThermionViewerFFI extends ThermionViewer {
|
||||||
final _compat = Compatibility();
|
final _compat = Compatibility();
|
||||||
|
|
||||||
late SceneImpl _scene;
|
SceneImpl? _scene;
|
||||||
Scene get scene => _scene;
|
Scene get scene => _scene!;
|
||||||
|
|
||||||
double _pixelRatio = 1.0;
|
double _pixelRatio = 1.0;
|
||||||
|
|
||||||
@@ -172,14 +168,39 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
set_frame_interval_ffi(_viewer!, interval);
|
set_frame_interval_ffi(_viewer!, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _onDispose = <Future Function()>[];
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future dispose() async {
|
Future dispose() async {
|
||||||
|
if (_viewer == null) {
|
||||||
|
// we've already cleaned everything up, ignore the call to dispose
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await setRendering(false);
|
||||||
|
await clearEntities();
|
||||||
|
await clearLights();
|
||||||
|
await _scene!.dispose();
|
||||||
|
_scene = null;
|
||||||
destroy_filament_viewer_ffi(_viewer!);
|
destroy_filament_viewer_ffi(_viewer!);
|
||||||
|
|
||||||
_sceneManager = null;
|
_sceneManager = null;
|
||||||
_viewer = null;
|
_viewer = null;
|
||||||
|
await _pickResultController.close();
|
||||||
|
|
||||||
|
for (final callback in _onDispose) {
|
||||||
|
await callback.call();
|
||||||
|
}
|
||||||
|
_onDispose.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
void onDispose(Future Function() callback) {
|
||||||
|
_onDispose.add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -317,7 +338,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
throw Exception("Failed to add light to scene");
|
throw Exception("Failed to add light to scene");
|
||||||
}
|
}
|
||||||
|
|
||||||
_scene.registerLight(entity);
|
_scene!.registerLight(entity);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +347,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future removeLight(ThermionEntity entity) async {
|
Future removeLight(ThermionEntity entity) async {
|
||||||
_scene.unregisterLight(entity);
|
_scene!.unregisterLight(entity);
|
||||||
remove_light_ffi(_viewer!, entity);
|
remove_light_ffi(_viewer!, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +358,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future clearLights() async {
|
Future clearLights() async {
|
||||||
clear_lights_ffi(_viewer!);
|
clear_lights_ffi(_viewer!);
|
||||||
|
|
||||||
_scene.clearLights();
|
_scene!.clearLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -393,7 +414,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("An error occurred loading the asset at $path");
|
throw Exception("An error occurred loading the asset at $path");
|
||||||
}
|
}
|
||||||
_scene.registerEntity(entity);
|
_scene!.registerEntity(entity);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
@@ -404,11 +425,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
@override
|
@override
|
||||||
Future<ThermionEntity> loadGltf(String path, String relativeResourcePath,
|
Future<ThermionEntity> loadGltf(String path, String relativeResourcePath,
|
||||||
{bool force = false}) async {
|
{bool force = false}) async {
|
||||||
// if (Platform.isWindows && !force) {
|
|
||||||
// throw Exception(
|
|
||||||
// "loadGltf has a race condition on Windows which is likely to crash your program. If you really want to try, pass force=true to loadGltf");
|
|
||||||
// }
|
|
||||||
|
|
||||||
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||||
final relativeResourcePathPtr =
|
final relativeResourcePathPtr =
|
||||||
relativeResourcePath.toNativeUtf8(allocator: allocator).cast<Char>();
|
relativeResourcePath.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||||
@@ -419,7 +435,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("An error occurred loading the asset at $path");
|
throw Exception("An error occurred loading the asset at $path");
|
||||||
}
|
}
|
||||||
_scene.registerEntity(entity);
|
_scene!.registerEntity(entity);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
@@ -676,8 +692,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future addBoneAnimation(ThermionEntity entity, BoneAnimationData animation,
|
Future addBoneAnimation(ThermionEntity entity, BoneAnimationData animation,
|
||||||
{int skinIndex = 0,
|
{int skinIndex = 0,
|
||||||
double fadeOutInSecs = 0.0,
|
double fadeOutInSecs = 0.0,
|
||||||
double fadeInInSecs = 0.0,
|
double fadeInInSecs = 0.0,
|
||||||
double maxDelta=1.0}) async {
|
double maxDelta = 1.0}) async {
|
||||||
if (animation.space != Space.Bone &&
|
if (animation.space != Space.Bone &&
|
||||||
animation.space != Space.ParentWorldRotation) {
|
animation.space != Space.ParentWorldRotation) {
|
||||||
throw UnimplementedError("TODO - support ${animation.space}");
|
throw UnimplementedError("TODO - support ${animation.space}");
|
||||||
@@ -720,7 +736,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
var world = Matrix4.identity();
|
var world = Matrix4.identity();
|
||||||
// this odd use of ! is intentional, without it, the WASM optimizer gets in trouble
|
// this odd use of ! is intentional, without it, the WASM optimizer gets in trouble
|
||||||
var parentBoneEntity = (await getParent(boneEntity))!;
|
var parentBoneEntity = (await getParent(boneEntity))!;
|
||||||
while(true) {
|
while (true) {
|
||||||
if (!bones.contains(parentBoneEntity!)) {
|
if (!bones.contains(parentBoneEntity!)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -758,7 +774,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
numFrames,
|
numFrames,
|
||||||
animation.frameLengthInMs,
|
animation.frameLengthInMs,
|
||||||
fadeOutInSecs,
|
fadeOutInSecs,
|
||||||
fadeInInSecs,
|
fadeInInSecs,
|
||||||
maxDelta);
|
maxDelta);
|
||||||
}
|
}
|
||||||
allocator.free(data);
|
allocator.free(data);
|
||||||
@@ -894,7 +910,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future removeEntity(ThermionEntity entity) async {
|
Future removeEntity(ThermionEntity entity) async {
|
||||||
_scene.unregisterEntity(entity);
|
_scene!.unregisterEntity(entity);
|
||||||
|
|
||||||
await withVoidCallback(
|
await withVoidCallback(
|
||||||
(callback) => remove_entity_ffi(_viewer!, entity, callback));
|
(callback) => remove_entity_ffi(_viewer!, entity, callback));
|
||||||
@@ -911,7 +927,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
await withVoidCallback((callback) {
|
await withVoidCallback((callback) {
|
||||||
clear_entities_ffi(_viewer!, callback);
|
clear_entities_ffi(_viewer!, callback);
|
||||||
});
|
});
|
||||||
_scene.clearEntities();
|
_scene!.clearEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -1296,7 +1312,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
x: (x / _pixelRatio).toDouble(),
|
x: (x / _pixelRatio).toDouble(),
|
||||||
y: (viewportDimensions.$2 - y) / _pixelRatio
|
y: (viewportDimensions.$2 - y) / _pixelRatio
|
||||||
));
|
));
|
||||||
_scene.registerSelected(entityId);
|
_scene!.registerSelected(entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
late NativeCallable<Void Function(Int32 entityId, Int x, Int y)>
|
late NativeCallable<Void Function(Int32 entityId, Int x, Int y)>
|
||||||
@@ -1307,7 +1323,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
void pick(int x, int y) async {
|
void pick(int x, int y) async {
|
||||||
_scene.unregisterSelected();
|
_scene!.unregisterSelected();
|
||||||
|
|
||||||
filament_pick(
|
filament_pick(
|
||||||
_viewer!,
|
_viewer!,
|
||||||
@@ -1624,7 +1640,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
throw Exception("Failed to create geometry");
|
throw Exception("Failed to create geometry");
|
||||||
}
|
}
|
||||||
|
|
||||||
_scene.registerEntity(entity);
|
_scene!.registerEntity(entity);
|
||||||
|
|
||||||
allocator.free(materialPathPtr);
|
allocator.free(materialPathPtr);
|
||||||
allocator.free(vertexPtr);
|
allocator.free(vertexPtr);
|
||||||
|
|||||||
Reference in New Issue
Block a user