Hi
Methinks it's time for another little example of working with the mvp-pattern, produced by 'mvp-setup', namely for those of you, who are as /lazy/ as I am
Here's an example of semi-automatic section registering, it touches 3 files after the initial creation with mvp-setup: model.intf, model.main & presenter.main.
we'll start with presenter.main:
...
initialization { we're taking advantage of the fact, that }
RegisterSection(TregPresenterMain.ClassName); { 'Classname' is a class function }
end.
then model.main:
{ TregModelMain }
TregModelMain = class(TObject,IregModelMain)
private { remember to use 'RegisterSection' in units, you want to add to 'Sects' :o) }
const Sects: TStringArray = ('[view.main]'); //* cutaway: ,'[TregModelMain]','[TregPresenterMain]'
var
...
constructor TregModelMain.Create(aPresenter: IregPresenterMain; const aRoot: shortstring);
begin
inherited Create;
fPresenter:= aPresenter;
fRoot:= aRoot;
UpdateSections(Sects); { <- fetch our registered sections, v- i18n }
fTextCache:= CreStrListFromFile(format(mvpTexts,[fRoot,regLang])); ///<- i18n
{ we need the model, this is a minor flaw if it fails, because then the }
if fTextCache.Count = 0 then { user will see a view filled with 'dummy' ;) }
fPresenter.Provider.NotifySubscribers(prStatus,nil,Str2Pch('(!) ERROR: Could NOT retrieve static texts!'));
end; /// the above text can't be translated in the i18n'ed mvptexts, the count is 0! ///
...
{$EndRegion 'TregModelMain'}
initialization
RegisterSection(TregModelMain.ClassName); /// <-- new in example, added
finalization
if Assigned(Singleton) then FreeAndNil(Singleton); { checks for nil explicitly, freeandnil doesn't! }
end.
and finally the model.intf:
...
{$interfaces com}
{ registers sections for use in 'GetStaticTexts()', put it in 'initialization'
at the bottom of the unit, for the objects/units you'll be registering }
procedure RegisterSection(const aSect: string);
{ gets called from model.main.constructor to update the 'Sects' array }
procedure UpdateSections(var anArray: TStringArray); // <- - needs 'sysutils' added in top-uses
implementation
uses contnrs;
var QSections: TQueue; { storage for our registrations till the model comes online }
procedure RegisterSection(const aSect: string);
begin
if aSect = '' then exit; { no empty allocations }
QSections.Push(strnew(pchar('['+aSect+']'))); { enqueue the [section] for later update }
end;
procedure UpdateSections(var anArray: TStringArray);
var lai: integer; lp: pchar = nil;
begin
if anArray = nil then exit; { we want at least '[view.main]' present before we start }
lai:= length(anArray); // start index for additions ~ 1
SetLength(anArray,lai+QSections.Count); { make room for all the registered sections at once }
while QSections.AtLeast(1) do begin { now as long as there are items in the queue }
lp:= QSections.Pop; { dequeue/pop the sections from queue }
anArray[lai]:= string(lp); { and add to array as a string }
inc(lai); { step our (l)ocal(a)rray(i)ndex 1 forward }
StrDispose(lp); { now release the memory the string was being held in }
end;
end;
procedure FinalizeQueue;
begin
while QSections.AtLeast(1) do StrDispose(QSections.Pop); { clear the queue, jic }
QSections.Free; { free the queue }
end;
initialization
QSections:= TQueue.Create;
finalization
FinalizeQueue;
end.
The reason, the registry is implemented in 'model.intf', is that this unit is referenced in every other unit's 'uses'-clause
Example project attached...
edit: Remember, 'TObject.UnitName' is also a class function, it's a nifty way of getting the unitname automagically...
Have fun & regards
Benny