Closed erf closed 3 years ago
I'm not sure about the automatic closing of streams when awaiting the first event. If it always work, what you do is fine.
If it doesn't always work. I would subscribe to the stream in the load method and use a completer to wait from the first value.
I'm not in front of a computer right now so I can't paste a snippet of code to show you. But if it's not clear I can do it later.
In any case don't forget to cancel the subscription in the dispose method of the logic.
Thanks. I'd like to see a Completer example.
For the completer, something like that should work (not tested though):
class MyLogic with Logic, Loadable {
MyLogic(this.scope);
@override
final Scope scope;
final Completer<int> _completer = Completer();
@override
Future<void> load() {
stream.listen((event) {
write(stateRef, event);
if (!_completer.isCompleted) {
_completer.complete(event);
}
});
return _completer.future;
}
}
That seem to work!
I made this LoadCompleter mixin to make it easier to use with Logic. What do you think?
( it would only expect one type to complete but..)
mixin LoadCompleter<T> {
Completer<T> completer = Completer();
void complete(T event) {
if (!completer.isCompleted) {
completer.complete(event);
}
}
}
class MyLogic with Logic, LoadCompleter implements Loadable {
MyLogic(this.scope);
@override
final Scope scope;
@override
Future<void> load() {
stream.listen((event) {
write(stateRef, event);
complete(event);
});
return completer.future;
}
}
Or you could do:
mixin LoadCompleter<T> implements Loadable {
Completer<T> completer = Completer();
void complete(T event) {
if (!completer.isCompleted) {
completer.complete(event);
}
}
Future<void> load() {
return completer.future;
}
}
class MyLogic with Logic, LoadCompleter {
MyLogic(this.scope);
@override
final Scope scope;
@override
Future<void> load() {
stream.listen((event) {
write(stateRef, event);
complete(event);
});
return super.load();
}
}
Could call it LogicCompleter..
But maybe this is too spesific to make generic..
I think its maybe better to just make an extension on Completer to check if isCompleted
..
BTW are you allowed to use the with
keyword to implement interfaces/abstract classes in dart instead of implements
? It seem to work and but i could not find documentation on this.
Yes you can. I don't see the advantage to mix in an interface, but with an abstract class, it can be useful because your object can extend another type, and mix in the abstract class to add default behavior.
I have several Logic classes which subscribes to one ore more steams. I use Loadable so i can use them with LogicLoader, but i would like to get the first stream event before returning (so that values are not always null at first) and also subscribing to new events. How would you do this? I read that if i first listen to stream.first then non-broadcast streams are closed it says, however the following seem to work (although a bit awkward):