Eclipse RAP: Best practice for "dispose" of widgets? - swt

I am new to Eclipse RAP and have no experience with SWT or Eclipse RCP. But I understand that the developer is responsible to dispose SWT widgets because they have native peers which would block resources of the operating system.
But what about "dispose" in a RAP application? It is the browser's problem to manage operating system resources (a file dialog, maybe). So "dispose" seems unnecessary for an application that is purely RAP, correct?
Now, if I wanted to have single-sourcing with SWT and RWT, i.e. the same source code runs as a standalone RCP application and as a RAP web application. What would be a best practice regarding "dispose"? How should it be triggered? What needs to be disposed?

There is no difference between SWT and SWT/RAP when it comes to disposing of widgets.
While SWT widgets hold native OS/window system resources while not disposed, RAP widgets hold browser resources i.e. DOM nodes as long as they live. Dispose of widgets when they are no longer needed and create widgets lazily if possible.

As to what needs to be disposed - anything with a dispose method! That is anything derived from Widget or Resource.
Disposing of objects derived from Widget (controls, composites, ...) is generally handled automatically when a Shell is closed.
Disposing of objects derived from Resource (things like Color, GC, Font,...) must be done by your code. You should dispose of these as soon as they are no longer needed. Failing to dispose of these objects is a common fault.

Related

Best practices for globals in flutter

I'm building an app that has text to speech.
It's possible to change the voice and set speed and such.
I'm using a standard TTS from the public dev.
My question is, how to initialize this and use it throughout the app without passing recreating it everywhere since the object rarely will change.
Once it is set up, I just want to have it speak.
It's certainly not impossible to recreate it every time I need it.
I'm looking for best practices.
Just have a class that holds all the information with an initialize method:
class Constants {
static bool firstVar;
static String secondVar;
static void initialize() {
firstVar = true;
secondVar = "";
}
}
// then call it in your main method before building the first widget
Constants.initialize();
In this case, you need to use a state management architecture.
There are a good number of them to choose from. There are many articles and videos that explain how to use them. One thing they have in common is just what you're looking for. The ability to provide state at an app-wide level without reconfiguring in each widget.
Check out the Flutter Documentation here. Follow through the next pages and you'll have a good general overview of state management. Available options include, Provider, Riverpod, Redux, InheritedWidget, Stacked, etc. (Many of them actually).
For example, with Provider, you initialise the TTS in some TTS StateProvider (just an example). Then after wrapping your topmost MaterialApp in a ProviderScope, you can easily use the TTS in any widget as follows:
final tts = Provider.of<TTSProvider>(context).tts;
tts.doWhateverYouWant();
Another advantage of these architectures is that a good number of them permit good separation of concerns and dependency injection (or inversion of control).
In simpler terms, separation of concerns give you have the ability to write UI specific code separate from logic specific code. This way, if you want to debug, or change the packages or APIs you're using, you'll do them easily from one place (without fear of damaging the codebase). Besides it promotes clean code too.
Dependency Injection involves the use of services or something similar to obtain what widgets need to work without the widgets configuring the services themselves.
As you explore, you'll also notice that some architectures like Stacked permit you to manage app-wide state without the BuildContext. For another example for TTS, with Stacked Architecture, you could have:
final tts = locator<TTSService>().tts;
tts.doWhateverYouWant();
This pattern is useful because, in StatelessWidgets, the BuildContext is available only within the build method and you might need to use stuff outside it. In addition to obtaining the TTS anywhere in the Flutter code, you could do other things like BottomSheet, Navigation, Toast, etc. without BuildContext.
Furthermore, you'll notice that you will tend to use more StatelessWidgets as widgets no longer keep state for you.
On a final note, don't worry about performance. Flutter in itself is efficient and handles everything properly.

Flutter(Cubit and Repository) - Where to inject dependencies

I'm relatively new to Flutter and Cubit pattern and I'm trying to figure out which are the best ways to work with them. Recently my colleague and I have been struggling to reach an agreement where we should inject the cubit and the repositories.
Reading the bloc/cubit documentation, it is not very clear about where we should do it.
IMO, everything that we need to instantiate, should be injected as high in the tree as possible where two different components that will use this information have in common.
For my colleague, each widget can instantiate one cubit, meaning that each widget will have its own instance of the cubit.
I would like to discuss about what are the community thoughts and best practices regarding the dependency injection and architecture regarding cubit.
There is no single answer to that question. It all depends on your project structure and architecture. In general though:
It's OK to create a few cubits/blocs in one screen/widget. Some widgets or screens contain more than one business logic stuff. Cubits are just classes that help you maintain the state, but it's no different than having many animation controllers or text editing controllers, it's just that it serves a more high-level state management. Let's say that you have a comments section in your app. You may have:
a cubit for the comments themselves, to load them, load more on scroll, report error when loading failed etc.
a cubit for each comment that manages the "Like" button under a comment
It's perfectly valid to have it that way.
It's OK to have global cubits for the whole app. There are some things that you need to have access to from the whole application. It usually is navigation (Navigator), and some theme management (Theme), why not something more business-logic related then, like authentication logic, current user context, user's app preferences, etc.? :)
IMO, everything that we need to instantiate, should be injected as high in the tree as possible where two different components that will use this information have in common.
This is a good approach. Most frequently it will be above your routes, so somewhere above your MaterialApp. If you make use of nested Navigators, then this common place could be above this nested Navigator.
On a more technical side, how will you manage the dependencies used in those cubits/blocs is up to you and your liking. I find some of the options:
Instantiating all repositories and other dependencies in main.dart method and then passing them in constructors to your blocs/cubits in Providers.
To reload those dependencies you will need a Hot Restart though, Hot Reload won't be enough.
Putting your dependencies in the widget's tree with Provider, just like blocs/cubits.
Using riverpod instead of provider.
Using a Service Locator pattern with get_it and injectable combo.
The most correct choice will be something that you (and your colleagues) are most comfortable developing with and that scales well.

