Recent

Author Topic: Best way to exchange data between a form and a unit  (Read 48401 times)

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #30 on: January 16, 2024, 05:43:27 pm »
Quote
However, we need to shift your focus from mainly visual to more

If that is possible then I am grateful. I learn all kinds of things this way.


Code: Pascal  [Select][+][-]
  1. lRec: TProgressRec; // local rec, doesn't need to be global :o)
Using local variables is often my pitfall. But i never done this before. I should definitely remember this one:
Code: Pascal  [Select][+][-]
  1. Edit1.Text:= CalculatePercentage(PProgressRec(aData)^);


cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #31 on: January 16, 2024, 06:12:34 pm »
Hi
Welcome to the "sandbox", where we build all sorts of stuff  :D
Quote
If that is possible then I am grateful. I learn all kinds of things this way.
Well, if You feel like it, we can play here in the sandbox for a longer thread and gradually build up to a project following the MVP-pattern  8-)
What do you think?
I've got the time and you can just play along within your time-limits, no hustle... ...and I've even got half of an idea for a test/play -project  :D
edit: First off, I'll start by renaming the unit "logic" to "hvb_presenter.pas"
Regards Benny
« Last Edit: January 16, 2024, 06:15:45 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #32 on: January 16, 2024, 06:39:45 pm »
Well, its still early dark in the evening and it is cold. So i wll spend most of the time in the evening behind my laptop , tv or read a book. I have time.

cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #33 on: January 16, 2024, 07:13:24 pm »
Cool  8-)
I'll prepare something for you to look at, hang on for a bit...
edit: have you got a small task, you would like for us to solve?
/b
« Last Edit: January 16, 2024, 07:15:41 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #34 on: January 16, 2024, 07:21:08 pm »
Btw, here are the lazarus forms for the mvvm-book.
/b
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #35 on: January 17, 2024, 03:02:19 pm »
Hi
@Hansvb: So I've fiddled a bit with our toy-project...  %)
Here it is attached, have fun  :D
edit: I think we take questions/discussions here, so that others can chime in, with their ideas & points of view...
Regards Benny
« Last Edit: January 17, 2024, 03:06:23 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #36 on: January 17, 2024, 07:27:13 pm »
Hi Benny,
Thanks, I wasn't expecting a completely working project. I have to look into this carefully. There's a lot going on that's new to me. I'll dig into it properly this Friday afternoon or Saturday. Tomorrow I unexpectedly have to work longer and then I won't have the energy to remember new things late in the evening.
I have only briefly looked through it now.

Thanks for all the effort so far.

Quote
edit: I think we take questions/discussions here, so that others can chime in, with their ideas & points of view...
That's certainly good. Everything is nicely collected together. I have already bookmarked this thread.

cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #37 on: January 17, 2024, 09:52:27 pm »
Hi
Cool, you are very welcome  8-)
Yeah, well I like to have the code compile to run, after a new development spur... By all means we're far from done, just scratched the surface, more to come.
I thought I'd show you, what you can do with the built-in framework and more importantly, what you can't  ;D The limitations as such, e.g.: the "ooPercentCalculated" alias  ::)
We still haven't got a real little task to solve, I'd like it to be a useful one  :)
Play with it and I'll bet you will have some questions...  :D
It's a nice little skeleton to build on...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #38 on: January 19, 2024, 08:07:36 pm »
Hi,

I thought I'd start with the simplest, the reset button. With what I saw here I tried to provide a new project where the form caption and a statusbar.panel[0] have a different text string when the project starts. That only works half way. I see either the caption or the status bar text but not both. I can see why it works that way but haven't found a solution yet. So I suspect it will still take me a while to understand some of this.
So I'm still busy for now.  :)


cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #39 on: January 19, 2024, 08:33:44 pm »
Hi
Quote
So I'm still busy for now.  :)
Good, that means you're learning new stuff  8)
Quote
I can see why it works that way but haven't found a solution yet. So I suspect it will still take me a while to understand some of this.
Remember it's better to ask one too many questions, than to ask one too few questions... I and the rest of our little club here, are ready to help out, if you need it  ;)

3 things to consider:
1) The View is stupid! it relies 90% on the Presenter, to do everything for it.
2) The Presenter is the genius in the family, it takes care of all the thinking.
3) The Model is everything about data! Principally all data should come from
    it and to it, through the Presenter. The model is the "Heavy Lifter" of the
    family.
Have fun & a nice weekend  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #40 on: January 19, 2024, 09:27:38 pm »
Quote
Remember it's better to ask one too many questions, than to ask one too few questions...
I know but I need some basic knowledge through practice. Then I wil rember it better later on.

I'm a lot further along. I can now put a form caption and a status bar panel text and if I edit text in an edit, the status bar text changes and the form caption remains intact.
I'll see how the rest works this weekend.

Why is there a separate lcl_observer unit? Are the default options of lazarus/pascal not enough? And can I use lcl_observer in my own tool?

cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #41 on: January 20, 2024, 01:38:58 am »
Hi
Quote
Why is there a separate lcl_observer unit? Are the default options of lazarus/pascal not enough? And can I use lcl_observer in my own tool?
The point is, with that unit you can utilize the IFPOxxx interfaces, also from a unit of code separated from the lcl. You can instatiate an IFPOBserved / TlclObserved object in your own classes and connect your forms IFPObserver
 to it easily. The same goes for the TlclObserver, it can reside in your own class separate from the lcl and listen to your forms or an edits/trackbars messages / callbacks etc. The second point was to show you how to communicate outside of the form-unit and the limitations of the design with TObservedOperation, you have 5 separate types of operations you can identify and not more. It's non-extendable.
