Recent

Author Topic: MVP made easier.  (Read 11472 times)

Hansvb

  • Hero Member
  • *****
  • Posts: 792
Re: MVP made easier.
« Reply #45 on: April 14, 2025, 08:29:54 pm »
I will enjoy Easter, Lazarus or mvp have little influence on that. :) But it might be a good moment to take another good look at everything. I still don't use the full possibilities it seems.

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #46 on: April 15, 2025, 01:01:45 pm »
Hi Hans
Sounds good to me  8)
Quote
I still don't use the full possibilities it seems.
Well in that case, I might just have something to "Wet your appetite" with...
Have you noticed the feature of the TransactionManager:
- It remembers 'Non-Comitted' transactions!

So attached is a small example on how to use / exploit that feature.
It's a small app, I use when I have to publish a project here in the forum, to weed out unwanted files... Nothing fancy  8-)

Happy Easter my friend & have fun...
Regards Benny

edit: The zip now contains all files  %)
« Last Edit: April 15, 2025, 03:56:52 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #47 on: April 15, 2025, 01:10:19 pm »
Sorry mate, forgot these...
They go in 'common'.
Regards Benny

edit: new zip uploaded in previous post, now contains all files
« Last Edit: April 15, 2025, 03:58:09 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #48 on: April 21, 2025, 05:38:10 pm »
Helllloooo  ;D
Right, so I had made myself a TODO-list for Easter  ...and today I've finished it,  8) with a new release of MVP-Setup as the result \o/\ö/\o/  ver.: 14.21.04.2025
Here's an excerpt from the CHANGELOG:
Quote
21.04.2025 Added a 'Transaction-Factory' to the transaction-manager, incl. transaction-class'
           registration on unit-initialization. Added a new unit 'common.consts.pas', to do away
           with most of the constant-aliases. Plus added 2 more transaction-examples for you
           guys to play with i.e.: you have to make the view etc. for them - practice :o)
As always, you can get it HERE at my Gitlab-crib...
Have fun and happy coding out there...  8-)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Hansvb

  • Hero Member
  • *****
  • Posts: 792
Re: MVP made easier.
« Reply #49 on: April 22, 2025, 12:07:41 pm »
I start with small steps. I made a simple transaction with the NoRes. That works. It looks like I can put a record that is used in a transaction in model.base or in common.const. Both work but common.const saves 1 alias mentioning.
Then I thought I'd take a look at TFileInfoTrx I have trouble with that. I am doing something wrong in the transaction or in the handling of the Dofunction. If I look at the LSL variable in the transaction, I find 10 files in the list. That is good. But I have no idea how to translate that into the Dofunction. LSL comes in there as a pointer. casting to stringlist gives an empty list. Where am I going wrong?
More questions will come this week if i may :-[.

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.Button1Click(Sender : TObject);
  2. var
  3.   lTrx: TFileInfoTrx;
  4. begin
  5.   try
  6.     lTrx:= FPresenter.TrxMan.StartTransaction(prFetchFileData) as TFileInfoTrx;
  7.     lTrx.Title:= 'd:\Development\Pascal\40\MVP-setup\Gegenereerd_project\Leeg_21042025\';
  8.     FPresenter.TrxMan.CommitTransaction;
  9.   except
  10.     FPresenter.TrxMan.RollbackTransaction;
  11.     stbInfo.SimpleText:= 'Oeps';
  12.   end;
  13. end;  
  14.  
  15.  
  16. { TFileInfoTrx }
  17. procedure TFileInfoTrx.Execute(aMgr: ITransactionManager);
  18. var lsl: IStringList;
  19.   i: Integer;
  20.   tmp: String;
  21. begin
  22.   if fTitle = '' then aMgr.Owner.Provider.NotifySubscribers(prDirDataNeeded,self,nil);
  23.   if fTitle = '' then exit;
  24.   fDi:= GetDirInfo; { nifty little <experimental> manual interface :o) }
  25.   lsl:= fDi.GetFiles(fTitle,true);
  26.   // so far ik works. I have to figure out what is happening here.
  27.  
  28.   // ctrl
  29.   i:= lsl.Count;  // = 10 files = good.
  30.  
  31.   for i:= 0 to lsl.Count -1 do begin
  32.     tmp:= lsl[i];  // tmp gets the correct file names = good.
  33.   end;
  34.  
  35.   // nd here i go wrong...
  36.  
  37. //  aMgr.Owner.Provider.NotifySubscribers(prFetchFileData,self, Pointer(lsl));  // < wrong ??
  38. //  aMgr.Owner.Provider.NotifySubscribers(prFetchFileData,self, @lsl);  // < wrong ??
  39.   aMgr.Owner.Provider.NotifySubscribers(prFetchFileData,self, lsl);  // < wrong ?? is empty when it arrives in the view ???
  40.  
  41.   aMgr.Owner.Provider.NotifySubscribers(prStatus,nil,Str2Pch('(i) Dir-Info on "'+Title+'" fetched successfully'));
  42. end; { end of examples }

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #50 on: April 22, 2025, 01:37:49 pm »
Hi Hans
This is correct:
Code: Pascal  [Select][+][-]
  1. aMgr.Owner.Provider.NotifySubscribers(prFetchFileData,self, lsl);
