Клубове Дир.бг
powered by diri.bg
търси в Клубове diri.bg Разширено търсене

Вход
Име
Парола

Клубове
Dir.bg
Взаимопомощ
Горещи теми
Компютри и Интернет
Контакти
Култура и изкуство
Мнения
Наука
Политика, Свят
Спорт
Техника
Градове
Религия и мистика
Фен клубове
Хоби, Развлечения
Общества
Я, архивите са живи
Клубове Дирене Регистрация Кой е тук Въпроси Списък Купувам / Продавам 02:27 20.06.24 
Клубове/ Компютри и Интернет / Delphi Всички теми Следваща тема Пълен преглед*
Информация за клуба
Тема Re: actions, threads, chain-of-actions [re: tikva]
Авторtikva (Нерегистриран) 
Публикувано22.06.07 14:49  



някой има ли желание да погледне и да ми направи едно кратко code review :)
видимо работи, обаче незнам дали съм сложил данните, които се ползват от main и от runner thread-а на правилното място (в случая - глобални:) и т.н.


unit ActionRunner;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, SyncObjs, ActnList;

type
TClientActionCallback = procedure (const result: boolean) of object;

{ TClientAction }

TClientAction = class
action: TAction;
callback: TClientActionCallback;

constructor Create(const a: TAction; const cbk: TClientActionCallback);
end;

TClientActionChain = array of TClientAction;

{ TClientActionRunnerThread }

TClientActionRunnerThread = class(TThread)
procedure Execute; override;

private
finished: boolean;

function GetNextInChain(): TClientAction;
end;

{ TClientActionRunner }

TClientActionRunner = class
public
constructor Create;
destructor Destroy; override;

procedure InitChain(const ch: TClientActionChain);
procedure StartChain;

procedure SetUserAction(const ua: TClientAction);

Done: procedure(Sender: TObject) of object;
private
runnerThread: TClientActionRunnerThread;
end;

var
actrunLock: TCriticalSection;
chain: TClientActionChain;
chainIndex: integer;

userAction: TClientAction;

implementation

{ TClientActionRunner }

constructor TClientActionRunner.Create;
begin
actrunLock := TCriticalSection.Create;
end;

destructor TClientActionRunner.Destroy;
begin
FreeAndNil(actrunLock);
inherited Destroy;
end;

procedure TClientActionRunner.InitChain(const ch: TClientActionChain);
begin
chain := ch;
end;

procedure TClientActionRunner.StartChain;
begin
chainIndex := -1;
runnerThread := TClientActionRunnerThread.Create(true);
runnerThread.FreeOnTerminate := true;
runnerThread.OnTerminate := Done;
runnerThread.Resume;
end;

procedure TClientActionRunner.SetUserAction(const ua: TClientAction);
begin
actrunLock.Enter;
try
userAction := ua;
chainIndex := -1;
finally
actrunLock.Leave;
end;
end;

{ TClientActionRunnerThread }

function TClientActionRunnerThread.GetNextInChain(): TClientAction;
begin
result := nil;
actrunLock.Enter;
try
if (chainIndex = -1) then
begin
if (userAction <> nil) then
begin
result := userAction;
userAction := nil;
exit;
end
end;

Inc(chainIndex);
if (chainIndex < Length(chain)) then
result := chain[chainIndex];
finally
actrunLock.Leave;
end;
end;

procedure TClientActionRunnerThread.Execute;
var
ca: TClientAction;
ok: boolean;
begin
while (not terminated) do
begin
ca := GetNextInChain();
if (ca = nil) then // no next action - i.e. chain finished
break;

ok := ca.action.Execute();
ca.callback(ok);
end;
end;

{ TClientAction }

constructor TClientAction.Create(const a: TAction;
const cbk: TClientActionCallback);
begin
action := a;
callback := cbk;
end;

end.




a това е тестовата формичка, от която се ползва:


unit chainMain;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ActnList,
StdCtrls, ExtCtrls, Buttons;

type

{ TForm1 }

TForm1 = class(TForm)
aFinishRefreshing: TAction;
aRefreshStep5: TAction;
aRefreshStep4: TAction;
aRefreshStep3: TAction;
aRefreshStep2: TAction;
aUserAction2: TAction;
aRefreshStep1: TAction;
aUserAction1: TAction;
ActionList1: TActionList;
btnUserAction1: TButton;
btnUserAction2: TButton;
Memo1: TMemo;
Timer1: TTimer;
procedure aFinishRefreshingExecute(Sender: TObject);
procedure aRefreshStep1Execute(Sender: TObject);
procedure aRefreshStep2Execute(Sender: TObject);
procedure aRefreshStep3Execute(Sender: TObject);
procedure aRefreshStep4Execute(Sender: TObject);
procedure aRefreshStep5Execute(Sender: TObject);
procedure aUserAction1Execute(Sender: TObject);
procedure aUserAction2Execute(Sender: TObject);
procedure btnUserAction1Click(Sender: TObject);
procedure btnUserAction2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ private declarations }

procedure RefreshStep1Done(const result: boolean);
procedure RefreshStep2Done(const result: boolean);
procedure RefreshStep3Done(const result: boolean);
procedure RefreshStep4Done(const result: boolean);
procedure RefreshStep5Done(const result: boolean);
procedure RefreshingDone(Sender: TObject);

