observers, use generic type to validate

This commit is contained in:
Basile Burg 2015-12-26 12:08:25 +01:00
parent 2d0b493783
commit e3831ac404
3 changed files with 22 additions and 68 deletions

View File

@ -22,7 +22,7 @@ type
* Each project format has its own dedicated editors.
* A few common properties allow some generic operations whatever is the format.
*)
ICECommonProject = interface
ICECommonProject = interface(ISubjectType)
['ICECommonProject']
// general properties ------------------------------------------------------
@ -90,7 +90,7 @@ type
(**
* An implementer declares some actions on demand.
*)
ICEContextualActions = interface
ICEContextualActions = interface(ISubjectType)
['ICEContextualActions']
// declares a context name for the actions
function contextName: string;
@ -105,7 +105,7 @@ type
(**
* An implementer is informed about the current file(s).
*)
ICEMultiDocObserver = interface
ICEMultiDocObserver = interface(ISubjectType)
['ICEMultiDocObserver']
// aDoc has been created (empty, runnable, project source, ...).
procedure docNew(aDoc: TCESynMemo);
@ -119,17 +119,14 @@ type
(**
* An implementer informs some ICEMultiDocObserver about the current file(s)
*)
TCEMultiDocSubject = class(TCECustomSubject)
protected
function acceptObserver(aObject: TObject): boolean; override;
end;
TCEMultiDocSubject = specialize TCECustomSubject<ICEMultiDocObserver>;
(**
* An implementer is informed about the current project(s).
*)
ICEProjectObserver = interface
ICEProjectObserver = interface(ISubjectType)
['ICEProjectObserver']
// aProject has been created/opened
procedure projNew(aProject: ICECommonProject);
@ -145,17 +142,14 @@ type
(**
* An implementer informs some ICEProjectObserver about the current project(s)
*)
TCEProjectSubject = class(TCECustomSubject)
protected
function acceptObserver(aObject: TObject): boolean; override;
end;
TCEProjectSubject = specialize TCECustomSubject<ICEProjectObserver>;
(**
* An implementer can add a main menu entry.
*)
ICEMainMenuProvider = interface
ICEMainMenuProvider = interface(ISubjectType)
['ICEMainMenuProvider']
// item is a new mainMenu entry. item must be filled with the sub-items to be added.
procedure menuDeclare(item: TMenuItem);
@ -165,10 +159,7 @@ type
(**
* An implementer collects and updates its observers menus.
*)
TCEMainMenuSubject = class(TCECustomSubject)
protected
function acceptObserver(aObject: TObject): boolean; override;
end;
TCEMainMenuSubject = specialize TCECustomSubject<ICEMainMenuProvider>;
@ -176,7 +167,7 @@ type
* An implementer declares some actions which have their own main menu entry and
* whose shortcuts are automatically handled
*)
ICEActionProvider = interface
ICEActionProvider = interface(ISubjectType)
['ICEActionProvider']
// the action handler will clear the references to the actions collected previously and start collecting if result.
function actHandlerWantRecollect: boolean;
@ -190,17 +181,14 @@ type
(**
* An implementer handles its observers actions.
*)
TCEActionProviderSubject = class(TCECustomSubject)
protected
function acceptObserver(aObject: TObject): boolean; override;
end;
TCEActionProviderSubject = specialize TCECustomSubject<ICEActionProvider>;
(**
* An implementer can expose some customizable shortcuts to be edited in a dedicated widget.
*)
ICEEditableShortCut = interface
ICEEditableShortCut = interface(ISubjectType)
['ICEEditableShortCut']
// a TCEEditableShortCutSubject will start to collect shortcuts if result
function scedWantFirst: boolean;
@ -212,10 +200,7 @@ type
(**
* An implementer manages its observers shortcuts.
*)
TCEEditableShortCutSubject = class(TCECustomSubject)
protected
function acceptObserver(aObject: TObject): boolean; override;
end;
TCEEditableShortCutSubject = specialize TCECustomSubject<ICEEditableShortCut>;
@ -227,7 +212,7 @@ type
(**
* An implementer can expose some options to be edited in a dedicated widget.
*)
ICEEditableOptions = interface
ICEEditableOptions = interface(ISubjectType)
['ICEEditableOptions']
// the widget wants the category.
function optionedWantCategory(): string;
@ -243,10 +228,7 @@ type
(**
* An implementer displays its observers editable options.
*)
TCEEditableOptionsSubject = class(TCECustomSubject)
protected
function acceptObserver(aObject: TObject): boolean; override;
end;
TCEEditableOptionsSubject = specialize TCECustomSubject<ICEEditableOptions>;
@ -377,11 +359,6 @@ type
implementation
{$REGION TCEMultiDocSubject ----------------------------------------------------}
function TCEMultiDocSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(aObject is ICEMultiDocObserver);
end;
procedure subjDocNew(aSubject: TCEMultiDocSubject; aDoc: TCESynMemo);
var
i: Integer;
@ -416,11 +393,6 @@ end;
{$ENDREGION}
{$REGION TCEProjectSubject -----------------------------------------------------}
function TCEProjectSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(aObject is ICEProjectObserver);
end;
procedure subjProjNew(aSubject: TCEProjectSubject; aProj: ICECommonProject);
var
i: Integer;
@ -462,28 +434,6 @@ begin
end;
{$ENDREGION}
{$REGION Misc subjects ---------------------------------------------------------}
function TCEMainMenuSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(aObject is ICEMainMenuProvider);
end;
function TCEEditableShortCutSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(aObject is ICEEditableShortCut);
end;
function TCEEditableOptionsSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(aObject is ICEEditableOptions);
end;
function TCEActionProviderSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(aObject is ICEActionProvider);
end;
{$ENDREGION}
{$REGION ICESingleService getters ----------------------------------------------}
function getMessageDisplay(var obj: ICEMessagesDisplay): ICEMessagesDisplay;
begin

View File

@ -68,15 +68,19 @@ type
procedure updateObservers;
end;
// Base type for an interface that contains the methods of a subject.
ISubjectType = interface
end;
(**
* Standard implementation of an ICESubject.
* Any descendant adds itself to the global EntitiesConnector.
*)
TCECustomSubject = class(ICESubject)
generic TCECustomSubject<T:ISubjectType> = class(ICESubject)
protected
fObservers: TObjectList;
// test for a specific interface when adding an observer.
function acceptObserver(aObject: TObject): boolean; virtual;
function acceptObserver(aObject: TObject): boolean;
function getObserversCount: Integer;
function getObserver(index: Integer): TObject;
public
@ -242,7 +246,7 @@ end;
function TCECustomSubject.acceptObserver(aObject: TObject): boolean;
begin
exit(False);
exit(aObject is T);
end;
function TCECustomSubject.getObserversCount: Integer;

View File

@ -106,7 +106,7 @@ type
fFocusForInput: boolean;
fIdentifier: string;
fTempFileName: string;
fMultiDocSubject: TCECustomSubject;
fMultiDocSubject: TObject;
fDefaultFontSize: Integer;
fPositions: TCESynMemoPositions;
fMousePos: TPoint;