aboutsummaryrefslogtreecommitdiff
path: root/Занимательное программирование/7/7_columns/unit2.pas
blob: d4f6f4f42f1ae4431b12cfe869da23995d0cfd4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
unit Unit2;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils;

const
  StartMSecsPerFrame = 20;

type
  IGameHandler = class(TObject)
  private
    MSecsPerFrame: Integer;

  public
    Finished: Boolean;
    constructor Create;
    procedure DoIteration; virtual; abstract;

    procedure SlowDown;
    procedure SpeedUp;
  end;

  TActionThread = class(TThread)
  private
    FGameHandler: IGameHandler;

  public
    constructor Create(AGameHandler: IGameHandler);
    destructor Destroy;

    property GameHandler: IGameHandler read FGameHandler;

    procedure Execute; override;
  end;

implementation

constructor IGameHandler.Create;
begin
  Finished := false;
  MSecsPerFrame := StartMSecsPerFrame
end;

procedure IGameHandler.SlowDown;
begin
  MSecsPerFrame := StartMSecsPerFrame
end;

procedure IGameHandler.SpeedUp;
begin
  MSecsPerFrame := 100
end;

constructor TActionThread.Create(AGameHandler: IGameHandler);
begin
  inherited Create(false);
  FGameHandler := AGameHandler
end;

destructor TActionThread.Destroy;
begin
  FreeAndNil(FGameHandler)
end;

procedure TActionThread.Execute;
var
  OldTime: TDateTime;
  ToWait: Integer;
begin
  while not GameHandler.Finished do
  begin
    OldTime := Now;
    Synchronize(@FGameHandler.DoIteration);
    { Синхронизация с таймером. }
    ToWait := Round(GameHandler.MSecsPerFrame - (Now - OldTime) * MSecsPerDay);
    if ToWait > 0 then
      Sleep(ToWait)
  end
end;

end.