Skip to content

Commit

Permalink
New BoldClassSubscriber component #20
Browse files Browse the repository at this point in the history
  • Loading branch information
bero committed Dec 6, 2024
1 parent 292c79c commit dfcf19f
Show file tree
Hide file tree
Showing 2 changed files with 390 additions and 0 deletions.
277 changes: 277 additions & 0 deletions Source/BoldClassSubscriber.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
unit BoldClassSubscriber;

interface

uses
Classes,
BoldHandles,
BoldSubscription,
BoldSystemRT,
BoldSystem;

type
TBoldClassSubscriber = class;
TBoldClassEventMapping = class;
TBoldClassEventMappingCollection = class;
TEventMappingEnumerator = class;

TBoldClassSubscriptionEvent = procedure (AClassList: TBoldObjectList; ASubscriber: TBoldSubscriber) of object;

TBoldClassEventMapping = class(TCollectionItem)
private
fSubscriber: TBoldExtendedPassthroughSubscriber;
fClassTypeName: string;
fOnChange: TBoldExtendedEventHandler;
fOnSubscribe: TBoldClassSubscriptionEvent;
procedure SetClassTypeName(const Value: string);
function GetStaticSystemTypeInfo: TBoldSystemTypeInfo;
function GetCollection: TBoldClassEventMappingCollection;
procedure SetOnSubscribe(const Value: TBoldClassSubscriptionEvent);
procedure _Receive(Originator: TObject; OriginalEvent: TBoldEvent; RequestedEvent: TBoldRequestedEvent; const args: array of const);
function GetBoldSystem: TBoldSystem;
protected
function GetDisplayName: string; override;
property Collection: TBoldClassEventMappingCollection read GetCollection;
procedure PlaceSubscriptions;
property Subscriber: TBoldExtendedPassthroughSubscriber read fSubscriber;
property BoldSystem: TBoldSystem read GetBoldSystem;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
property StaticSystemTypeInfo: TBoldSystemTypeInfo read GetStaticSystemTypeInfo;
procedure Assign(Source: TPersistent); override;
published
property ClassTypeName: string read fClassTypeName write SetClassTypeName;
property OnChange: TBoldExtendedEventHandler read fOnChange write fOnChange;
property OnSubscribe: TBoldClassSubscriptionEvent read fOnSubscribe write SetOnSubscribe;
end;

TBoldClassEventMappingCollection = class(TCollection)
private
fBoldEventSubscriber: TBoldClassSubscriber;
function GetItem(Index: Integer): TBoldClassEventMapping;
procedure SetItem(Index: Integer; Value: TBoldClassEventMapping);
function GetEventSubscriber: TBoldClassSubscriber;
protected
function GetOwner: TPersistent; override;
property EventSubscriber: TBoldClassSubscriber read GetEventSubscriber;
public
constructor Create(AEventSubscriber: TBoldClassSubscriber);
function Add: TBoldClassEventMapping;
function GetEnumerator: TEventMappingEnumerator;
property Items[Index: Integer]: TBoldClassEventMapping read GetItem write SetItem; default;
end;

[ComponentPlatformsAttribute (pidWin32 or pidWin64)]
TBoldClassSubscriber = class(TBoldSystemExtensionComponent)
private
fEnabled: boolean;
fMappingCollection: TBoldClassEventMappingCollection;
procedure SetEnabled(const Value: boolean);
procedure SetEventMappingCollection(const Value: TBoldClassEventMappingCollection);
protected
procedure PlaceSubscriptions; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: boolean read fEnabled write SetEnabled;
property EventMapping: TBoldClassEventMappingCollection read fMappingCollection write SetEventMappingCollection;
end;

TEventMappingEnumerator = class
private
FIndex: Integer;
FCollection: TBoldClassEventMappingCollection;
public
constructor Create(ACollection: TBoldClassEventMappingCollection);
function GetCurrent: TBoldClassEventMapping; inline;
function MoveNext: Boolean; inline;
property Current: TBoldClassEventMapping read GetCurrent;
end;

implementation

uses
System.SysUtils;

{ TBoldClassSubscriber }

