How can I require calling dispose method? - flutter

I'm trying to require (or at least warn in the linter) that when I create an object I also define when it should be disposed, if necessary. An example of this is the warning for Sink: Close instances of dart.core.Sink, which appears in VS Code if you create a Sink without ever calling .close(). The issue is that I have classes that define multiple Sink objects, so I close all of them in a dispose method for the class, which solves the dart.core.Sink warning but doesn't solve the underlying issue, because this method might never be called.
Is there any way to create a similar error/warning for my own classes? I've looked at adding new rules to the linter, but this seems like a lot of work, and before I go that far, I was wondering if there's any mixin or similar that would give me this functionality.

Your can use mustCallSuper attribute like this:
import 'package:meta/meta.dart';
#mustCallSuper
void dispose() {
// ...
}

Related

Why are all the methods in BlocObserver empty?

Looking through the class that defines BlocObserver, all the methods do not have any functionality defined. The BlocObserver does not inherit anything from any other class. It is only connected to the Bloc class by being created during instantiation of a Bloc.
How do the methods in BlocObserver have functionality when they are empty inside BlocObserver?
Read through the BlocObserver definition, and read through the Bloc definition.
What to do
The way you are expected to use BlocObserver is described pretty well in Core Concepts.
Basically, as BlocObserver is an abstract class, you would extend it in your own class, providing implementations for the handler methods as appropriate for your use-case.
So, roughly:
class CustomObserver extends BlocObserver {
#override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
// Perform logic based on the change
}
}
Then, you would assign an instance of this class as the static observer on Bloc, for example:
Bloc.observer = CustomObserver();
After this point, you would expect any changes that propagate through Bloc to call your CustomObserver.onChange() method.
How this works
The pattern of providing some framework object a definition of the code you'd like to run when certain events happen is a pretty common one, so it's useful to come to grips with it. Usually (and also in this case) it's way simpler than it appears.
As discussed above, you provide a BlocObserver to Bloc by setting a static member. This means both that:
you can only have one observer in the system at a time, and
any code can access it directly by calling Bloc.observer
Then, when making state changes, you ensure you do so via an instance of BlocBase (such as Cubit), which takes care of calling the appropriate method on our observer.
So, once again using Core Concepts as a base, when calling CounterCubit().increment(), the call stack looks like this:
CounterCubit.increment
CounterCubit.emit/Cubit.emit/BlocBase.emit (through inheritance)
CounterCubit.onChange
BlocBase.onChange
SimpleBlocObserver.onChange
At this point, you're back in your own code, and you can see that SimpleBlocObserver.onChange(...) calls super.onChange(...). No magic, just function calls.

Dart - Snackbar service - global function vs static class function vs singleton

I would like to create a wrapper around a third-party package Snackbar (the third party Snackbar is simply called like this: Get.snackbar(title, body, snackPosition: SnackPosition.BOTTOM);) in order to decouple my app from the package and be able to easily swap in another Snackbar implementation.
I figure it should be a singleton for performance reasons. I would like to call it like VpSnackBar(title, body); ideally. I found how to make a singleton in dart (Vp is my app prefix to identify it was made in my app):
Here I have created this singleton
class VpSnackBar {
VpSnackBar._privateConstructor();
static final VpSnackBar instance = VpSnackBar._privateConstructor();
static void show(String title, String body) {
Get.snackbar(title, body, snackPosition: SnackPosition.BOTTOM);
}
}
I would have to call it like VpSnackBar.show(title, body);. But then I'm like should I just make a plain class with a static method which would do what this does, without ever being instantiated? Is instantiation beneficial?
Another option is a global function with an uppercase name so it is used like a class:
void VpSnackBar(String title, String body) {
Get.snackbar(title, body, snackPosition: SnackPosition.BOTTOM);
}
This is the only way that I know how to call it like VpSnackBar(title, body);. Which is my preferred way to call it. However, is a global function a bad practice? Could I achieve calling it like VpSnackBar(title, body); without a global function? Which way is the best practice?
So that I can be safe against any potential changes to the package
You won't be in any sort of way.
If the package owner decides to completely change the method internals without touching its prototype, you'll still be affected by those changes.
If the package owner decides to change the method's prototype in a backwards incompatible way, which features a breaking change, you'll also be affected by those changes.
I figure it should be a singleton for performance reasons.
I see that you're not running any heavy processes (like IO) when instantiating your class, so I cannot see why you should be concerned about performance. Consider that, for each widget build() call, which happens a lot of times in one second, hundreds of classes get instantiated, and they do not affect app's performance.
However, is a global function a bad practice?
Not at all. The actual problem with your approach is capitalizing the function's first letter. This is a bad practice, since it leaves who's reading to believe that your function call is actually a constructor call.
Which way is the best practice?
As I stated, I cannot even see a reasonable motive to wrap snackbar in the first place. But leaving this matter apart, each of your solutions seem equally fair to me (as long as you the uncapitalize the first of the function). In such situation, you may want to use the one that you feel more comfortable with.

Why should I only use `setState` in subclasses of `framework.dart`?

I have written and extension on Stream that allows me to call .watch(<some state>) and automatically keep the widget updated. It works really well, however, I call setState on passed states from the extension and because of this I get a warning saying The member 'setState' can only be used within instance members of subclasses of 'package:flutter/src/widgets/framework.dart'. My question is why is this not recommended/allowed?. To clarify, I get why I am getting the warning - I'm calling setState from another class - but why does Flutter "care" if I do this?
I have tried to find information on any reason for this, but I can only find the obvious workaround of adding a helper function, and no reason is given.
There could be two possible reasons why you are getting this error:
You are using a static or final keyword somewhere where you declare a state
You are unable to setState, because the extension is updating the state of the widget already
Let me know if you need any further help or I understood you wrong!

