123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668 |
- { TObservers }
- function TObservers.CanObserve(const aID: Integer): Boolean;
- begin
- Result:=Assigned(FCanObserve) and FCanObserve(aID);
- end;
- procedure TObservers.AddObserver(const aID: Integer; const aIntf: IInterface);
- var
- I : integer;
- P : PIDArray;
- O : IObserver;
- E : IEditLinkObserver;
- begin
- if not Supports(aIntf,IObserver,O) then
- raise EObserverException.Create(SErrNotIObserverInterface);
- if not CanObserve(aID) then
- raise EObserverException.Create(SErrUnsupportedObserver);
- P:=FList.GetIDArrayFromID(aId);
- if P=Nil then
- FList.AddInterface(aID,aIntf)
- else
- begin
- if not Supports(aIntf,ISingleCastObserver) then
- P^.Add(aIntf)
- else
- begin
- if Supports(aIntf,IEditLinkObserver,E) and Not E.IsReadOnly then
- begin
- // There can be only one editing link observer.
- For I:=0 to P^.Count-1 do
- if Supports(P^.List[I],IEditLinkObserver,E) then
- if not E.IsReadOnly then
- Raise EObserverException.Create(SErrOnlyOneEditingObserverAllowed)
- end;
- P^.Add(aIntf)
- end;
- end;
- if Assigned(FObserverAdded) then
- FObserverAdded(aId,O);
- end;
- procedure TObservers.AddObserver(const aIDs: array of Integer; const aIntf: IInterface);
- var
- aID : integer;
- begin
- for aID in aIDs do
- AddObserver(aId,aIntf);
- end;
- procedure TObservers.RemoveObserver(const aID: Integer; const aIntf: IInterface);
- var
- P : PIDArray;
- begin
- P:=FList.GetIDArrayFromID(aID);
- if P=Nil then
- exit;
- P^.Remove(aIntf);
- end;
- procedure TObservers.RemoveObserver(const aIDs: array of Integer; const aIntf: IInterface);
- var
- aID : integer;
- begin
- for aID in aIDs do
- RemoveObserver(aId,aIntf);
- end;
- function TObservers.IsObserving(const aID: Integer): Boolean;
- var
- O : IInterface;
- begin
- Result:=TryIsObserving(aID,O);
- end;
- function TObservers.TryIsObserving(const aID: Integer; out aIntf: IInterface): Boolean;
- var
- P : PIDArray;
- begin
- aIntf:=Nil;
- Result:=False;
- P:=FList.GetIDArrayFromID(aID);
- if P=Nil then
- exit;
- aIntf:=P^.GetActive;
- Result:=aIntf<>Nil;
- end;
- function TObservers.GetSingleCastObserver(const aID: Integer): IInterface;
- var
- P : PIDArray;
- begin
- Result:=Nil;
- P:=FList.GetIDArrayFromID(aID);
- if P<>Nil then
- Result:=P^.GetSingleCast;
- if Result=Nil then
- raise EObserverException.CreateFmt(SErrObserverNoSinglecast, [aID]);
- end;
- function TObservers.GetMultiCastObserverArray(const aID: Integer): TIInterfaceArray;
- var
- aCount, I : Integer;
- P : PIDArray;
- O : IObserver;
- begin
- Result:=[];
- P:=FList.GetIDArrayFromId(aId);
- if P=Nil then
- exit;
- SetLength(Result,P^.Count);
- aCount:=0;
- for I:=0 to P^.Count-1 do
- if Supports(P^.List[I],IMultiCastObserver,O) then
- if O.Active then
- begin
- Result[aCount]:=O;
- Inc(aCount);
- end;
- SetLength(Result,aCount);
- if aCount=0 then
- raise EObserverException.CreateFmt(SerrObserverNoMulticastFound, [aID]);
- end;
- function TObservers.GetMultiCastObserver(const aID: Integer): IInterfaceList;
- Var
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- begin
- Result:=TInterfaceList.Create;
- IntfArray:=GetMultiCastObserverArray(aId);
- For Intf in IntfArray do
- Result.Add(Intf);
- end;
- { TObservers.TIDArray }
- procedure TObservers.TIDArray.Add(const aInterface: IInterface);
- begin
- if Count=Length(List) then
- SetLength(List,Count+10);
- List[Count]:=aInterface;
- Inc(Count);
- end;
- procedure TObservers.TIDArray.Remove(const aInterface: IInterface);
- var
- I : Integer;
- begin
- I:=Count-1;
- While (I>=0) and (List[i]<>aInterface) do
- Dec(I);
- if (I>=0) then
- List[i]:=Nil;
- end;
- function TObservers.TIDArray.GetActive: IObserver;
- var
- I : integer;
- begin
- Result:=Nil;
- I:=Count-1;
- While (Result=Nil) and (I>=0) do
- begin
- if Supports(List[I],IObserver,Result) then
- if Not Result.Active then
- Result:=nil;
- Dec(I);
- end;
- end;
- function TObservers.TIDArray.GetSingleCast: ISingleCastObserver;
- var
- I : Integer;
- E : IEditLinkObserver;
- begin
- Result:=Nil;
- I:=Count-1;
- While (Result=Nil) and (I>=0) do
- begin
- Result:=nil;
- if Supports(List[I],ISingleCastObserver,Result) then
- begin
- if Not (Result.Active
- and Supports(Result,IEditLinkObserver,E)
- and not E.IsReadOnly) then
- Result:=nil;
- end;
- Dec(I);
- end;
- end;
- { TObservers.TIDArrayList }
- function TObservers.TIDArrayList.IndexOfID(aId: Integer): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (List[Result].ID<>aID) do
- Dec(Result);
- end;
- function TObservers.TIDArrayList.AddID(aId: Integer): Integer;
- begin
- if Count=Length(List) then
- SetLength(List,Count+10);
- List[Count].ID:=aID;
- Result:=Count;
- Inc(Count);
- end;
- procedure TObservers.TIDArrayList.AddInterface(aID: integer;
- aInterFace: IInterface);
- var
- Idx : Integer;
- P : PIDarray;
- begin
- Idx:=AddID(aID);
- P:=GetIDArray(Idx);
- P^.Add(aInterface);
- end;
- function TObservers.TIDArrayList.GetIDArray(aIdx: Integer): PIDArray;
- begin
- Result:=@List[aIdx];
- end;
- function TObservers.TIDArrayList.GetIDArrayFromID(aId: Integer): PIDArray;
- var
- Idx : Integer;
- begin
- Result:=Nil;
- Idx:=IndexOfID(aId);
- if Idx<>-1 then
- Result:=GetIDArray(Idx);
- end;
- { TLinkObservers }
- class function TLinkObservers.CheckObserving(const aObservers: TObservers; aID : Integer) : Integer;
- begin
- Result:=aID;
- if Not aObservers.IsObserving(aID) then
- raise EObserverException.CreateFmt(SErrObserverNotAvailable,[aID]);
- end;
- class function TLinkObservers.GetEditGridLink(const aObservers: TObservers): IEditGridLinkObserver;
- var
- aId: Integer;
- begin
- aId:=CheckObserving(aObservers, TObserverMapping.EditGridLinkID);
- Result:=aObservers.GetSingleCastObserver(aID) as IEditGridLinkObserver;
- end;
- class function TLinkObservers.GetEditLink(const aObservers: TObservers): IEditLinkObserver;
- var
- aId: Integer;
- begin
- aId:=CheckObserving(aObservers,TObserverMapping.EditLinkID);
- Result:=aObservers.GetSingleCastObserver(aID) as IEditLinkObserver;
- end;
- class procedure TLinkObservers.EditLinkUpdate(const aObservers: TObservers);
- begin
- GetEditLink(AObservers).Update;
- end;
- class function TLinkObservers.EditLinkTrackUpdate(const aObservers: TObservers): Boolean;
- var
- E : IEditLinkObserver;
- T : IObserverTrack;
- begin
- Result:=False;
- E:=GetEditLink(aObservers);
- if Supports(E,IObserverTrack,T) then
- if T.Track then
- begin
- Result:=true;
- E.Update;
- end;
- end;
- class procedure TLinkObservers.EditLinkReset(const aObservers: TObservers);
- begin
- GetEditLink(AObservers).Reset;
- end;
- class procedure TLinkObservers.EditLinkModified(aObservers: TObservers);
- begin
- GetEditLink(aObservers).Modified;
- end;
- class function TLinkObservers.EditLinkIsModified(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditLink(aObservers).IsModified;
- end;
- class function TLinkObservers.EditLinkIsValidChar(const aObservers: TObservers; aKey: Char): Boolean;
- begin
- Result:=GetEditLink(aObservers).IsValidChar(aKey);
- end;
- class function TLinkObservers.EditLinkIsEditing(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditLink(aObservers).IsEditing;
- end;
- class function TLinkObservers.EditLinkEdit(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditLink(aObservers).Edit;
- end;
- class procedure TLinkObservers.EditLinkSetIsReadOnly(const aObservers: TObservers; AValue: Boolean);
- begin
- GetEditLink(aObservers).IsReadOnly:=aValue;
- end;
- class function TLinkObservers.EditLinkIsReadOnly(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditLink(aObservers).IsReadOnly;
- end;
- class procedure TLinkObservers.EditGridLinkUpdate(const aObservers: TObservers);
- begin
- GetEditGridLink(aObservers).Update;
- end;
- class procedure TLinkObservers.EditGridLinkReset(const aObservers: TObservers);
- begin
- GetEditGridLink(aObservers).Reset;
- end;
- class procedure TLinkObservers.EditGridLinkModified(const aObservers: TObservers
- );
- begin
- GetEditGridLink(aObservers).Modified;
- end;
- class function TLinkObservers.EditGridLinkIsModified(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditGridLink(aObservers).IsModified;
- end;
- class function TLinkObservers.EditGridLinkIsValidChar(const aObservers: TObservers; aKey: Char): Boolean;
- begin
- Result:=GetEditGridLink(aObservers).IsValidChar(aKey);
- end;
- class function TLinkObservers.EditGridLinkIsEditing(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditGridLink(aObservers).IsEditing
- end;
- class function TLinkObservers.EditGridLinkEdit(const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditGridLink(aObservers).Edit;
- end;
- class function TLinkObservers.EditGridLinkIsReadOnly(
- const aObservers: TObservers): Boolean;
- begin
- Result:=GetEditGridLink(aObservers).IsReadOnly;
- end;
- class procedure TLinkObservers.EditGridLinkSetIsReadOnly(const aObservers: TObservers; aValue: Boolean);
- begin
- GetEditGridLink(aObservers).IsReadOnly:=aValue
- end;
- class procedure TLinkObservers.PositionLinkPosChanged(const aObservers: TObservers);
- var
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- PL: IPositionLinkObserver;
- PL170: IPositionLinkObserver170;
- begin
- if Not aObservers.IsObserving(TObserverMapping.PositionLinkID) then
- Exit;
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.PositionLinkID);
- for Intf in IntfArray do
- begin
- if Supports(Intf,IPositionLinkObserver,PL) then
- PL.PosChanged;
- if Supports(Intf,IPositionLinkObserver170,PL170) then
- PL.PosChanged;
- end;
- end;
- class procedure TLinkObservers.PositionLinkPosChanging(const aObservers: TObservers);
- var
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- PL: IPositionLinkObserver;
- PL170: IPositionLinkObserver170;
- begin
- if Not aObservers.IsObserving(TObserverMapping.PositionLinkID) then
- Exit;
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.PositionLinkID);
- for Intf in IntfArray do
- begin
- if Supports(Intf,IPositionLinkObserver,PL) then
- PL.PosChanging;
- if Supports(Intf,IPositionLinkObserver170,PL170) then
- PL.PosChanging;
- end;
- end;
- class procedure TLinkObservers.ListSelectionChanged(const aObservers: TObservers);
- begin
- if AObservers.IsObserving(TObserverMapping.EditLinkID) then
- if not TLinkObservers.EditLinkIsEditing(aObservers) then
- EditLinkReset(AObservers)
- else
- begin
- EditLinkModified(aObservers);
- EditLinkTrackUpdate(aObservers);
- PositionLinkPosChanged(aObservers);
- end;
- if aObservers.IsObserving(TObserverMapping.ControlValueID) then
- begin
- ControlValueModified(aObservers);
- ControlValueTrackUpdate(aObservers);
- end;
- if aObservers.IsObserving(TObserverMapping.PositionLinkID) then
- PositionLinkPosChanged(aObservers);
- end;
- class procedure TLinkObservers.ControlValueUpdate(aObservers: TObservers);
- var
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- O: IControlValueObserver;
- begin
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.ControlValueID);
- for Intf in IntfArray do
- if Supports(Intf,IControlValueObserver,O) then
- O.ValueUpdate;
- end;
- class procedure TLinkObservers.ControlValueModified(aObservers: TObservers);
- var
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- O: IControlValueObserver;
- begin
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.ControlValueID);
- for Intf in IntfArray do
- if Supports(Intf,IControlValueObserver,O) then
- O.ValueModified;
- end;
- class function TLinkObservers.ControlValueTrackUpdate(const aObservers: TObservers): Boolean;
- var
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- O: IControlValueObserver;
- T : IObserverTrack;
- begin
- Result:=False;
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.ControlValueID);
- for Intf in IntfArray do
- if Supports(Intf,IControlValueObserver,O)
- And Supports(O,IObserverTrack,T) then
- if T.Track then
- begin
- Result:=true;
- O.ValueUpdate;
- end;
- end;
- class function TLinkObservers.AllowControlChange(const aObservers: TObservers): Boolean;
- begin
- if aObservers.IsObserving(TObserverMapping.EditLinkID) then
- Result:=TLinkObservers.EditLinkEdit(aObservers)
- else
- Result := True;
- end;
- class procedure TLinkObservers.ControlChanged(const aObservers: TObservers);
- begin
- if (aObservers.IsObserving(TObserverMapping.EditLinkID))
- and EditLinkEdit(aObservers) then
- begin
- EditLinkModified(aObservers);
- EditLinkUpdate(aObservers);
- end;
- if aObservers.IsObserving(TObserverMapping.ControlValueID) then
- begin
- ControlValueModified(aObservers);
- ControlValueUpdate(aObservers);
- end;
- if aObservers.IsObserving(TObserverMapping.PositionLinkID) then
- PositionLinkPosChanged(aObservers);
- end;
- class function TLinkObservers.AllowControlChange(const aControl: TComponent): Boolean;
- begin
- AllowControlChange(aControl.Observers);
- end;
- class procedure TLinkObservers.ControlChanged(const aControl: TComponent);
- begin
- ControlChanged(aControl.Observers);
- end;
- class procedure TLinkObservers.IteratorLinkUpdateControlComponent(const aObservers: TObservers; aControl: TComponent);
- var
- O : IIteratorLinkObserver;
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- begin
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.IteratorLinkID);
- for Intf in IntfArray do
- if Supports(Intf,IIteratorLinkObserver,O) then
- O.UpdateControlComponent(aControl);
- end;
- class procedure TLinkObservers.IteratorLinkStartFrom(const aObservers: TObservers; aPosition: Integer);
- var
- O : IIteratorLinkObserver;
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- begin
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.IteratorLinkID);
- for Intf in IntfArray do
- if Supports(Intf,IIteratorLinkObserver,O) then
- O.StartFrom(aPosition);
- end;
- class function TLinkObservers.IteratorLinkMoveNext(const aObservers: TObservers): Boolean;
- var
- O : IIteratorLinkObserver;
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- begin
- Result:=false;
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.IteratorLinkID);
- for Intf in IntfArray do
- if Supports(Intf,IIteratorLinkObserver,O) then
- Result:=Result or O.MoveNext;
- end;
- class procedure TLinkObservers.IteratorLinkFinish(const aObservers: TObservers);
- var
- O : IIteratorLinkObserver;
- IntfArray : TIInterfaceArray;
- Intf : IInterface;
- begin
- IntfArray:=aObservers.GetMultiCastObserverArray(TObserverMapping.IteratorLinkID);
- for Intf in IntfArray do
- if Supports(Intf,IIteratorLinkObserver,O) then
- O.Finish;
- end;
- { TObserverMapping }
- constructor TObserverMapping.Create;
- begin
- FList:=TStringList.Create;
- // Don't use sorted, as it will change the IDs as more records are added
- end;
- destructor TObserverMapping.Destroy;
- begin
- FreeAndNil(FList);
- inherited Destroy;
- end;
- class constructor TObserverMapping.Init;
- begin
- _Instance:=TObserverMapping.Create;
- end;
- class destructor TObserverMapping.Done;
- begin
- FreeAndNil(_Instance)
- end;
- class function TObserverMapping.GetObserverID(const aKey: string): Integer;
- begin
- Result:=Instance.List.Indexof(aKey);
- if Result=-1 then
- Result:=Instance.List.Add(aKey);
- Result:=Result+MinPublicID;
- end;
- class procedure TObserverMapping.Clear;
- begin
- Instance.List.Clear;
- end;
- constructor ObservableMemberAttribute.Create(const aMemberName, aFramework: string; aTrack: Boolean);
- begin
- inherited Create;
- FFramework := AFramework;
- FMemberName := AMemberName;
- FTrack := ATrack;
- end;
- constructor ObservableMemberAttribute.Create(const aMemberName: string; aTrack: Boolean);
- begin
- inherited Create;
- FMemberName := AMemberName;
- FTrack := ATrack;
- end;
- constructor ObservableMemberAttribute.Create(const aMemberName: string);
- begin
- inherited Create;
- FMemberName := AMemberName;
- end;
|