...and here is one possible way to handle it:
Code: Pascal  [Select][+][-]
  1.   case aReason of
  2.     { the following line handles the stringlist in userdata/adata }
  3.     prDataChanged,prFetchDirData,
  4.     prFetchFileData: DoShowText(aNotifyClass,IStringList(aData));
  5.     {$ifdef unix}
  6.     prDirDataNeeded: TtbdTransaction(aNotifyClass).Title:= InputBox('Dir-Info',
  7.                                                                  'Please enter a full path:',
  8.                                                                  '/home/bc/src/');
  9.     {$endif}
  10.     prMainStaticTexts: DoStaticTexts(IStringList(UserData)); { important startup-code }
  11.     prStatus: if aNotifyClass = nil then stbInfo.SimpleText:= Pch2Str(UserData)
  12.               else DoStatus(aNotifyClass,UserData);
  13.   end;
... and finally I stuff it into a memo-control:
Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.DoShowText(anObj: TObject; aText: IStrings); { moneygreen: $00AAF0B5 ABGR }
  2. var lt: ItbdTransaction; { we use the ancester 'cause we use common title prop }
  3. begin
  4.   if anObj.GetInterface(ItbdTransaction,lt) then Edit1.Text:= lt.Title;  
  5.   aText.AssignToEx(Memo1.Lines); /// into memo here
  6. end;
Just remember, it's an IStringlist you're sending, NOT TStringlist.
It works pretty flawless here...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #51 on: April 22, 2025, 01:42:20 pm »
Hi
Here's an example view.main.pas/lfm
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #52 on: April 22, 2025, 05:02:07 pm »
Hi
If you use the example-view, you might miss this function, which I've implemented in 'model.intf.pas':
Code: Pascal  [Select][+][-]
  1.  
  2. { convenience function for cleaning up CORBA references }
  3. procedure FreeCorbaThenNil(var anIntf);
  4. { registers sections for use in 'GetStaticTexts()', put it in 'initialization'
  5.   at the bottom of the unit, for the objects/units you'll be registering }
  6. procedure RegisterSection(const aSect: string);
  7. { gets called from model.main.constructor to update the 'Sects' array }
  8. procedure UpdateSections(var anArray: TStringArray); // <- - needs 'sysutils' added in top-uses
  9.  
  10. implementation
  11. uses contnrs;
  12.  
  13. var QSections: TQueue; { storage for our registrations till the model comes online }
  14.  
  15. procedure FreeCorbaThenNil(var anIntf);
  16. begin
  17.   if pointer(anIntf) <> nil then begin
  18.     IftnCorba(anIntf).Obj.Free;
  19.     pointer(anIntf):= nil;
  20.   end;
  21. end;
  22.      
The important one is 'FreeCorbaThenNil();'...  ;D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Hansvb

  • Hero Member
  • *****
  • Posts: 792
Re: MVP made easier.
« Reply #53 on: April 22, 2025, 06:11:26 pm »
My DoFiledata was wrong. This works.

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.DoFileData(anObj : TObject; aData : pointer);
  2. var
  3.   i: Integer;
  4.   filelist: IStringList;
  5. begin
  6.   // just a short test.
  7.   filelist:=  IStringList(aData);
  8.   if filelist.Count> 0 then begin
  9.     Memo1.Clear;
  10.     for i:=0 to filelist.Count-1 do begin
  11.       memo1.Lines.Add(filelist[i]);
  12.     end;
  13.   end;
  14. end;  

Now I have to understand what I see and what I am doing.

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #54 on: April 22, 2025, 06:44:17 pm »
Hi Hans
Glad you've figured it out... :)
Btw. there's this method of IStrings, you can use: "procedure AssignToEx(aDest: TStrings;aClearFirst: boolean = true);", so instead of:
Code: Pascal  [Select][+][-]
  1. Memo1.Clear;
  2.     for i:=0 to filelist.Count-1 do begin
  3.       memo1.Lines.Add(filelist[i]);
  4.     end;
you can:
Code: Pascal  [Select][+][-]
  1. ...
  2.   filelist.AssignToEx(memo1.Lines);
-- IStringlist is packed with small conveniences like that...  ;)
I wish you a happy educational journey through the sorce of the new release, don't forget to check out the new Transaction-Factory, hidden in the manager... It should alleviate you having to write lines in the manager's 'StartTransaction' & 'CommitTransaction', respective case statements...  8-)
...As long as you remember to register them on unit initialization...
The 'IDirInfo' interface is for when you're feeling advanced  :D 'cause that's how an interface looks behind the scenes...  :-X Completely made by hand--
Regards Benny