Composing IObservables and cleaning up after registrations

I have some code in a class that takes FileSystemWatcher events and flattens them into an event in my domain:
(Please note, the *AsObservable methods are extensions from elsewhere in my project, they do what they say 🙂.)
watcher = new FileSystemWatcher(ConfigurationFilePath);
ChangeObservable = Observable
.Merge(
watcher.ChangedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Edited,
};
}),
watcher.DeletedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Deleted,
};
}),
watcher.RenamedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Renamed,
};
})
);
ChangeObservable.Subscribe((args) =>
{
Changed.Invoke(this, args);
});
Something that I'm trying to wrap my head around as I'm learning are best practices around naming, ownership and cleanup of the IObservable and IDisposable returned by code like this.
So, some specific questions:
Is it okay to leak IObservables from a class that creates them? For example, is the property I'm assigning this chain to okay to be public?
Does the property name ChangeObservable align with what most people would consider best practice when using the .net reactive extensions?
Do I need to call Dispose on any of my subscriptions to this chain, or is it safe enough to leave everything up to garbage collection when the containing class goes out of scope? Keep in mind, I'm observing events from watcher, so there's some shared lifecycle there.
Is it okay to take an observable and wire them into an event on my own class (Changed in the example above), or is the idea to stay out of the native .net event system and leak my IObservable?
Other tips and advice always appreciated! 😀
Is it okay to leak IObservables from a class that creates them? For
example, is the property I'm assigning this chain to okay to be
public?
Yes.
Does the property name ChangeObservable align with what most
people would consider best practice when using the .net reactive
extensions?
Subjective question. Maybe FileChanges? The fact that it's an observable is clear from the type.
Do I need to call Dispose on any of my subscriptions to
this chain, or is it safe enough to leave everything up to garbage
collection when the containing class goes out of scope?
The ChangeObservable.Subscribe at the end could live forever, preventing the object from being garbage collected if the event is subscribed to, though that could also be your intention. Operator subscriptions are generally fine. I can't see the code for your ChangedAsObservable like functions. If they don't include a Subscribe or an event subscription, they're probably fine as well.
Keep in mind,
I'm observing events from watcher, so there's some shared lifecycle
there.
Since FileWatcher implements IDisposable, you should probably use Observable.Using around it so you can combine the lifecycles.
Is it okay to take an observable and wire them into an event on
my own class (Changed in the example above), or is the idea to stay
out of the native .net event system and leak my IObservable?
I would prefer to stay in Rx. The problem with event subscriptions is that they generally live forever. You lose the ability to control subscription lifecycle. They're also feel so much more primitive. But again, that's a bit subjective.

Static methods & inheritance in Coffeescript

I've been reading up a bit about coffeescript's inheritance model and I have the feeling I'm on the fringes of an ideological debate which I really don't understand. So, I would be perfectly happy to find out that I'm just doing things in the wrong way.
Basically what I am doing is writing a set of widgets which, among other things, need to handle events on their DOM elements. I thought a good way to go about this would be to have a class method which would be called once, to delegate all the events which the widget might need. The base widget class might have some simple click handlers, while the subclass might add to that some mouseover handlers or extra click handlers.
However, it appears that I'm not supposed to try and do the equivalent of calling super() inside a static method. There is a workaround which exists, (this.__super__.constructor.METHODNAME() but I've seen a lot of suggestions that this isn't the best way to do what I'm trying to do. Has anyone got any insights on how I should structure this code? Keep using the workaround, or put all the delegation into a totally different place? I can't really just stick it in the prototype, since I won't necessarily have an instance to call the method on (or can I essentially still call a method on the prototype from a static context, like putting SwatchableWidget.prototype.delegateEvents() into an onload function or something?
Here's a bit of code to illustrate what I'm talking about:
class Widget
#testProp: "ThemeWidget"
#delegateEvents: ->
console.log "delegate some generic events"
class SwatchableWidget extends Widget
#testProp2 = "SwatchWidget"
#delegateEvents: ->
console.log "delegate some specific swatchable widget events"
this.__super__.constructor.delegateEvents()
Widget.delegateEvents()
SwatchableWidget.delegateEvents()
Thanks for any help.
I suggest replacing
this.__super__.constructor.delegateEvents()
with
Widget.delegateEvents()
trying to use super to call static methods is not required (and doesn't make much sense)
I don't understand why delegateEvents would be a class-level method, or why Widget.delegateEvents have to be called again from SwatchableWidget.delegateEvents. If it's just class initialization code, you should put it in the class body directly:
class Widget
console.log "delegate some generic events"
...
#testProp: "ThemeWidget"
class SwatchableWidget extends Widget
console.log "delegate some specific swatchable widget events"
...
#testProp2 = "SwatchWidget"
I take it you're waiting for a specific DOM state before running this initialization code? Maybe I could suggest another approach if you told me a little bit more about the preconditions for delegateEvents.
It sounds like you want a different type of inheritance model where each inherited function of a certain type ("parent calling") will walk the inheritance tree and call all its parents with the same name.
You could call any direct parent functions in each child manually as you've written. Then it will float up the inheritance chain anywhere you specify such a relationship.
I would bind the parents delegate call in the constructor to a current class function
delegateparents =>
#call any parent class methods