diff --git a/thermion_dart/lib/thermion_dart/scene.dart b/thermion_dart/lib/thermion_dart/scene.dart index 2bb820b4..76d86d43 100644 --- a/thermion_dart/lib/thermion_dart/scene.dart +++ b/thermion_dart/lib/thermion_dart/scene.dart @@ -1,120 +1,48 @@ +import 'package:thermion_dart/thermion_dart/thermion_viewer.dart'; import 'dart:async'; -import 'thermion_viewer.dart'; - /// /// For now, this class just holds the entities that have been loaded (though not necessarily visible in the Filament Scene). /// -class SceneImpl extends Scene { - - ThermionViewer controller; - - SceneImpl(this.controller); - - @override +abstract class Scene { + /// + /// The last entity clicked/tapped in the viewport (internally, the result of calling pick); ThermionEntity? selected; - final _onUpdatedController = StreamController.broadcast(); - @override - Stream get onUpdated => _onUpdatedController.stream; - - final _onLoadController = StreamController.broadcast(); - @override - Stream get onLoad => _onLoadController.stream; - - final _onUnloadController = StreamController.broadcast(); - @override - Stream get onUnload => _onUnloadController.stream; - - final _lights = {}; - final _entities = {}; - - void registerLight(ThermionEntity entity) { - _lights.add(entity); - _onLoadController.sink.add(entity); - _onUpdatedController.add(true); - } - - void unregisterLight(ThermionEntity entity) async { - var children = await controller.getChildEntities(entity, true); - if (selected == entity || children.contains(selected)) { - selected = null; - controller.gizmo?.detach(); - } - _lights.remove(entity); - _onUnloadController.add(entity); - _onUpdatedController.add(true); - } - - void unregisterEntity(ThermionEntity entity) async { - var children = await controller.getChildEntities(entity, true); - if (selected == entity || children.contains(selected)) { - selected = null; - - controller.gizmo?.detach(); - } - _entities.remove(entity); - _onUnloadController.add(entity); - _onUpdatedController.add(true); - } - - void registerEntity(ThermionEntity entity) { - _entities.add(entity); - _onLoadController.sink.add(entity); - _onUpdatedController.add(true); - } - - void clearLights() { - for (final light in _lights) { - if (selected == light) { - selected = null; - controller.gizmo?.detach(); - } - _onUnloadController.add(light); - } - - _lights.clear(); - _onUpdatedController.add(true); - } - - void clearEntities() { - for (final entity in _entities) { - if (selected == entity) { - selected = null; - controller.gizmo?.detach(); - } - _onUnloadController.add(entity); - } - _entities.clear(); - _onUpdatedController.add(true); - } + /// + /// A Stream updated whenever an entity is added/removed from the scene. + /// + Stream get onUpdated; /// - /// Lists all entities currently loaded (not necessarily active in the scene). + /// A Stream containing every ThermionEntity added to the scene (i.e. via [loadGlb], [loadGltf] or [addLight]). + /// This is provided for convenience so you can set listeners in front-end widgets that can respond to entity loads without manually passing around the ThermionEntity returned from those methods. /// - Iterable listLights() { - return _lights; - } + Stream get onLoad; - @override - Iterable listEntities() { - return _entities; - } + /// + /// A Stream containing every ThermionEntity removed from the scene (i.e. via [removeEntity], [clearEntities], [removeLight] or [clearLights]). - void registerSelected(ThermionEntity entity) { - selected = entity; - _onUpdatedController.add(true); - } + Stream get onUnload; - void unregisterSelected() { - selected = null; - _onUpdatedController.add(true); - } + /// + /// Lists all light entities currently loaded (not necessarily active in the scene). Does not account for instances. + /// + Iterable listLights(); - @override - void select(ThermionEntity entity) { - selected = entity; - controller.gizmo?.attach(entity); - _onUpdatedController.add(true); - } -} + /// + /// Lists all entities currently loaded (not necessarily active in the scene). Does not account for instances. + /// + Iterable listEntities(); + + /// + /// Attach the gizmo to the specified entity. + /// + void select(ThermionEntity entity); + + /// + /// + /// + void registerEntity(ThermionEntity entity); + +} \ No newline at end of file diff --git a/thermion_dart/lib/thermion_dart/scene_impl.dart b/thermion_dart/lib/thermion_dart/scene_impl.dart new file mode 100644 index 00000000..a31c8848 --- /dev/null +++ b/thermion_dart/lib/thermion_dart/scene_impl.dart @@ -0,0 +1,125 @@ +import 'dart:async'; +import 'package:thermion_dart/thermion_dart/scene.dart'; +import 'thermion_viewer.dart'; + +/// +/// For now, this class just holds the entities that have been loaded (though not necessarily visible in the Filament Scene). +/// +class SceneImpl extends Scene { + ThermionViewer controller; + + SceneImpl(this.controller); + + @override + ThermionEntity? selected; + + final _onUpdatedController = StreamController.broadcast(); + @override + Stream get onUpdated => _onUpdatedController.stream; + + final _onLoadController = StreamController.broadcast(); + @override + Stream get onLoad => _onLoadController.stream; + + final _onUnloadController = StreamController.broadcast(); + @override + Stream get onUnload => _onUnloadController.stream; + + final _lights = {}; + final _entities = {}; + + void registerLight(ThermionEntity entity) { + _lights.add(entity); + _onLoadController.sink.add(entity); + _onUpdatedController.add(true); + } + + void unregisterLight(ThermionEntity entity) async { + var children = await controller.getChildEntities(entity, true); + if (selected == entity || children.contains(selected)) { + selected = null; + controller.gizmo?.detach(); + } + _lights.remove(entity); + _onUnloadController.add(entity); + _onUpdatedController.add(true); + } + + void unregisterEntity(ThermionEntity entity) async { + var children = await controller.getChildEntities(entity, true); + if (selected == entity || children.contains(selected)) { + selected = null; + + controller.gizmo?.detach(); + } + _entities.remove(entity); + _onUnloadController.add(entity); + _onUpdatedController.add(true); + } + + void registerEntity(ThermionEntity entity) { + _entities.add(entity); + _onLoadController.sink.add(entity); + _onUpdatedController.add(true); + } + + void clearLights() { + for (final light in _lights) { + if (selected == light) { + selected = null; + controller.gizmo?.detach(); + } + _onUnloadController.add(light); + } + + _lights.clear(); + _onUpdatedController.add(true); + } + + void clearEntities() { + for (final entity in _entities) { + if (selected == entity) { + selected = null; + controller.gizmo?.detach(); + } + _onUnloadController.add(entity); + } + _entities.clear(); + _onUpdatedController.add(true); + } + + /// + /// Lists all entities currently loaded (not necessarily active in the scene). + /// + Iterable listLights() { + return _lights; + } + + @override + Iterable listEntities() { + return _entities; + } + + void registerSelected(ThermionEntity entity) { + selected = entity; + _onUpdatedController.add(true); + } + + void unregisterSelected() { + selected = null; + _onUpdatedController.add(true); + } + + @override + void select(ThermionEntity entity) { + selected = entity; + controller.gizmo?.attach(entity); + _onUpdatedController.add(true); + } + + Future dispose() async { + await _onLoadController.close(); + await _onUnloadController.close(); + await _onUpdatedController.close(); + } +} diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer.dart b/thermion_dart/lib/thermion_dart/thermion_viewer.dart index 22fe9eb8..73f458ec 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:thermion_dart/thermion_dart/scene.dart'; import 'package:vector_math/vector_math_64.dart'; import 'dart:async'; import 'package:animation_tools_dart/animation_tools_dart.dart'; @@ -707,52 +708,6 @@ abstract class ThermionViewer { void onDispose(Future Function() callback); } -/// -/// For now, this class just holds the entities that have been loaded (though not necessarily visible in the Filament Scene). -/// -abstract class Scene { - /// - /// The last entity clicked/tapped in the viewport (internally, the result of calling pick); - ThermionEntity? selected; - - /// - /// A Stream updated whenever an entity is added/removed from the scene. - /// - Stream get onUpdated; - - /// - /// A Stream containing every ThermionEntity added to the scene (i.e. via [loadGlb], [loadGltf] or [addLight]). - /// This is provided for convenience so you can set listeners in front-end widgets that can respond to entity loads without manually passing around the ThermionEntity returned from those methods. - /// - Stream get onLoad; - - /// - /// A Stream containing every ThermionEntity removed from the scene (i.e. via [removeEntity], [clearEntities], [removeLight] or [clearLights]). - - Stream get onUnload; - - /// - /// Lists all light entities currently loaded (not necessarily active in the scene). Does not account for instances. - /// - Iterable listLights(); - - /// - /// Lists all entities currently loaded (not necessarily active in the scene). Does not account for instances. - /// - Iterable listEntities(); - - /// - /// Attach the gizmo to the specified entity. - /// - void select(ThermionEntity entity); - - /// - /// - /// - void registerEntity(ThermionEntity entity); - -} - abstract class AbstractGizmo { bool get isActive; diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart index 0d9daf48..7dc0018f 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart @@ -3,9 +3,10 @@ import 'dart:math'; import 'package:animation_tools_dart/animation_tools_dart.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/scene.dart'; import 'package:vector_math/vector_math_64.dart'; import 'thermion_viewer.dart'; -import 'scene.dart'; +import 'scene_impl.dart'; import 'package:logging/logging.dart'; // ignore: constant_identifier_names