How to handle local-state in flutter with provider?

I use the provider package to manage my application state. I have a few questions concerning how to manage the state in the application.
Is it a good practice to create a ChangeNotifier class for each screen in my application to handle the back end for this page (which is provided to only this screen) ?
In an example like this:
If i have a page that have multiple widgets and i need to rebuild a small part of the page like adding a new TextField on enabling a switch.
in the previous example
Should i use a provider to only rebuild the small part of the page or this part is mostly handled by only using changeState() ?
in case that the local-state of the page should be handled in the screen.
Where should i place the logic of the page, like http requests on button clicks and loading data for this page ?
If the state that you are updating is only needed within one widget with one or two down widgets down the tree, I would recommend using the built-in SetState. While both Provider and SetState would work for any form of state management, I tend to think of Provider as similar to React Context.
Provider is great for holding state at page levels or if you want to maintain the separation between widget builds and logic in different files.
SetState is great for local widgets with not a lot of nested widgets underneath.
Here is a great article that discusses the different state management solution approaches. At the end of the day, it's up to preference!

Integrating a GWTP project with a standard GWT project

I have a GWTP application which has no entry point because I don't ever need to run this application on its own. Rather I want to use it within a standard GWT application which has an entry point, implements its own history management mechanism, uses its own implementation of MVP framework, has its own dependency injection and so on.
The question is: Is it even possible to nicely integrate a GWTP application within a standard GWT application?
Consider this use-case for example: I want to show a popup dialog when a button is clicked in a view that is implemented in the GWT application. The popup dialog is a GWTP PresenterWidget implemented in the GWTP application. How is it possible for a non GWTP presenter to show a popup and make sure all life cycle events are properly called.
I know it's a broad question but I'm looking to see if any body has ever tried to integrate two such applications together. If not is there any advice on how to approach this problem at all.
Thanks in advance
In that kind of context, I would suggest to build your home made mvp framework. It would be easier and cleaner than using a subset of the capabilities of GWTP.
That being said, it's not imposible, but you will have to use a complete hierarchy of presenter / presenter widgets. But that won't mean that the lifecycle will work... The lifecycle of GWTP is strongly tied to internal Navigation Events and if your application doesn't use this feature of GWTP, you're likely to lose all its advantages.
Here's how you can embed a GWTP application in your own already existing application:
https://github.com/ArcBees/GWTP/wiki/Website-Embedding
We've already worked on migrating an existing application to GWTP by embedding the existing application IN GWTP while gradually migrating the existing code base, but not the other way around.

How Build GWT Application using MVP

I have great experience in programming by using java and other languages.
I need anyone who has great experience in using GWT with MVP to explain how to build GWT Application using MVP:
View package : explain what should be in view class.
Client Package: explain what java files are supposed to be here and what is the benefit from each file.
Server Package: I think here all services files( RPC ).
Activity Package: Explain what is the benefit from the classes here , I think here we we connect events with controls in view classes( Am I correct?).
Place Package: I need to understand this very well.
Also what is the benefit from Clientfactory java file?
what is eventbus?
what is placecontroller?
please if you can order which file should be coded one after another?
Thank you in advance,
1) View is a widget with link to its presenter. It should notify presenter about ui events which should be processed.
2) Views, presenters, client(not shared with the server side) model, places, activities, PlaceHistoryMapper, ActivityMapper. About benefits see below.
Are you understand presenters well? According to your question i assume you confuse it with activities.
1.1 ) Presenter creates and manages view, makes rpc and most of 'logic' stuff.
3) You are right, server package is just a java server logic.
4) Activities link places and presenters. I will return to describing activities below.
5) Place has name, token and own Tokenizer which transforms its place to a token and other way round.
6) I didn't use ClientFactory. I prefer dependency injection with google-gin(gwt client version of guice)
7) Event bus is... I couldn't describe better than official javadoc does :)
Dispatches Events to interested parties. Eases decoupling by allowing objects to interact without having direct dependencies upon one another, and without requiring event sources to deal with maintaining handler lists. There will typically be one EventBus per application, broadcasting events that may be of general interest.
8) PlaceController knows where you are(in application :) and may change current place. (obviously, it has getWhere() and goTo(Place) methods)
9) Firstly you need to code application's singletones like PlaceHostoryMapper and ActivityMapper.
PlaceHostoryMapper provides history and converting tokens to places by segregating all PlaceTokenizers.
ACtivityMapper segregates all places and activities and provides second ones by first ones.
Views and presenters are based on interfaces. Next I would declare such interfaces.
Then write places. Then you able to code activities because you have places and interfaces of presenters.
Then in any order implement views and presenters, map activities to places in ActivityMapper and register PlaceTokenizers in PlaceHistoryMapper.
I assume now you have more questions, feel free to ask in comments or by contacts in my profile :)