unit model.intf;
{$mode ObjFPC}{$H+}
{-$define dbg}
interface
uses classes, sysutils, istrlist, model.base, obs_prosu;
type
{$interfaces corba}
IPresenterMain = interface; // forward
IPresenterConfigure = interface; // forward
{ aliases for provider & subscriber }
IobsProvider = obs_prosu.IobsProvider;
IobsSubscriber = obs_prosu.IobsSubscriber;
{ alias for transaction }
ITransaction = model.base.ITransaction;
{ the actual model/datastore api, the "King" }
IModelMain = interface(ICorba)['{0349B40E-FBB4-4C6E-9CB0-A63690CF0898}']
function GetStaticTexts(const aSection: string; out aTarget: integer): IStringList;
procedure RefreshSections;
procedure ReloadTextCache;
function StringConcat(firstString, secondString : String) : String;
end; { IModel }
{ the child model/datastore api, the "BigBrother" }
IModelConfigure = interface(ICorba)['{F5E9E12D-F9B5-412F-9708-C751F50A14D2}']
function GetStaticTexts(const aSection: string; out aTarget: integer): IStringList;
procedure RefreshSections;
procedure ReloadTextCache;
function StringConcat(firstString, secondString : String) : String;
end; { IModelConfigure }
{ ITransactionManager reacts to user actions }
ITransactionManager = interface(ICorba)['{C75AE70E-43DA-4A76-A52D-061AFC6562D0}']
function get_ActiveTrx: ITransaction;
function get_ModelConfig: IModelConfigure;
function get_ModelMain: IModelMain;
function get_OwnerConfig: IPresenterConfigure;
function get_OwnerMain: IPresenterMain;
procedure set_ModelConfig(aValue: IModelConfigure);
procedure set_OwnerConfig(aValue: IPresenterConfigure);
procedure CommitTransaction;
function InTransaction: boolean; { below is register for runtime jic, NOT startup!!! }
procedure RegisterTransactionClass(aModReason: ptrint; aTransactionClass: TTransactionClass);
procedure RollbackTransaction;
function StartTransaction(aModReason: ptrint): TTransaction;
property ActiveTrx: ITransaction read get_ActiveTrx;
property ModelConfig: IModelConfigure read get_ModelConfig write set_ModelConfig;
property ModelMain: IModelMain read get_ModelMain;
property OwnerConfig: IPresenterConfigure read get_OwnerConfig write set_OwnerConfig;
property OwnerMain: IPresenterMain read get_OwnerMain;
end; { ITransactionManager }
{ specialized transaction, sports an 'execute' method, i.e.: it knows how to commit itself ;-) }
ITrxExec = interface(ITransaction)['{2E618F58-DE15-4A79-ADEF-C4E0A7CBECA4}']
function Execute(aMgr: ITransactionManager): boolean;
end; { ITrxExec }
{ sibling trx, but without returning a result }
ITrxExecNoRes = interface(ITransaction)['{5E4DCDBA-8CB0-45E4-8DC3-6CD859DB4F1B}']
procedure Execute(aMgr: ITransactionManager);
end; { ITrxExecNoRes }
{ the "Queen" }
IPresenterMain = interface(ICorba)['{736B14F8-8BB7-4F5D-ADAA-B90A1735765C}']
function get_Model: IModelMain;
function get_Provider: IobsProvider;
function get_TrxMan: ITransactionManager;
procedure set_Provider(aValue: IobsProvider);
procedure GetStaticTexts(const aSection: string);
procedure RefreshTextCache(const aSection,aLangStr: string);
property Model: IModelMain read get_Model; // TODO: write set_Model;
property Provider: IobsProvider read get_Provider write set_Provider;
property TrxMan: ITransactionManager read get_TrxMan;
end; { IPresenterMain }
{ the "BigSister" }
IPresenterConfigure = interface(ICorba)['{C948C2C9-2590-4030-B8B3-54B44AEB06F9}']
function get_Model: IModelConfigure;
function get_Provider: IobsProvider;
function get_TrxMan: ITransactionManager;
procedure set_Provider(aValue: IobsProvider);
procedure GetStaticTexts(const aSection: string);
procedure RefreshTextCache(const aSection,aLangStr: string);
property Model: IModelConfigure read get_Model; // TODO: write set_Model;
property Provider: IobsProvider read get_Provider write set_Provider;
property TrxMan: ITransactionManager read get_TrxMan;
end; { IPresenterPresenterMain }
{ this is the 'contract' the view has to fulfill, for us to work with it }
IViewMain = interface(ICorba)['{5AC3C283-C7EB-437D-8A72-3A0BD7A47B1C}']
function get_Observer: IobsSubscriber;
function get_Presenter: IPresenterMain;
procedure set_Observer(aValue: IobsSubscriber);
procedure set_Presenter(aValue: IPresenterMain);
procedure HandleObsNotify(aReason: ptrint; aNotifyObj: TObject; aData: pointer);
{ mainly here for when implementing console-views for the same back-end / engine }
procedure Show; // TForm implements it too
property Observer: IobsSubscriber read get_Observer write set_Observer;
property Presenter: IPresenterMain read get_Presenter write set_Presenter;
end; { IViewMain }
{ this is the 'contract' the view has to fulfill, for us to work with it }
IViewConfigure = interface(ICorba)['{07D9D3BE-8426-4E7A-BC7F-5AC0BBD70803}']
function get_Observer: IobsSubscriber;
function get_Presenter: IPresenterConfigure;
procedure set_Observer(aValue: IobsSubscriber);
procedure set_Presenter(aValue: IPresenterConfigure);
procedure HandleObsNotify(aReason: ptrint; aNotifyObj: TObject; aData: pointer);
{ mainly here for when implementing console-views for the same back-end / engine }
procedure Show; // TForm implements it too
property Observer: IobsSubscriber read get_Observer write set_Observer;
property Presenter: IPresenterConfigure read get_Presenter write set_Presenter;
end; { IViewConfigure }
{$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 RegisterMainSection(const aSect: string);
procedure RegisterConfigureSection(const aSect: string);
{ gets called from model.main.constructor to update the 'Sects' array }
procedure UpdateMainSections(var anArray: TStringArray); // <- - needs 'sysutils' added in top-uses
procedure UpdateConfigureSections(var anArray: TStringArray);
implementation
uses contnrs;
var { storage for our registrations till the models come online }
QSections,ConfSections: TQueue;
procedure RegisterMainSection(const aSect: string);
begin
if aSect = '' then exit; { no empty allocations }
QSections.Push(strnew(pchar('['+aSect+']'))); { enqueue the [section] for later update }
end;
procedure RegisterConfigureSection(const aSect: string);
begin
if aSect = '' then exit; { no empty allocations }
ConfSections.Push(strnew(pchar('['+aSect+']'))); { enqueue the [section] for later update }
end;
procedure UpdateMainSections(var anArray: TStringArray);
var lai: integer; lp: pchar = nil;
begin
if anArray = nil then exit; { we want at least '[view.main]' @ idx 0 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 UpdateConfigureSections(var anArray: TStringArray);
var lai: integer; lp: pchar = nil;
begin
if anArray = nil then exit; { we want at least '[view.configure]' @ idx 0 present before we start }
lai:= length(anArray); // start index for additions ~ 1
SetLength(anArray,lai+ConfSections.Count); { make room for all the registered sections at once }
while ConfSections.AtLeast(1) do begin { now as long as there are items in the queue }
lp:= ConfSections.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 FinalizeQueues;
begin
while QSections.AtLeast(1) do StrDispose(QSections.Pop); { clear the main queue, jic }
QSections.Free; { free the main queue }
while ConfSections.AtLeast(1) do StrDispose(ConfSections.Pop);
ConfSections.Free; { free the config queue }
end;
initialization
QSections:= TQueue.Create;
ConfSections:= TQueue.Create;
finalization
FinalizeQueues;
end.