source: trunk/NewView/GlobalFilelistUnit.pas@ 32

Last change on this file since 32 was 32, checked in by RBRi, 19 years ago

% more source cleanup (uses)

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1unit GlobalFilelistUnit;
2
3// NewView - a new OS/2 Help Viewer
4// Copyright 2003 Aaron Lawrence (aaronl at consultant dot com)
5// This software is released under the Gnu Public License - see readme.txt
6
7interface
8
9// Maintains a linked list in shared memory
10// Mapping files (full path) to newview windows (frames)
11
12uses
13 OS2Def,
14 SharedMemoryUnit,
15 Semaphores;
16
17const
18 // size of shared mem used for storing global filelist
19 GLOBAL_FILELIST_SIZE = 64000;
20
21type
22 TOpenFileEntry = record
23 Next: ^TOpenFileEntry;
24 Window: HWND;
25 FilePath: array[ 0..255] of char;
26 end;
27 TPOpenFileEntry = ^ TOpenFileEntry;
28
29 TGlobalFilelist = class
30 protected
31 FMem: TSuballocatedSharedMemory;
32 FMutex: TMutex;
33 function GetHead: TPOpenFileEntry;
34 procedure SetHead( pEntry: TPOpenFileEntry );
35
36 function FindEntry( const FilePath: string ): TPOpenFileEntry;
37 public
38 constructor Create;
39 destructor Destroy; override;
40 function FindFile( const FilePath: string ): HWND;
41 procedure AddFile( const FilePath: string;
42 Window: HWND );
43
44 procedure RemoveFile( Window: HWND;
45 const FilePath: string );
46 procedure RemoveWindowFiles( Window: HWND );
47 end;
48
49implementation
50
51uses
52 ACLStringUtility,
53 SysUtils;
54
55constructor TGlobalFilelist.Create;
56begin
57 FMem := TSuballocatedSharedMemory.Create( 'NEWVIEW_GLOBAL_FILELIST',
58 GLOBAL_FILELIST_SIZE,
59 4 ); // space for head pointer
60 FMutex := TMutex.CreateNamed( 'NEWVIEW_FILELIST' );
61
62 // hm. What about initialising the head pointer?
63 // well I have changed suballocatedsharedmemory constructor
64 // so that the first instance accessing the memory will clear the
65 // reserved space to null...
66end;
67
68destructor TGlobalFilelist.Destroy;
69begin
70 FMem.Destroy;
71 FMutex.Destroy;
72end;
73
74function TGlobalFilelist.GetHead: TPOpenFileEntry;
75begin
76 Result := TPOpenFileEntry( FMem.Data ^ );
77end;
78
79procedure TGlobalFilelist.SetHead( pEntry: TPOpenFileEntry );
80begin
81 TPOpenFileEntry( FMem.Data ^ ) := pEntry;
82end;
83
84procedure TGlobalFilelist.AddFile( const FilePath: string;
85 Window: HWND );
86var
87 pEntry: TPOpenFileEntry;
88begin
89 FMutex.Get;
90
91 try
92 FMem.Allocate( pEntry,
93 sizeof( TPOpenFileEntry )
94 + sizeof( HWND )
95 + 1 // string length byte
96 + Length( FilePath ) );
97 except
98 begin
99 // didn't fit: discard
100 FMutex.Release;
101 exit;
102 end;
103 end;
104
105 // store handle, filename
106 pEntry ^. Window := Window;
107 StrPCopy( pEntry ^. FilePath, FilePath );
108
109 // link into list at head
110 pEntry ^. Next := GetHead;
111 SetHead( pEntry );
112
113 FMutex.Release;
114end;
115
116function TGlobalFilelist.FindEntry( const FilePath: string ): TPOpenFileEntry;
117begin
118 Result := GetHead;
119 while ( Result <> nil ) do
120 begin
121 if ( StringsSame( StrPas( Result ^. FilePath ), FilePath ) ) then
122 begin
123 // found
124 exit;
125 end;
126 Result := Result ^. Next;
127 end;
128 // not found
129end;
130
131function TGlobalFilelist.FindFile( const FilePath: string ): HWND;
132var
133 pEntry: TPOpenFileEntry;
134begin
135 FMutex.Get;
136 pEntry := FindEntry( FilePath );
137
138 if pEntry <> nil then
139 Result := pEntry ^. Window
140 else
141 Result := NULLHANDLE;
142
143 FMutex.Release;
144end;
145
146// Remove specified file from list
147procedure TGlobalFilelist.RemoveFile( Window: HWND;
148 const FilePath: string );
149var
150 pEntry: TPOpenFileEntry;
151 pPrevious: TPOpenFileEntry;
152begin
153 FMutex.Get;
154
155 pEntry := GetHead;
156 pPrevious := nil;
157 while ( pEntry <> nil ) do
158 begin
159 if ( pEntry ^. Window = Window ) then
160 begin
161 if ( StringsSame( StrPas( pEntry ^. FilePath ), FilePath ) ) then
162 begin
163 // found
164 // remove node from list
165 if pPrevious = nil then
166 // head node has changed
167 SetHead( pEntry ^.Next )
168 else
169 // point previous node to next node
170 pPrevious ^.Next := pEntry ^.Next;
171
172 FMem.Free( pEntry );
173
174 // done
175 FMutex.Release;
176 exit;
177 end;
178 end;
179 pPrevious := pEntry;
180 pEntry := pEntry ^. Next;
181 end;
182
183 // not found! Bad programmer event
184 FMutex.Release;
185
186 raise Exception.Create( 'GlobalFilelist: File cannot be removed, since not added: ' + FilePath );
187end;
188
189procedure TGlobalFilelist.RemoveWindowFiles( Window: HWND );
190var
191 pEntry: TPOpenFileEntry;
192 pPrevious: TPOpenFileEntry;
193begin
194 FMutex.Get;
195
196 pEntry := GetHead;
197 pPrevious := nil;
198 while ( pEntry <> nil ) do
199 begin
200 if ( pEntry ^. Window = Window ) then
201 begin
202 // found
203 // remove node from list
204 if pPrevious = nil then
205 // head node has changed
206 SetHead( pEntry ^.Next )
207 else
208 // point previous node to next node
209 pPrevious ^.Next := pEntry ^.Next;
210
211 FMem.Free( pEntry );
212 // continue looking - there could be more for this window
213 end;
214 pPrevious := pEntry;
215 pEntry := pEntry ^. Next;
216 end;
217 FMutex.Release;
218end;
219
220begin
221end.
Note: See TracBrowser for help on using the repository browser.