add onLoad/onUnload streams
This commit is contained in:
@@ -27,6 +27,17 @@ class TextureDetails {
|
||||
}
|
||||
|
||||
abstract class FilamentController {
|
||||
///
|
||||
/// A Stream containing every FilamentEntity 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 FilamentEntity returned from those methods.
|
||||
///
|
||||
Stream<FilamentEntity> get onLoad;
|
||||
|
||||
///
|
||||
/// A Stream containing every FilamentEntity removed from the scene (i.e. via [removeAsset], [clearAssets], [removeLight] or [clearLights]).
|
||||
|
||||
Stream<FilamentEntity> get onUnload;
|
||||
|
||||
///
|
||||
/// A [ValueNotifier] that holds the current dimensions (in physical pixels, after multiplying by pixel ratio) of the FilamentWidget.
|
||||
/// If you need to perform work as early as possible, add a listener to this property before a [FilamentWidget] has been inserted into the widget hierarchy.
|
||||
@@ -201,7 +212,8 @@ abstract class FilamentController {
|
||||
/// [relativeResourcePath] is the folder path where the glTF resources are stored;
|
||||
/// this is usually the parent directory of the .gltf file itself.
|
||||
///
|
||||
Future<FilamentEntity> loadGltf(String path, String relativeResourcePath);
|
||||
Future<FilamentEntity> loadGltf(String path, String relativeResourcePath,
|
||||
{bool force = false});
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
|
||||
@@ -20,7 +20,14 @@ const FilamentEntity _FILAMENT_ASSET_ERROR = 0;
|
||||
class FilamentControllerFFI extends FilamentController {
|
||||
final _channel = const MethodChannel("app.polyvox.filament/event");
|
||||
|
||||
///
|
||||
/// This will be set on constructor invocation.
|
||||
/// On Windows, this will be set to the value returned by the [usesBackingWindow] method call.
|
||||
/// On Web, this will always be true;
|
||||
/// On other platforms, this will always be false.
|
||||
///
|
||||
bool _usesBackingWindow = false;
|
||||
|
||||
@override
|
||||
bool get requiresTextureWidget => !_usesBackingWindow;
|
||||
|
||||
@@ -49,6 +56,15 @@ class FilamentControllerFFI extends FilamentController {
|
||||
|
||||
Timer? _resizeTimer;
|
||||
|
||||
final _lights = <FilamentEntity>{};
|
||||
final _entities = <FilamentEntity>{};
|
||||
|
||||
final _onLoadController = StreamController<FilamentEntity>.broadcast();
|
||||
Stream<FilamentEntity> get onLoad => _onLoadController.stream;
|
||||
|
||||
final _onUnloadController = StreamController<FilamentEntity>.broadcast();
|
||||
Stream<FilamentEntity> get onUnload => _onUnloadController.stream;
|
||||
|
||||
///
|
||||
/// This controller uses platform channels to bridge Dart with the C/C++ code for the Filament API.
|
||||
/// Setting up the context/texture (since this is platform-specific) and the render ticker are platform-specific; all other methods are passed through by the platform channel to the methods specified in FlutterFilamentApi.h.
|
||||
@@ -450,15 +466,19 @@ class FilamentControllerFFI extends FilamentController {
|
||||
}
|
||||
var entity = add_light_ffi(_viewer!, type, colour, intensity, posX, posY,
|
||||
posZ, dirX, dirY, dirZ, castShadows);
|
||||
_onLoadController.sink.add(entity);
|
||||
_lights.add(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@override
|
||||
Future removeLight(FilamentEntity light) async {
|
||||
Future removeLight(FilamentEntity entity) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
remove_light_ffi(_viewer!, light);
|
||||
_lights.remove(entity);
|
||||
remove_light_ffi(_viewer!, entity);
|
||||
_onUnloadController.add(entity);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -467,6 +487,10 @@ class FilamentControllerFFI extends FilamentController {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
clear_lights_ffi(_viewer!);
|
||||
for (final entity in _lights) {
|
||||
_onUnloadController.add(entity);
|
||||
}
|
||||
_lights.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -477,12 +501,14 @@ class FilamentControllerFFI extends FilamentController {
|
||||
if (unlit) {
|
||||
throw Exception("Not yet implemented");
|
||||
}
|
||||
var asset =
|
||||
var entity =
|
||||
load_glb_ffi(_assetManager!, path.toNativeUtf8().cast<Char>(), unlit);
|
||||
if (asset == _FILAMENT_ASSET_ERROR) {
|
||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("An error occurred loading the asset at $path");
|
||||
}
|
||||
return asset;
|
||||
_entities.add(entity);
|
||||
_onLoadController.sink.add(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -495,12 +521,14 @@ class FilamentControllerFFI extends FilamentController {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
var asset = load_gltf_ffi(_assetManager!, path.toNativeUtf8().cast<Char>(),
|
||||
var entity = load_gltf_ffi(_assetManager!, path.toNativeUtf8().cast<Char>(),
|
||||
relativeResourcePath.toNativeUtf8().cast<Char>());
|
||||
if (asset == _FILAMENT_ASSET_ERROR) {
|
||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("An error occurred loading the asset at $path");
|
||||
}
|
||||
return asset;
|
||||
_entities.add(entity);
|
||||
_onLoadController.sink.add(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -700,7 +728,9 @@ class FilamentControllerFFI extends FilamentController {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
_entities.remove(entity);
|
||||
remove_asset_ffi(_viewer!, entity);
|
||||
_onUnloadController.add(entity);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -709,6 +739,11 @@ class FilamentControllerFFI extends FilamentController {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
clear_assets_ffi(_viewer!);
|
||||
|
||||
for (final entity in _entities) {
|
||||
_onUnloadController.add(entity);
|
||||
}
|
||||
_entities.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user