Mercurial > projects > mde
comparison mde/resource/paths.d @ 53:f000d6cd0f74
Changes to paths, command line arguments and font LCD rendering.
Use "./" instead of "" as default install dir on windows.
Implemented a command-line argument parser.
Changes to LCD filter/render-mode option handling after testing what actually happens.
Changed some FontTexture messages and internals.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Thu, 05 Jun 2008 17:16:52 +0100 |
parents | e0839643ff52 |
children |
comparison
equal
deleted
inserted
replaced
51:387a80724c35 | 53:f000d6cd0f74 |
---|---|
37 import mde.mergetag.DataSet; | 37 import mde.mergetag.DataSet; |
38 import mde.mergetag.exception; | 38 import mde.mergetag.exception; |
39 | 39 |
40 import tango.io.Console; | 40 import tango.io.Console; |
41 import tango.io.FilePath; | 41 import tango.io.FilePath; |
42 import tango.stdc.stdlib; | 42 import tango.sys.Environment; |
43 import tango.stdc.stringz; | |
44 //import tango.scrapple.sys.win32.Registry; // Trouble getting this to work | 43 //import tango.scrapple.sys.win32.Registry; // Trouble getting this to work |
45 | 44 |
46 /** Order to read files in. | 45 /** Order to read files in. |
47 * | 46 * |
48 * Values: HIGH_LOW, LOW_HIGH, HIGH_ONLY. */ | 47 * Values: HIGH_LOW, LOW_HIGH, HIGH_ONLY. */ |
113 if (FilePath (paths[i]~file~".mtb").exists) return true; | 112 if (FilePath (paths[i]~file~".mtb").exists) return true; |
114 } | 113 } |
115 return false; | 114 return false; |
116 } | 115 } |
117 | 116 |
117 /// Print all paths found. | |
118 static void printPaths () { | |
119 Cout ("Data paths found:"); | |
120 dataDir.coutPaths; | |
121 Cout ("\nConf paths found:"); | |
122 confDir.coutPaths; | |
123 Cout ("\nLog file directory:\n\t")(logDir).newline; | |
124 } | |
125 | |
118 private: | 126 private: |
119 PathView[] getFiles (char[] filename, PRIORITY readOrder) | 127 PathView[] getFiles (char[] filename, PRIORITY readOrder) |
120 in { | 128 in { |
121 assert (readOrder == PRIORITY.LOW_HIGH || | 129 assert (readOrder == PRIORITY.LOW_HIGH || |
122 readOrder == PRIORITY.HIGH_LOW || | 130 readOrder == PRIORITY.HIGH_LOW || |
163 } | 171 } |
164 } | 172 } |
165 return false; | 173 return false; |
166 } | 174 } |
167 | 175 |
176 void coutPaths () { | |
177 if (pathsLen) { | |
178 for (size_t i = 0; i < pathsLen; ++i) | |
179 Cout ("\n\t" ~ paths[i]); | |
180 } else | |
181 Cout ("[none]"); | |
182 } | |
183 | |
168 // Use a static array to store all possible paths with separate length counters. | 184 // Use a static array to store all possible paths with separate length counters. |
169 // Lowest priority paths are first. | 185 // Lowest priority paths are first. |
170 char[][MAX_PATHS] paths; | 186 char[][MAX_PATHS] paths; |
171 ubyte pathsLen = 0; | 187 ubyte pathsLen = 0; |
172 } | 188 } |
183 /** Find at least one path for each required directory. | 199 /** Find at least one path for each required directory. |
184 * | 200 * |
185 * Note: the logger cannot be used yet, so only output is exception messages. */ | 201 * Note: the logger cannot be used yet, so only output is exception messages. */ |
186 // FIXME: use tango/sys/Environment.d | 202 // FIXME: use tango/sys/Environment.d |
187 version (linux) { | 203 version (linux) { |
188 void resolvePaths () { | 204 // base-path not used on posix |
205 void resolvePaths (char[] = null) { | |
189 // Home directory: | 206 // Home directory: |
190 char[] HOME = fromStringz (getenv (toStringz ("HOME"))); | 207 char[] HOME = Environment.get("HOME", "."); |
191 | 208 |
192 // Base paths: | 209 // Base paths: |
193 // Static data (must exist): | 210 // Static data (must exist): |
194 PathView staticPath = findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", "data"); | 211 PathView staticPath = |
212 findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", "data"); | |
195 // Config (can just use defaults if necessary, so long as we can save afterwards): | 213 // Config (can just use defaults if necessary, so long as we can save afterwards): |
196 PathView userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde"); | 214 PathView userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde"); |
197 | 215 |
198 // Static data paths: | 216 // Static data paths: |
199 dataDir.addPath (staticPath.toString); // we know this is valid anyway | 217 dataDir.addPath (staticPath.toString); // we know this is valid anyway |
200 dataDir.tryPath (userPath.toString ~ DATA); | 218 dataDir.tryPath (userPath.toString ~ DATA); |
219 if (extraDataPath) dataDir.tryPath (extraDataPath); | |
201 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); | 220 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); |
202 | 221 |
203 // Configuration paths: | 222 // Configuration paths: |
204 confDir.tryPath (staticPath.toString ~ CONF); | 223 confDir.tryPath (staticPath.toString ~ CONF); |
205 confDir.tryPath ("/etc/mde"); | 224 confDir.tryPath ("/etc/mde"); |
206 confDir.tryPath (userPath.toString ~ CONF, true); | 225 confDir.tryPath (userPath.toString ~ CONF, true); |
226 if (extraConfPath) confDir.tryPath (extraConfPath); | |
207 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); | 227 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); |
208 | 228 |
209 // Logging path: | 229 // Logging path: |
210 logDir = userPath.toString; | 230 logDir = userPath.toString; |
211 } | 231 } |
212 } else version (Windows) { | 232 } else version (Windows) { |
213 void resolvePaths () { | 233 void resolvePaths (char[] base = "./") { |
214 //FIXME: Get path from registry | 234 //FIXME: Get path from registry |
215 //FIXME: Get user path (Docs&Settings/USER/Local Settings/Application data/mde) | 235 //FIXME: Get user path (Docs&Settings/USER/Local Settings/Application data/mde) |
236 //http://www.dsource.org/projects/tango/forums/topic/187 | |
216 | 237 |
217 // Base paths: | 238 // Base paths: |
218 PathView installPath = findPath (false, "");; | 239 PathView installPath = findPath (false, base); |
219 PathView userPath = findPath (true, "user"); // FIXME: see above | 240 PathView staticPath = findPath (false, installPath.append("data").toString); |
220 PathView staticPath = findPath (false, "data"); | 241 PathView userPath = findPath (true, installPath.append("user").toString); // FIXME: see above |
221 | 242 |
222 // Static data paths: | 243 // Static data paths: |
223 dataDir.addPath (staticPath.toString); // we know this is valid anyway | 244 dataDir.addPath (staticPath.toString); // we know this is valid anyway |
224 dataDir.tryPath (userPath.toString ~ DATA); | 245 dataDir.tryPath (userPath.toString ~ DATA); |
246 if (extraDataPath) dataDir.tryPath (extraDataPath); | |
225 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); | 247 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); |
226 | 248 |
227 // Configuration paths: | 249 // Configuration paths: |
228 confDir.tryPath (staticPath.toString ~ CONF); | 250 confDir.tryPath (staticPath.toString ~ CONF); |
229 confDir.tryPath ("conf"); | 251 confDir.tryPath (installPath.append("user").toString); |
230 confDir.tryPath (userPath.toString ~ CONF, true); | 252 confDir.tryPath (userPath.toString ~ CONF, true); |
253 if (extraConfPath) confDir.tryPath (extraConfPath); | |
231 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); | 254 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); |
232 | 255 |
233 // Logging path: | 256 // Logging path: |
234 logDir = userPath.toString; | 257 logDir = userPath.toString; |
235 } | 258 } |
236 } else { | 259 } else { |
237 static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!"); | 260 static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!"); |
238 } | 261 } |
239 | 262 |
240 private: | 263 /// For command line args: these paths are added if non-null, with highest priority. |
264 char[] extraDataPath, extraConfPath; | |
265 | |
266 private { | |
267 class PathException : mdeException { | |
268 this(char[] msg) { | |
269 super (msg); | |
270 } | |
271 } | |
272 | |
241 // The maximum number of paths for any one "directory". | 273 // The maximum number of paths for any one "directory". |
242 // There are NO CHECKS that this is not exceeded. | 274 // There are NO CHECKS that this is not exceeded. |
243 const MAX_PATHS = 3; | 275 const MAX_PATHS = 4; |
244 | 276 |
245 /* Try each path in succession, returning the first to exist and be a folder. | 277 /* Try each path in succession, returning the first to exist and be a folder. |
246 * If none are valid and create is true, will try creating each in turn. | 278 * If none are valid and create is true, will try creating each in turn. |
247 * If still none are valid, throws. */ | 279 * If still none are valid, throws. */ |
248 PathView findPath (bool create, char[][] paths ...) { | 280 PathView findPath (bool create, char[][] paths ...) { |
249 foreach (path; paths) { | 281 FilePath[] fps; |
250 PathView pv = new FilePath (path); | 282 fps.length = paths.length; |
251 if (pv.exists && pv.isFolder) return pv; // got a valid path | 283 foreach (i,path; paths) { |
252 } | 284 FilePath pv = new FilePath (path); |
253 if (create) { // try to create a folder, using each path in turn until succesful | 285 if (pv.exists && pv.isFolder) return pv; // got a valid path |
254 foreach (path; paths) { | 286 fps[i] = pv; |
255 FilePath fp = new FilePath (path); | 287 } |
256 try { | 288 if (create) { // try to create a folder, using each path in turn until succesful |
257 return fp.create; | 289 foreach (fp; fps) { |
258 } | 290 try { |
259 catch (Exception e) {} | 291 return fp.create; |
260 } | 292 } |
261 } | 293 catch (Exception e) {} |
294 } | |
295 } | |
262 // no valid path... | 296 // no valid path... |
263 char[] msg = "Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:"; | 297 char[] msg = "Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:"; |
264 foreach (path; paths) msg ~= " \"" ~ path ~ '\"'; | 298 foreach (path; paths) msg ~= " \"" ~ path ~ '\"'; |
265 throw new mdeException (msg); | 299 throw new PathException (msg); |
266 } | 300 } |
267 //END Path resolution | 301 //END Path resolution |
268 | 302 |
269 /** A special adapter for reading from multiple mergetag files with the same relative path to an | 303 /** A special adapter for reading from multiple mergetag files with the same relative path to an |
270 * mdeDirectory simultaneously. | 304 * mdeDirectory simultaneously. |
271 */ | 305 */ |
272 class mdeReader : IReader | 306 class mdeReader : IReader |
273 { | 307 { |
274 private this (PathView[] files, DataSet ds, bool rdHeader) | 308 private this (PathView[] files, DataSet ds, bool rdHeader) |
275 in { | 309 in { |
276 assert (files !is null, "mdeReader.this: files is null"); | 310 assert (files !is null, "mdeReader.this: files is null"); |
277 } body { | 311 } body { |
278 if (ds is null) ds = new DataSet; | 312 if (ds is null) ds = new DataSet; |
279 | 313 |
280 foreach (file; files) { | 314 foreach (file; files) { |
281 IReader r = makeReader (file, ds, rdHeader); | 315 IReader r = makeReader (file, ds, rdHeader); |
282 | 316 |
283 readers[readersLen++] = r; | 317 readers[readersLen++] = r; |
284 } | 318 } |
285 } | 319 } |
286 | 320 |
287 DataSet dataset () { /// Get the DataSet | 321 DataSet dataset () { /// Get the DataSet |
288 return readers[0].dataset; // all readers share the same dataset | 322 return readers[0].dataset; // all readers share the same dataset |
289 } | 323 } |
290 void dataset (DataSet ds) { /// Set the DataSet | 324 void dataset (DataSet ds) { /// Set the DataSet |
291 for (uint i = 0; i < readersLen; ++i) readers[i].dataset (ds); | 325 for (uint i = 0; i < readersLen; ++i) readers[i].dataset (ds); |
292 } | 326 } |
293 | 327 |
294 void dataSecCreator (IDataSection delegate (ID) dsC) { /// Set the dataSecCreator | 328 void dataSecCreator (IDataSection delegate (ID) dsC) { /// Set the dataSecCreator |
295 for (uint i = 0; i < readersLen; ++i) readers[i].dataSecCreator = dsC; | 329 for (uint i = 0; i < readersLen; ++i) readers[i].dataSecCreator = dsC; |
296 } | 330 } |
297 | 331 |
298 /** Get identifiers for all sections. | 332 /** Get identifiers for all sections. |
299 * | 333 * |
300 * Note: the identifiers from all sections in all files are just strung together, starting with | 334 * Note: the identifiers from all sections in all files are just strung together, starting with |
301 * the highest-priority file. */ | 335 * the highest-priority file. */ |
302 ID[] getSectionNames () { | 336 ID[] getSectionNames () { |
303 ID[] names; | 337 ID[] names; |
304 for (int i = readersLen-1; i >= 0; --i) names ~= readers[i].getSectionNames; | 338 for (int i = readersLen-1; i >= 0; --i) names ~= readers[i].getSectionNames; |
305 return names; | 339 return names; |
306 } | 340 } |
307 void read () { /// Commence reading | 341 void read () { /// Commence reading |
308 for (uint i = 0; i < readersLen; ++i) readers[i].read(); | 342 for (uint i = 0; i < readersLen; ++i) readers[i].read(); |
309 } | 343 } |
310 void read (ID[] secSet) { /// ditto | 344 void read (ID[] secSet) { /// ditto |
311 for (uint i = 0; i < readersLen; ++i) readers[i].read(secSet); | 345 for (uint i = 0; i < readersLen; ++i) readers[i].read(secSet); |
312 } | 346 } |
313 void read (View!(ID) secSet) { /// ditto | 347 void read (View!(ID) secSet) { /// ditto |
314 for (uint i = 0; i < readersLen; ++i) readers[i].read(secSet); | 348 for (uint i = 0; i < readersLen; ++i) readers[i].read(secSet); |
315 } | 349 } |
316 | 350 |
317 private: | 351 private: |
318 IReader[MAX_PATHS] readers; | 352 IReader[MAX_PATHS] readers; |
319 ubyte readersLen = 0; | 353 ubyte readersLen = 0; |
320 | 354 |
321 PRIORITY rdOrder; | 355 PRIORITY rdOrder; |
356 } | |
322 } | 357 } |