Later i'll show you another observer implementation, which is a lot more flexible, I know, wrote it myself  :D
The lcl_observer-unit code is the original fpc-rtl code from PascalDragon(I think), just forked to a separate unit plus a couple of additions to ease its use. It has the same copyright and license as the one sitting in the belly of rtl(clearly stated in the unit). I should think you can use it, like you use any fpc or lazarus code-bit, just don't remove the copyright & license statement.
So yes, you can use it in your own tool.

It's all part of an attempt to free ourselves of the "LCL-Shackles", if you like.
:D "Decoupling" being the operative word here.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #42 on: January 20, 2024, 03:18:21 pm »
I'm trying to sort it out...
During the creation of the view, a presenter is created (and you have access to the public methods in the presenter).
In the creation of the presenter, a model is created (And you have access to the Model). view->presenter->model are connected via a property. (or get set methods)
In the presenter you can have functions that, when you call them from the view, trigger the presenter's observer. If a change takes place, the view is informed. And you can have functions in the presenter that first call a function in the Model. The function in the Model then returns a value or a record or something as a pointer. As I see it now, the functions in the Model must always return a value, is that correct? (Unless the model is extended and also has private methods. These are necessary for the operation within the model itself).
This returned pointer data is passed to the observer (notifyObserver) which in turn informs the view.
Is this broadly correct?

What I don't understand is how do you know which TFPObservedOperation to use. And what can you do with ooCustom?

And what I still have trouble with is that there is something (an observer) running in the background that you cannot see into.


Suppose I create a function that checks whether certain directories are present in the directory of the executable. Does this also have to go via the presenter to the model and back to the presenter? Or can that be done directly via the presenter?

cdbc

  • Hero Member
  • *****
  • Posts: 1497
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #43 on: January 20, 2024, 07:04:59 pm »
Hi
Nifty little setup, huh  :D Don't worry, it'll get much better as we go along...
Quote
During the creation of the view, a presenter is created (and you have access to the public methods in the presenter).
In the creation of the presenter, a model is created (And you have access to the Model). view->presenter->model are connected via a property. (or get set methods)
Yes, that's the idea, basically: The view can't live without a presenter (view is stupid, remember), which in turn can't do much without the model (Business Object Model), the model is where the app's data lives(& logic). The view /needs/ the presenter, which /needs/ the model.
Quote
In the presenter you can have functions that, when you call them from the view, trigger the presenter's observer. If a change takes place, the view is informed. And you can have functions in the presenter that first call a function in the Model. The function in the Model then returns a value or a record or something as a pointer. As I see it now, the functions in the Model must always return a value, is that correct? (Unless the model is extended and also has private methods. These are necessary for the operation within the model itself).
This returned pointer data is passed to the observer (notifyObserver) which in turn informs the view.
Is this broadly correct?
Yes, broadly speaking, that's the gist of it.
The public interface of the presenter _is_ your app's API to what it can do.
The notifications from the Observed _must_ be documented, so that the view knows how to react to them, e.g., "how do you know which TFPObservedOperation to use?"
a) In this case I choose! ...and I'm writing the view as well, so I know what
    to react to = "ooPercentCalculated"
b) In case someone else is writing the view, you must document that this
    "CalculatePercentage(p: PProgressRec);" method returns a record to the
    observer, containing the relevant information via the ooOperation
   "ooPercentCalculated".
c) I could have chosen "ooCustom" just as well, it's /generel purpose/
Quote
And what I still have trouble with is that there is something (an observer) running in the background that you cannot see into.
If it didn't work, your view would just show "dummy" texts on startup  :)
Actually, as it should be, opaque - nothing to see here - just mechanics  8)
When the subject/observer -pattern is working, there's nothing to see there.
It's like a conveyor belt, if it's broken you'll notice it, if not, it'll just transport stuff, all day long.
Later or maybe tomorrow, I'll show you another subject/observer and make some changes to our view...
Quote
Suppose I create a function that checks whether certain directories are present in the directory of the executable. Does this also have to go via the presenter to the model and back to the presenter? Or can that be done directly via the presenter?
Suppose the view feeds a "list" of names to the presenter-method that handles that search -> procedure TPresenter.FindDirectories(alist: tstrings);
This method then ask subject to notify observer that it should put a "Rootdir" in the supplied record(p), well back again, suppose it then feeds the model-method "ScanForDirs(aRoot: string;aList: tstrings): boolean;"
...and if that returns true, it then sends the rootdir & list to the view via subject.NotifyObservers (using ooCustom), then the view can happily show the user the results  :)
Look at it this way:
view -> order presenter to find -> presenter needs more info ...<--- back to view <ask> -> presenter{OK} -> order model to find {model cooks up a result} <- return to presenter with result -> forward result to subject{packs in record and notifies} -> the view gets result and shows in a treeview...
Pheewww... Hope that all makes sense to you...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 687
Re: Best way to exchange data between a form and a unit
« Reply #44 on: January 20, 2024, 08:46:33 pm »
I will try to create the directory creater tomorrow.

What else comes to mind. Won't the presenter and the model be way too big if everything goes into it? Or can you have multiple models talk to 1 presenter? Normally, I try to separate things into different units.

 

TinyPortal © 2005-2018