eta: The little interface could serve as a base for a simple "File-Explorer"...
« Last Edit: April 22, 2025, 06:52:17 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Hansvb

  • Hero Member
  • *****
  • Posts: 792
Re: MVP made easier.
« Reply #55 on: April 22, 2025, 07:49:14 pm »
Quote
don't forget to check out the new Transaction-Factory, hidden in the manager...
I will, but for now i have "problems" with my own tool. I open a second view from view.main and so far that was a simple thing but I now want to create a sqlite file from this view. (I had also circumvented that by putting that in the viewmain). But now I also want to build tables based on Treenodes names. So I guess I should actually provide this view with its own presenter etc to keep things separate. What do you think?

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #56 on: April 22, 2025, 08:07:40 pm »
Hi Hans
Yes, that formally screams for its own Presenter, it's a nifty way of separating module-logic and keep things clean...
I tend to think of it, in the same vein I see TFrames used to group related stuff together and not /clutter/ up the main module...
...Perhaps I would even go so far, as to create a 'model.datastore' along with it, maybe making them children to the 'Main' respectively with a reference...
Sounds good to me, let me know how you fare...  ;D
Regards Benny

eta: Also, as I told you a long time ago, there are mvp'ers out there, who swears by the "1 view->1 presenter->1 model" paradigm...
These paradigms are all dialects of the same basic model, namely the one we practice, just made to scale easier.
« Last Edit: April 22, 2025, 08:16:00 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Hansvb

  • Hero Member
  • *****
  • Posts: 792
Re: MVP made easier.
« Reply #57 on: April 23, 2025, 12:22:08 pm »
I think I have almost finished it in an empty project. I have now cut everything up. Custom model and presenter files for the second view. Now I still run into 1 error message that I can't find. "multiple defined symbol "BC_PCH2STR"

Giving a second view my own model, presenter etc seems too much ballast for my simple tool.

cdbc

  • Hero Member
  • *****
  • Posts: 2100
    • http://www.cdbc.dk
Re: MVP made easier.
« Reply #58 on: April 23, 2025, 01:33:55 pm »
Hi Hans
Look in 'model.decl.pas', there you'll find these:
Code: Pascal  [Select][+][-]
  1. { utility functions, here we publicly export these functions, to be made available
  2.   in other units, that can't /see/ us, for import :o) gotta love FPC \o/\ö/\o/ }
  3. function Pch2Str(aPch: pchar): string; public name 'BC_PCH2STR';
  4. function Str2Pch(aStr: string): pchar; public name 'BC_STR2PCH';
Then have a look in 'presenter.trax.pas', where you'll find these:
Code: Pascal  [Select][+][-]
  1. implementation
  2. // uses StrUtils; { for: 'IndexText' etc... }
  3.  
  4. { utility functions, taking advantage of the publicly exported functions,
  5.   in a unit that we can't /see/ from here. compiler imports for us :o) gotta love FPC }
  6. function Pch2Str(aPch: pchar): string; external name 'BC_PCH2STR';
  7. function Str2Pch(aStr: string): pchar; external name 'BC_STR2PCH';
  8. { the above 2 imports, are here to avoid referencing 'model.decl' in this unit.
  9.   if you have to, then only in this 'implementation' part. }      
  10.  
The first one publishes the 2 functions and the second one imports them for use...
So I think you have to define 2 of your own, like in presenter.trax, i.e.: the import ones...
Regards Benny

EDIT: OH, I just reread your post, somewhere in your code, you have a second set of the publisher functions... DAS IST VERBOTEN! compiler chokes...  :D So try to comment the 2 with 'public name' out...
« Last Edit: April 23, 2025, 01:39:28 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Hansvb

  • Hero Member
  • *****
  • Posts: 792
Re: MVP made easier.
« Reply #59 on: April 23, 2025, 04:08:52 pm »
Hi Benny,

This works but is wrong. To get rid of the error "multiple defined symbol "BC_PCH2STR", I turned off both functions in model.configure.decl. But then I ran into the fact that they were no longer found. For that I have added model.decl in presenter.configure and in model.configure in the uses. (That's not good, the beginning of spaghetti code). (First mistake). I also run into the fact that I am only allowed to open the second view 1 time. The second time I get stuck on an acces violation in the function:

Code: Pascal  [Select][+][-]
  1. unit model.configure.base;
  2.  
  3. procedure UpdateTransactionManager(aTraxMap: ITraxClassList);
  4. begin
  5.   TCL.AssignTo(aTraxMap); { everything and the kitchen-sink }  <-- access violation when view is openend for the second time.
  6.   TCL:= nil; { release this reference, it's not needed after the manager is up }
  7. end;
  8.  


It more or less works but I think it's a bit too much of a good thing now.

 

TinyPortal © 2005-2018