Statistics
| Branch: | Tag: | Revision:

root / UOLib / UMulBlock.pas @ 119:66352054ce4d

History | View | Annotate | Download (4.2 kB)

1
(*
2
 * CDDL HEADER START
3
 *
4
 * The contents of this file are subject to the terms of the
5
 * Common Development and Distribution License, Version 1.0 only
6
 * (the "License").  You may not use this file except in compliance
7
 * with the License.
8
 *
9
 * You can obtain a copy of the license at
10
 * http://www.opensource.org/licenses/cddl1.php.
11
 * See the License for the specific language governing permissions
12
 * and limitations under the License.
13
 *
14
 * When distributing Covered Code, include this CDDL HEADER in each
15
 * file and include the License file at
16
 * http://www.opensource.org/licenses/cddl1.php.  If applicable,
17
 * add the following below this CDDL HEADER, with the fields enclosed
18
 * by brackets "[]" replaced with your own identifying * information:
19
 *      Portions Copyright [yyyy] [name of copyright owner]
20
 *
21
 * CDDL HEADER END
22
 *
23
 *
24
 *      Portions Copyright 2009 Andreas Schneider
25
 *)
26
unit UMulBlock;
27
28
{$mode objfpc}{$H+}
29
30
interface
31
32
uses
33
  SysUtils, Classes;
34
35
type
36
  TMulBlock = class;
37
  TMulBlockChanged = procedure(ABlock: TMulBlock) of object;
38
  
39
  { TMulBlockEventHandler }
40
41
  TMulBlockEventHandler = class
42
    constructor Create;
43
    destructor Destroy; override;
44
  protected
45
    FEvents: TList;
46
  public
47
    procedure RegisterEvent(AEvent: TMulBlockChanged);
48
    procedure UnregisterEvent(AEvent: TMulBlockChanged);
49
    procedure FireEvents(ABlock: TMulBlock);
50
  end;
51
52
  { TMulBlock }
53
54
  TMulBlock = class
55
    constructor Create;
56
    destructor Destroy; override;
57
  protected
58
    FID: Integer;
59
    FOnChanged: TMulBlockChanged;
60
    FOnFinished: TMulBlockChanged;
61
    FOnDestroy: TMulBlockEventHandler;
62
  public
63
    class procedure Change(ABlock: TMulBlock); virtual;
64
    class procedure Finish(var ABlock: TMulBlock); virtual;
65
    function Clone: TMulBlock; virtual; abstract;
66
    function GetSize: Integer; virtual; abstract;
67
    procedure Write(AData: TStream); virtual; abstract;
68
    property ID: Integer read FID write FID;
69
    property OnChanged: TMulBlockChanged read FOnChanged write FOnChanged;
70
    property OnFinished: TMulBlockChanged read FOnFinished write FOnFinished;
71
    property OnDestroy: TMulBlockEventHandler read FOnDestroy;
72
  end;
73
74
implementation
75
76
type
77
  PMethod = ^TMethod;
78
79
{ TMulBlockEventHandler }
80
81
constructor TMulBlockEventHandler.Create;
82
begin
83
  inherited Create;
84
  FEvents := TList.Create;
85
end;
86
87
destructor TMulBlockEventHandler.Destroy;
88
var
89
  i: Integer;
90
begin
91
  if FEvents <> nil then
92
  begin
93
    for i := 0 to FEvents.Count - 1 do
94
      Dispose(PMethod(FEvents.Items[i]));
95
    FreeAndNil(FEvents);
96
  end;
97
  inherited Destroy;
98
end;
99
100
procedure TMulBlockEventHandler.RegisterEvent(AEvent: TMulBlockChanged);
101
var
102
  eventInfo: PMethod;
103
begin
104
  //UnregisterEvent(AEvent);
105
  New(eventInfo);
106
  eventInfo^.Code := TMethod(AEvent).Code;
107
  eventInfo^.Data := TMethod(AEvent).Data;
108
  FEvents.Add(eventInfo);
109
end;
110
111
procedure TMulBlockEventHandler.UnregisterEvent(AEvent: TMulBlockChanged);
112
var
113
  i: Integer;
114
115
  function RemoveEntry: Boolean;
116
  begin
117
    Dispose(PMethod(FEvents.Items[i]));
118
    FEvents.Delete(i);
119
    Result := True;
120
  end;
121
122
begin
123
  i := 0;
124
  while (i < FEvents.Count) and ((TMethod(AEvent).Code <> TMethod(FEvents.Items[i]^).Code) or (TMethod(AEvent).Data <> TMethod(FEvents.Items[i]^).Data) or not RemoveEntry) do
125
    Inc(i);
126
end;
127
128
procedure TMulBlockEventHandler.FireEvents(ABlock: TMulBlock);
129
var
130
  i: Integer;
131
begin
132
  for i := 0 to FEvents.Count - 1 do
133
    TMulBlockChanged(FEvents.Items[i]^)(ABlock);
134
end;
135
136
{ TMulBlock }
137
138
constructor TMulBlock.Create;
139
begin
140
  inherited Create;
141
  FOnDestroy := TMulBlockEventHandler.Create;
142
end;
143
144
destructor TMulBlock.Destroy;
145
begin
146
  if FOnDestroy <> nil then
147
  begin
148
    FOnDestroy.FireEvents(Self);
149
    FreeAndNil(FOnDestroy);
150
  end;
151
  inherited Destroy;
152
end;
153
154
class procedure TMulBlock.Change(ABlock: TMulBlock);
155
begin
156
  if ABlock <> nil then
157
  begin
158
    if ABlock.OnChanged <> nil then ABlock.OnChanged(ABlock);
159
  end;
160
end;
161
162
class procedure TMulBlock.Finish(var ABlock: TMulBlock);
163
begin
164
  if ABlock <> nil then
165
  begin
166
    if ABlock.OnFinished <> nil then ABlock.OnFinished(ABlock) else ABlock.Free;
167
    ABlock := nil;
168
  end;
169
end;
170
171
end.