source: trunk/Packages/ModularSystem/UModularSystem.pas

Last change on this file was 18, checked in by chronos, 12 years ago
  • Used external packages are now stored in uncompressed form rather in zipped files. This allow better package version synchronisation.
File size: 6.8 KB
Line 
1unit UModularSystem;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Contnrs;
9
10type
11 TModuleManager = class;
12
13 TAPI = class(TComponent)
14
15 end;
16
17 { TModule }
18
19 TModule = class(TComponent)
20 private
21 FInstalled: Boolean;
22 Manager: TModuleManager;
23 FVersion: string;
24 FIdentification: string;
25 FTitle: string;
26 FLicense: string;
27 FAuthor: string;
28 FDependencies: TStringList;
29 FDescription: TStringList;
30 procedure SetInstalled(AValue: Boolean);
31 public
32 API: TAPI;
33 MarkForInstall: Boolean;
34 procedure Install; virtual;
35 procedure Uninstall; virtual;
36 procedure Update; virtual;
37 procedure EnumModulesInstall(ModuleList: TStringList);
38 procedure EnumModulesUninstall(ModuleList: TStringList);
39 constructor Create(Owner: TComponent); virtual;
40 destructor Destroy; override;
41 property Installed: Boolean read FInstalled write SetInstalled;
42 published
43 property Version: string read FVersion write FVersion;
44 property Identification: string read FIdentification write FIdentification;
45 property Title: string read FTitle write FTitle;
46 property License: string read FLicense write FLicense;
47 property Author: string read FAuthor write FAuthor;
48 property Dependencies: TStringList read FDependencies write FDependencies;
49 property Description: TStringList read FDescription write FDescription;
50 end;
51
52 { TModuleManager }
53
54 TModuleManager = class(TComponent)
55 private
56 FAPI: TAPI;
57 procedure SetAPI(AValue: TAPI);
58 public
59 Modules: TObjectList; // TObjectList<TModule>
60 function FindModuleByName(Name: string): TModule;
61 procedure InstallDependencies(ModuleName: string; Dependencies: TStringList);
62 procedure UninstallDependencies(ModuleName: string);
63 procedure EnumModulesInstall(Dependencies, ModuleList: TStringList);
64 procedure EnumModulesUninstall(ModuleName: string; ModuleList: TStringList);
65 procedure RegisterModule(Module: TModule; MarkForInstall: Boolean = False);
66 procedure UnregisterModule(Module: TModule);
67 procedure InstallMarked;
68 procedure UninstallAll;
69 constructor Create(AOwner: TComponent); override;
70 destructor Destroy; override;
71 property API: TAPI read FAPI write SetAPI;
72 end;
73
74procedure Register;
75
76
77implementation
78
79resourcestring
80 SModuleNotFound = 'Module "%1:s" not found as dependency for module "%0:s"';
81
82procedure Register;
83begin
84 RegisterComponents('ModularSystem', [TModuleManager, TModule]);
85end;
86
87{ TModuleManager }
88
89procedure TModuleManager.SetAPI(AValue: TAPI);
90var
91 I: Integer;
92begin
93 if FAPI = AValue then Exit;
94 FAPI := AValue;
95 for I := 0 to Modules.Count - 1 do
96 TModule(Modules[I]).API := FAPI;
97end;
98
99function TModuleManager.FindModuleByName(Name: string): TModule;
100var
101 I: Integer;
102begin
103 I := 0;
104 while (I < Modules.Count) and (TModule(Modules[I]).Identification <> Name) do Inc(I);
105 if I < Modules.Count then Result := TModule(Modules[I])
106 else Result := nil;
107end;
108
109procedure TModuleManager.InstallDependencies(ModuleName: string; Dependencies: TStringList);
110var
111 Module: TModule;
112 I: Integer;
113begin
114 for I := 0 to Dependencies.Count - 1 do begin
115 Module := FindModuleByName(Dependencies[I]);
116 if Assigned(Module) then begin
117 if not Module.Installed then Module.Install;
118 end else raise Exception.CreateFmt(SModuleNotFound, [ModuleName, Dependencies[I]]);
119 end;
120end;
121
122procedure TModuleManager.UninstallDependencies(ModuleName: string);
123var
124 I: Integer;
125begin
126 for I := 0 to Modules.Count - 1 do
127 with TModule(Modules[I]) do begin
128 if (Dependencies.IndexOf(ModuleName) <> - 1) and Installed then Uninstall;
129 end;
130end;
131
132procedure TModuleManager.EnumModulesInstall(Dependencies,
133 ModuleList: TStringList);
134var
135 Module: TModule;
136 I: Integer;
137begin
138 for I := 0 to Dependencies.Count - 1 do begin
139 Module := FindModuleByName(Dependencies[I]);
140 if Assigned(Module) then begin
141 if not Module.Installed and (ModuleList.IndexOf(Module.Identification) = -1) then begin
142 ModuleList.Add(Module.Identification);
143 EnumModulesInstall(Module.Dependencies, ModuleList);
144 end;
145 end else raise Exception.CreateFmt(SModuleNotFound, [Module.Identification]);
146 end;
147end;
148
149procedure TModuleManager.EnumModulesUninstall(ModuleName: string;
150 ModuleList: TStringList);
151var
152 I: Integer;
153begin
154 for I := 0 to Modules.Count - 1 do
155 with TModule(Modules[I]) do begin
156 if (Dependencies.IndexOf(ModuleName) <> -1) and Installed and
157 (ModuleList.IndexOf(Identification) = -1) then begin
158 ModuleList.Add(Identification);
159 Self.EnumModulesUninstall(Identification, ModuleList);
160 end;
161 end;
162end;
163
164procedure TModuleManager.RegisterModule(Module: TModule;
165 MarkForInstall: Boolean = False);
166begin
167 Modules.Add(Module);
168 Module.Manager := Self;
169 Module.API := API;
170 Module.MarkForInstall := MarkForInstall;
171end;
172
173procedure TModuleManager.UnregisterModule(Module: TModule);
174begin
175 Modules.Remove(Module);
176end;
177
178procedure TModuleManager.InstallMarked;
179var
180 I: Integer;
181begin
182 for I := 0 to Modules.Count - 1 do
183 with TModule(Modules[I]) do
184 if not Installed and MarkForInstall then Install;
185end;
186
187procedure TModuleManager.UninstallAll;
188var
189 I: Integer;
190begin
191 for I := 0 to Modules.Count - 1 do
192 with TModule(Modules[I]) do
193 if Installed then Uninstall;
194end;
195
196constructor TModuleManager.Create(AOwner: TComponent);
197begin
198 inherited;
199 Modules := TObjectList.Create;
200end;
201
202destructor TModuleManager.Destroy;
203begin
204 UninstallAll;
205 FreeAndNil(Modules);
206 inherited Destroy;
207end;
208
209{ TModule }
210
211procedure TModule.SetInstalled(AValue: Boolean);
212begin
213 if FInstalled = AValue then Exit;
214 if AValue then Install else Uninstall;
215end;
216
217procedure TModule.Install;
218begin
219 if Installed then Exit;
220 Manager.InstallDependencies(Identification, Dependencies);
221 FInstalled := True;
222end;
223
224procedure TModule.Uninstall;
225begin
226 if not Installed then Exit;
227 Manager.UninstallDependencies(Identification);
228 FInstalled := False;
229end;
230
231procedure TModule.Update;
232begin
233 if not Installed then Exit;
234end;
235
236procedure TModule.EnumModulesInstall(ModuleList: TStringList);
237begin
238 ModuleList.Clear;
239 Manager.EnumModulesInstall(Dependencies, ModuleList);
240end;
241
242procedure TModule.EnumModulesUninstall(ModuleList: TStringList);
243begin
244 ModuleList.Clear;
245 Manager.EnumModulesUninstall(Identification, ModuleList);
246end;
247
248constructor TModule.Create(Owner: TComponent);
249begin
250 inherited;
251 Dependencies := TStringList.Create;
252 Description := TStringList.Create;
253end;
254
255destructor TModule.Destroy;
256begin
257 Installed := False;
258 Description.Free;
259 Dependencies.Free;
260 inherited Destroy;
261end;
262
263end.
264
Note: See TracBrowser for help on using the repository browser.