constructor TBoldClassSubscriber.Create(AOwner: TComponent);
begin
inherited;
FMappingCollection := TBoldClassEventMappingCollection.Create(Self);
fEnabled:= true;
end;

destructor TBoldClassSubscriber.Destroy;
begin
FMappingCollection.free;
inherited;
end;

procedure TBoldClassSubscriber.PlaceSubscriptions;
var
BoldEventMapping: TBoldClassEventMapping;
begin
inherited;
for BoldEventMapping in FMappingCollection do
BoldEventMapping.PlaceSubscriptions;
end;

procedure TBoldClassSubscriber.SetEnabled(const Value: boolean);
begin
if fEnabled <> Value then
begin
fEnabled := Value;
PlaceSubscriptions;
end;
end;

procedure TBoldClassSubscriber.SetEventMappingCollection(
const Value: TBoldClassEventMappingCollection);
begin
fMappingCollection.Assign(Value);
end;

{ TBoldClassEventMapping }

procedure TBoldClassEventMapping.Assign(Source: TPersistent);
begin
if source is TBoldClassEventMapping then
begin
fOnChange := (Source as TBoldClassEventMapping).OnChange;
fOnSubscribe := (Source as TBoldClassEventMapping).OnSubscribe;
end
else
inherited;
end;

constructor TBoldClassEventMapping.Create(Collection: TCollection);
begin
inherited;
fSubscriber := TBoldExtendedPassthroughSubscriber.CreateWithExtendedReceive(_Receive);
end;

destructor TBoldClassEventMapping.Destroy;
begin
fSubscriber.Free;
inherited;
end;

function TBoldClassEventMapping.GetBoldSystem: TBoldSystem;
begin
result := Collection.fBoldEventSubscriber.BoldSystem;
end;

function TBoldClassEventMapping.GetCollection: TBoldClassEventMappingCollection;
begin
result := inherited Collection as TBoldClassEventMappingCollection;
end;

function TBoldClassEventMapping.GetDisplayName: string;
begin
result := fClassTypeName;
end;

function TBoldClassEventMapping.GetStaticSystemTypeInfo: TBoldSystemTypeInfo;
begin
result := nil;
if Assigned(Collection.fBoldEventSubscriber.StaticSystemHandle) then
result := Collection.fBoldEventSubscriber.StaticSystemHandle.StaticSystemTypeInfo;
if Collection.fBoldEventSubscriber.StaticSystemHandle = nil then
raise Exception.Create('StaticSystemHandle is nil');
if not Assigned(result) then
raise Exception.Create('StaticSystemTypeInfo is nil');
end;

procedure TBoldClassEventMapping.PlaceSubscriptions;
begin
fSubscriber.CancelAllSubscriptions;
if Assigned(BoldSystem) and Assigned(fOnSubscribe) then
OnSubscribe(BoldSystem.ClassByExpressionName[fClassTypeName], Subscriber);
end;

procedure TBoldClassEventMapping.SetClassTypeName(const Value: string);
begin
if fClassTypeName <> Value then
begin
fClassTypeName := Value;
PlaceSubscriptions;
end;
end;

procedure TBoldClassEventMapping.SetOnSubscribe(const Value: TBoldClassSubscriptionEvent);
begin
fOnSubscribe := Value;
end;

procedure TBoldClassEventMapping._Receive(Originator: TObject; OriginalEvent: TBoldEvent;
RequestedEvent: TBoldRequestedEvent; const args: array of const);
begin
if Assigned(OnChange) then
OnChange(Originator, OriginalEvent, RequestedEvent, args);
end;

{ TBoldClassEventMappingCollection }

function TBoldClassEventMappingCollection.Add: TBoldClassEventMapping;
begin
Result := TBoldClassEventMapping(inherited Add);
end;

constructor TBoldClassEventMappingCollection.Create(
AEventSubscriber: TBoldClassSubscriber);
begin
inherited Create(TBoldClassEventMapping);
fBoldEventSubscriber := AEventSubscriber;
end;

function TBoldClassEventMappingCollection.GetEnumerator: TEventMappingEnumerator;
begin
Result := TEventMappingEnumerator.Create(Self);
end;

function TBoldClassEventMappingCollection.GetEventSubscriber: TBoldClassSubscriber;
begin
result := owner as TBoldClassSubscriber;
end;

