source: branches/ByteArray/Devices/DeviceMapper.pas

Last change on this file was 9, checked in by chronos, 2 months ago
  • Modified: Optimized DeviceMapper read/write handlers calls without case statement.
  • Modified: Use TInt as base data type which can be redefined to different higher integer type. For start it is Int64.
File size: 2.9 KB
Line 
1unit DeviceMapper;
2
3interface
4
5uses
6 Classes, SysUtils, Device, Channel, Generics.Collections, Int, Math;
7
8type
9
10 { TMappedDevice }
11
12 TMappedDevice = class
13 Device: TDevice;
14 ReadCount: Integer;
15 WriteCount: Integer;
16 ReadBase: Integer;
17 WriteBase: Integer;
18 constructor Create;
19 destructor Destroy; override;
20 end;
21
22 { TDeviceMapper }
23
24 TDeviceMapper = class(TChannelDevice)
25 private
26 function ChannelRead(Address: TInt; Size: TIntSize): TInt;
27 procedure ChannelWrite(Address: TInt; Size: TIntSize; Value: TInt);
28 function ChannelGetSize: TInt;
29 public
30 ReadHandlers: TList<TReadEvent>;
31 WriteHandlers: TList<TWriteEvent>;
32 MappedDevices: TObjectList<TMappedDevice>;
33 procedure RegisterDevice(Device: TDevice);
34 procedure UnregisterDevice(Device: TDevice);
35 procedure SetChannel(Channel: TChannel); override;
36 constructor Create;
37 destructor Destroy; override;
38 end;
39
40
41implementation
42
43{ TMappedDevice }
44
45constructor TMappedDevice.Create;
46begin
47end;
48
49destructor TMappedDevice.Destroy;
50begin
51 inherited;
52end;
53
54{ TDeviceMapper }
55
56procedure TDeviceMapper.RegisterDevice(Device: TDevice);
57var
58 NewMappedDevice: TMappedDevice;
59 Handlers: THandlers;
60begin
61 Handlers := Device.GetHandlers;
62
63 NewMappedDevice := TMappedDevice.Create;
64 NewMappedDevice.Device := Device;
65 NewMappedDevice.ReadBase := ReadHandlers.Count;
66 NewMappedDevice.WriteBase := WriteHandlers.Count;
67 NewMappedDevice.ReadCount := Handlers.ReadHandlers.Count;
68 NewMappedDevice.WriteCount := Handlers.WriteHandlers.Count;
69 MappedDevices.Add(NewMappedDevice);
70
71 ReadHandlers.AddRange(Handlers.ReadHandlers);
72 WriteHandlers.AddRange(Handlers.WriteHandlers);
73 Handlers.Free;
74end;
75
76procedure TDeviceMapper.UnregisterDevice(Device: TDevice);
77var
78 I: Integer;
79begin
80 for I := 0 to MappedDevices.Count - 1 do
81 if MappedDevices[I].Device = Device then begin
82 MappedDevices.Delete(I);
83 Break;
84 end;
85end;
86
87function TDeviceMapper.ChannelRead(Address: TInt; Size: TIntSize): TInt;
88begin
89 if Address < ReadHandlers.Count then
90 Result := ReadHandlers[Address](Size)
91 else Result := 0;
92end;
93
94procedure TDeviceMapper.ChannelWrite(Address: TInt; Size: TIntSize; Value: TInt);
95var
96 I: Integer;
97begin
98 if Address < WriteHandlers.Count then
99 WriteHandlers[Address](Size, Value);
100end;
101
102function TDeviceMapper.ChannelGetSize: TInt;
103begin
104 Result := Max(ReadHandlers.Count, WriteHandlers.Count);
105end;
106
107procedure TDeviceMapper.SetChannel(Channel: TChannel);
108begin
109 Channel.Read := ChannelRead;
110 Channel.Write := ChannelWrite;
111 Channel.GetSize := ChannelGetSize;
112end;
113
114constructor TDeviceMapper.Create;
115begin
116 MappedDevices := TObjectList<TMappedDevice>.Create;
117 ReadHandlers := TList<TReadEvent>.Create;
118 WriteHandlers := TList<TWriteEvent>.Create;
119end;
120
121destructor TDeviceMapper.Destroy;
122begin
123 FreeAndNil(ReadHandlers);
124 FreeAndNil(WriteHandlers);
125 FreeAndNil(MappedDevices);
126 inherited;
127end;
128
129end.
130
Note: See TracBrowser for help on using the repository browser.