procedure UserAction1Done(const result: boolean);
procedure UserAction2Done(const result: boolean);
public
{ public declarations }
end;

var
Form1: TForm1;

implementation

{ TForm1 }
uses
ActionRunner;

var
runner: TClientActionRunner;

procedure TForm1.FormShow(Sender: TObject);
var
chain: TClientActionChain;
ca: TClientAction;
begin
SetLength(chain, 5);

ca := TClientAction.Create(aRefreshStep1, @RefreshStep1Done);
chain[0] := ca;
ca := TClientAction.Create(aRefreshStep2, @RefreshStep2Done);
chain[1] := ca;
ca := TClientAction.Create(aRefreshStep3, @RefreshStep3Done);
chain[2] := ca;
ca := TClientAction.Create(aRefreshStep4, @RefreshStep4Done);
chain[3] := ca;
ca := TClientAction.Create(aRefreshStep5, @RefreshStep5Done);
chain[4] := ca;
{
ca := TClientAction.Create(aFinishRefreshing, @FinishRefreshingDone);
chain[5] := ca;
}
runner := TClientActionRunner.Create;
runner.Done := @RefreshingDone;
runner.InitChain(chain);
end;

procedure TForm1.aRefreshStep1Execute(Sender: TObject);
begin
Memo1.Lines.Add('refreshstep1 start');
sleep(1000);
end;

procedure TForm1.aFinishRefreshingExecute(Sender: TObject);
begin
Memo1.Lines.Add('refreshing finished');
end;

procedure TForm1.aRefreshStep2Execute(Sender: TObject);
begin
Memo1.Lines.Add('refreshstep2 start');
sleep(2000);
end;

procedure TForm1.aRefreshStep3Execute(Sender: TObject);
begin
Memo1.Lines.Add('refreshstep3 start');
sleep(3000);
end;

procedure TForm1.aRefreshStep4Execute(Sender: TObject);
begin
Memo1.Lines.Add('refreshstep4 start');
sleep(4000);
end;

procedure TForm1.aRefreshStep5Execute(Sender: TObject);
begin
Memo1.Lines.Add('refreshstep5 start');
sleep(1000);
end;

procedure TForm1.aUserAction1Execute(Sender: TObject);
begin
Memo1.Lines.Add('user action 1 start');
sleep(2000);
end;

procedure TForm1.aUserAction2Execute(Sender: TObject);
begin
Memo1.Lines.Add('user action 2 start');
sleep(2000);
end;

procedure TForm1.btnUserAction1Click(Sender: TObject);
var
ca: TClientAction;
begin
ca := TClientAction.Create(aUserAction1, @UserAction1Done);
runner.SetUserAction(ca);
end;

procedure TForm1.btnUserAction2Click(Sender: TObject);
var
ca: TClientAction;
begin
ca := TClientAction.Create(aUserAction2, @UserAction2Done);
runner.SetUserAction(ca);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := false;
runner.StartChain;
end;

procedure TForm1.RefreshStep1Done(const result: boolean);
begin
Memo1.Lines.Add('refreshstep1 done');
end;

procedure TForm1.RefreshStep2Done(const result: boolean);
begin
Memo1.Lines.Add('refreshstep2 done');
end;

procedure TForm1.RefreshStep3Done(const result: boolean);
begin
Memo1.Lines.Add('refreshstep3 done');
end;

procedure TForm1.RefreshStep4Done(const result: boolean);
begin
Memo1.Lines.Add('refreshstep4 done');
end;

procedure TForm1.RefreshStep5Done(const result: boolean);
begin
Memo1.Lines.Add('refreshstep5 done');
end;

procedure TForm1.RefreshingDone(Sender: TObject);
var
en: boolean;
begin
Timer1.Enabled := true;
en := Timer1.Enabled;
end;

procedure TForm1.UserAction1Done(const result: boolean);
begin
Memo1.Lines.Add('user action 1 done');
end;

procedure TForm1.UserAction2Done(const result: boolean);
begin
Memo1.Lines.Add('user action 2 done');
end;

initialization
{$I chainMain.lrs}

end.






Цялата тема
ТемаАвторПубликувано
* actions, threads, chain-of-actions tikva   15.06.07 14:18
. * P.S: actions, threads, chain-of-actions tikva   15.06.07 16:28
. * По време на дълги процеси NikB   16.06.07 18:50
. * Става пожар nop   16.06.07 19:27
. * Re: Става пожар tikva   18.06.07 11:13
. * Re: actions, threads, chain-of-actions tikva   22.06.07 14:49
. * Re: actions, threads, chain-of-actions Formal   26.06.07 10:20
Клуб :  


Clubs.dir.bg е форум за дискусии. Dir.bg не носи отговорност за съдържанието и достоверността на публикуваните в дискусиите материали.

Никаква част от съдържанието на тази страница не може да бъде репродуцирана, записвана или предавана под каквато и да е форма или по какъвто и да е повод без писменото съгласие на Dir.bg
За Забележки, коментари и предложения ползвайте формата за Обратна връзка | Мобилна версия | Потребителско споразумение
© 2006-2024 Dir.bg Всички права запазени.