Video optimizations (#18)

* use events for `VideoTrackRenderer`

* logger

* implemented visibility detection

* optimize code with 1 param debounce func

* stop pending visibility event when disposed

* clean up

* mark internal

* report to track

* call dispose on pub and track

* use internal events to receive visibility events

* clean up visibility for disposed track

* listen to track visibility events on pub

* re-design

* quickly re-enable

* clean up

* clean up
This commit is contained in:
Hiroshi Horie
2021-10-25 18:34:02 +09:00
committed by GitHub
parent bf1322642b
commit 16910cae25
18 changed files with 314 additions and 95 deletions
+20 -9
View File
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:synchronized/synchronized.dart' as sync;
import 'package:meta/meta.dart';
import '../exceptions.dart';
import '../extensions.dart';
@@ -30,9 +31,13 @@ class EventsEmitter<T> extends EventsListenable<T> {
@override
EventsEmitter<T> get emitter => this;
@internal
void emit(T event) {
// do nothing if already closed
if (streamCtrl.isClosed) return;
if (streamCtrl.isClosed) {
logger.warning('failed to emit event ${event} on a disposed emitter');
return;
}
// emit the event
streamCtrl.add(event);
}
@@ -56,25 +61,31 @@ abstract class EventsListenable<T> extends Disposable {
// the emitter to listen to
EventsEmitter<T> get emitter;
bool synchronized;
final bool synchronized;
// keep track of listeners to cancel later
final _listeners = <StreamSubscription<T>>[];
final _syncLock = sync.Lock();
List<StreamSubscription<T>> get listeners => _listeners;
EventsListenable({
required this.synchronized,
}) {
onDispose(() async {
if (_listeners.isNotEmpty) {
// Stop listening to all events
logger.fine('${objectId} cancelling ${_listeners.length} listeners(s)');
for (final listener in _listeners) {
await listener.cancel();
}
}
await cancelAll();
});
}
Future<void> cancelAll() async {
if (_listeners.isNotEmpty) {
// Stop listening to all events
logger.fine('${objectId} cancelling ${_listeners.length} listeners(s)');
for (final listener in _listeners) {
await listener.cancel();
}
}
}
// @override
// @mustCallSuper
// Future<bool> dispose() async {