bogdanpolak / command-delphi Goto Github PK
View Code? Open in Web Editor NEWCommand pattern for Delphi (IComand & TComand)
License: MIT License
Command pattern for Delphi (IComand & TComand)
License: MIT License
Clone version_bumper
and adopt to this project
Updated main README with:
Build prototype test suite for TAsyncCommand. Problems:
Cleanup
command-delphi/src/Vcl.Pattern.Command.pas
Lines 48 to 53 in 9b3aa73
type
TCommandVclFactory = class(TComponent)
// ...
class function CreateCommand<T: TCommand>(AOwner: TComponent;
const Injections: array of const = []): T;
TCommandAction
: SetupSomething
=> WithSomething
Methods list:
SetupCaption
=> WithCaption
SetupCommand
=> WithCommand
SetupShortCut
=> WithShortCut
SetupEventOnUpdate
=> WithEventOnUpdate
SetupEventAfterExecution
=> WithEventAfterExecution
Inject
=> WithInjection
function TCommandAction.SetupEventOnUpdate (TProc<TCommandAction>): TCommandAction;
Button2.Action := TCommandAction.Create(Self)
.SetupCaption('Run command: Button2')
.SetupCommand(TSampleCommand.Create(Self))
.SetupShotcut( TextToShortCut('CTRL+K') )
.SetupEventOnUpdate(procedure (act: TComanndAction)
begin
act.Enable := (Memo1.Lines > 1)
end)
.InjectToCommand([Memo1, Edit1])
);
Remove release date from:
Change ReleaseVersion
to Version
in:
Add siganture to:
Update sample project (folder samples
) to Updated demo do new API
Read article and test with TActionCommand
:
Runtime assigned action's ShortCut does not fire in custom component
actual:
TAsyncCommand = class (TCommand)
procedure DoPrepare; override;
procedure DoTeardown; override;
refactor to:
TAsyncCommand = class (TCommand)
procedure WithEventBeforeStart(TProc)
procedure WithEventAfterFinish(TProc)
(Review current documentation and add missing points)
List:
TComponent
solution using owner.SetupCaption
=> WithCaption
SetupCommand
=> WithCommand
SetupShortCut
=> WithShortCut
SetupEventOnUpdate
=> WithEventOnUpdate
SetupEventAfterExecution
=> WithEventAfterExecution
Inject
=> WithInjection
TAsyncCommand
events:
fThread.NameThreadForDebugging('TAsyncCommand - '+Self.ClassName);
TAsyncCommand
- OnUpdate with TTimer
Select one o variant (A - E) from #1
Add:
TAsyncCommand.Terminate: boolean
type
TCommand = class
function GetElapsedTime: TTimeSpan;
function GetElapsedTimeMs: Integer;
Allow to inject inherited classes.
Remove command construction code from: TCommandVclFactory
class:
move to TCommand
class
TCommandVclFactory.CreateCommand<TMyCommand>(Owner,[injections...])
TMyCommand.CreateAndInject(Owner,[injections...])
TCommandVclFactory.ExecuteCommand<TMyCommand>([injections...]);
TCommand.Execute<TMyCommand>([injections...]);
(maybe saperate units too) - now is too early IMHO
Allow to inject: integer, word, double, boolean,
SetupCaption
=> WithCaption
SetupCommand
=> WithCommand
SetupShortCut
=> WithShortCut
SetupEventOnUpdate
=> WithEventOnUpdate
SetupEventAfterExecution
=> WithEventAfterExecution
Inject
=> WithInjection
Update samples and doc
See #22 for more references
As a developer, I want to:
Update properties in unit Tests.TCommandFactory
in class: TAdvancedCommand = class(TCommand)
TStrings
and TStream
isPrime
methodProcessNonPrimeNumbers: boolean
TClassPropertyList.Create(AnyComponentObject);
Name: TComponentName
Tag: NativeInt
TAsyncCommand = class (TCommand)
procedure WithEventOnProgress(TProc)
property ProgressInterval: integer;
function GetElapsedTime: TTimeSpan;
Add diagnostics to TAsyncCommand:
uses System.Diagnostics
fStopwatch: TStopwatch;
File: Readme.md
function TAsyncCommand.IsTerminated: boolean;
Result := TThread.CheckTerminated;
end;
variant A
// function InjectProperty(const APropertyName String; Value:Variant): TInjectRec;
Button2.Action := TCommandVclFactory.CreateCommandAction<TButon2Command>(Self,
'Run command: Button2', [InjectProperty('Memo', Memo1),
InjectProperty('Edit', Edit1)]);
variant B
// TIjector = class
// function InjectProperty(APropertyName, Value): TIjector;
Button2.Action := TCommandVclFactory.CreateCommandAction<TButon2Command>(Self,
'Run command: Button2', TIjector.Create.InjectProperty('Memo', Memo1)
.InjectProperty('Edit', Edit1));
variant C
Button2.Action := TCommandVclFactory.CreateCommandAction<TButon2Command>(Self,
'Run command: Button2', ['Memo','Edit'], [Memo1,Edit1]);
variant D
Button2.Action := TCommandVclFactory.CreateCommandAction<TButon2Command>(Self,
'Run command: Button2', [['property.Memo',Memo1],['Edit',Edit1]]);
function TAsyncCommand.Synchronize(aThreadMethod: TThreadMethod;
usage:
Synchronize(procedure
begin
fProgressBar.Position := i + 1;
end);
procedure DoGuard;
shouldn't be mandatory to implement in TCommand
and in TAsyncCommand
. Like in sample bellow:
type
TSamapleCommand
protected
procedure DoExecute; override;
end;
TAsyncCommand
unit:
Pattern.Command.pas
==> Pattern.AsyncCommand.pas
Extract:
TDiceRollCommand
and TAsyncDiceRollCommand
to separate demoDUnitxCommand.dpr
⇒ TestCommandPattern.dpr
Tests.TCommandFactory.pas
⇒ Tests.TCommand.pas
TestCommndFactory_BasicCommand
⇒ TestBasicCommnd
TestCommndFactory_StrigListCommand
⇒ TestStrigListCommnd
TestCommndFactory_AdvancedCommand
⇒ TestAdvancedCommnd
See TODO in comment:
procedure TAsyncCommand.Execute;
begin
DoGuard;
DoPrepare;
fIsWorking := True;
TThread.CreateAnonymousThread(
procedure
begin
DoExecute;
// TODO: lock or critical section is required bellow (critical !!!)
fIsWorking := True;
end);
end;
Refactor component publised properties
Requires #5 to be closed
Check:
System.EAssertionFailed
exception if no required exection was provided (use TCommandStringList class)TStringList
published properties (some variants: eg. change injection order)TStringList
and TComponent
published properties betweenfunction TAsyncCommand.WithInjections(const Injections: array of const): TCommand;
begin
TComponentInjector.InjectProperties(Self, Injections);
Result := Self;
end;
type TAsyncCommand = class(TCommand)
property ThreadSafeObject: TObject
read GetThreadSafeObject
write SetThreadSafeObject;
function TAsyncCommand GetThreadSafeObject: TObject;
begin
TMonitor.Enter(Self);
try
Result := fThreadSafeObject;
finally
TMonitor.Exit(Self);
end;
end;
Allow to inject inherited class, example:
type
TMyComponent = class(TComponent)
strict private
FStrings: TStrings;
published
property Strings: TStrings read FStrings write FStrings;
end;
allow to inject:
var aComponent := TMyComponent.Create(aOwner);
var aStringList := TStringList.Create;
TComponentInjector.InjectProperties(aComponent, [aStringList]);
Assert (aComponent.Strings = aStringList);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.