source: trunk/NewView/GlobalFilelistUnit.pas@ 25

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

+ newview source

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