function TBoldClassEventMappingCollection.GetItem(Index: Integer): TBoldClassEventMapping;
begin
Result := TBoldClassEventMapping(inherited GetItem(Index));
end;

function TBoldClassEventMappingCollection.GetOwner: TPersistent;
begin
result := fBoldEventSubscriber;
end;

procedure TBoldClassEventMappingCollection.SetItem(Index: Integer;
Value: TBoldClassEventMapping);
begin
inherited SetItem(Index, Value);
end;

{ TEventMappingEnumerator }

constructor TEventMappingEnumerator.Create(
ACollection: TBoldClassEventMappingCollection);
begin
inherited Create;
FIndex := -1;
FCollection := ACollection;
end;

function TEventMappingEnumerator.GetCurrent: TBoldClassEventMapping;
begin
Result := FCollection.Items[FIndex];
end;

function TEventMappingEnumerator.MoveNext: Boolean;
begin
Inc(FIndex);
Result := FIndex < FCollection.Count;
end;

end.
113 changes: 113 additions & 0 deletions Source/BoldClassSubscriberReg.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
unit BoldClassSubscriberReg;

interface

uses
Classes,
DesignEditors,
DesignIntf,
BoldAbstractPropertyEditors,
BoldPropertyEditors;

type
TBoldClassSubscriberComponentEditor = class(TBoldComponentDblClickEditor)
protected
function GetDefaultMethodName: string; override;
public
procedure EditProperty(const PropertyEditor: IProperty; var Continue: Boolean); override;
procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;
end;

procedure Register;

implementation

uses
SysUtils,
BoldIdeConsts,
BoldClassSubscriber,
BoldElements,
BoldSystemRT,
Vcl.Controls;

type
{ TBoldTypeNameSelectorForExpressionSubscriber }
TBoldTypeNameSelectorForClassSubscriber = class(TBoldTypeNameSelectorForHandles)
protected
function GetApprovedTypes: TBoldValueTypes; override;
function GetContextType(Component: TPersistent): TBoldSystemTypeInfo; override;
end;

procedure RegisterComponentsOnPalette;
begin
RegisterComponents(BOLDPAGENAME_MISC,
[
TBoldClassSubscriber
]);
end;

procedure RegisterEditors;
begin
RegisterComponentEditor(TBoldClassSubscriber, TBoldClassSubscriberComponentEditor);
RegisterPropertyEditor(TypeInfo(String), TBoldClassEventMapping, 'ClassTypeName', TBoldTypeNameSelectorForClassSubscriber);
end;

procedure Register;
begin
RegisterComponentsOnPalette;
RegisterEditors;
end;

{ TBoldClassSubscriberComponentEditor }

procedure TBoldClassSubscriberComponentEditor.EditProperty(const PropertyEditor: IProperty; var Continue: Boolean);
begin
if PropertyEditor.GetName = 'EventMapping' then
begin
PropertyEditor.Edit;
Continue := False;
end;
end;

procedure TBoldClassSubscriberComponentEditor.ExecuteVerb(Index: Integer);
begin
inherited;
case Index of
0: Edit;
end;
end;

function TBoldClassSubscriberComponentEditor.GetDefaultMethodName: string;
begin
result := 'EventMapping';
end;

function TBoldClassSubscriberComponentEditor.GetVerb(Index: Integer): string;
begin
case Index of
0: Result := 'Edit events...';
end;
end;

function TBoldClassSubscriberComponentEditor.GetVerbCount: Integer;
begin
Result := 1;
end;

{ TBoldTypeNameSelectorForClassSubscriber }

function TBoldTypeNameSelectorForClassSubscriber.GetApprovedTypes: TBoldValueTypes;
begin
Result := [bvtClass];
end;

function TBoldTypeNameSelectorForClassSubscriber.GetContextType(Component: TPersistent): TBoldSystemTypeInfo;
begin
Assert(Component is TBoldClassEventMapping, Component.ClassName);
result := TBoldClassEventMapping(Component).StaticSystemTypeInfo;
Assert(Assigned(result));
end;

end.

0 comments on commit dfcf19f

Please sign in to comment.