Mercurial > projects > mde
comparison mde/lookup/Options.d @ 94:9520cc0448e5
Boolean options are now encapsulated within a Content class (currently an experiment).
This should facilitate generic option editing widgets.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Thu, 23 Oct 2008 17:45:49 +0100 |
parents | 97e6dce08037 |
children | 2a364c7d82c9 |
comparison
equal
deleted
inserted
replaced
93:08a4ae11454b | 94:9520cc0448e5 |
---|---|
28 module mde.lookup.Options; | 28 module mde.lookup.Options; |
29 | 29 |
30 import mde.setup.paths; | 30 import mde.setup.paths; |
31 import mde.exception; | 31 import mde.exception; |
32 | 32 |
33 public import mde.gui.content.Content; | |
34 | |
33 import mde.file.mergetag.Reader; | 35 import mde.file.mergetag.Reader; |
34 import mde.file.mergetag.Writer; | 36 import mde.file.mergetag.Writer; |
35 import mde.file.mergetag.DataSet; | 37 import mde.file.mergetag.DataSet; |
36 import mde.file.serialize; | 38 import mde.file.serialize; |
37 | 39 |
50 * | 52 * |
51 * Each sub-class provides named variables for maximal-speed reading. Local sub-class references | 53 * Each sub-class provides named variables for maximal-speed reading. Local sub-class references |
52 * should be used for reading variables, and via the addOptionsClass() hook will be loaded from | 54 * should be used for reading variables, and via the addOptionsClass() hook will be loaded from |
53 * files during pre-init (init0 stage). Do not write changes directly to the subclasses or they will | 55 * files during pre-init (init0 stage). Do not write changes directly to the subclasses or they will |
54 * not be saved; instead use set(), for example, miscOpts.set!(char[])("L10n","en-GB"). Use an | 56 * not be saved; instead use set(), for example, miscOpts.set!(char[])("L10n","en-GB"). Use an |
55 * example like OptionsMisc as a template for creating a new Options sub-class. | 57 * example like MiscOptions as a template for creating a new Options sub-class. |
56 * | 58 * |
57 * Optionally, overload the validate() function. This is called after loading, allowing conditions | 59 * Optionally, overload the validate() function. This is called after loading, allowing conditions |
58 * to be enforced on variables. Use set!()() to change the variables. If an exception is thrown, | 60 * to be enforced on variables. Use set!()() to change the variables. If an exception is thrown, |
59 * init will abort and the executable won't start. | 61 * init will abort and the executable won't start. |
60 * | 62 * |
77 protected this() {} /// Do not instantiate directly. | 79 protected this() {} /// Do not instantiate directly. |
78 | 80 |
79 // All supported types, for generic handling via templates. It should be possible to change | 81 // All supported types, for generic handling via templates. It should be possible to change |
80 // the supported types simply by changing this list now (untested). | 82 // the supported types simply by changing this list now (untested). |
81 template store(A...) { alias A store; } | 83 template store(A...) { alias A store; } |
82 alias store!(bool, int, double, char[]) TYPES; | 84 alias store!(int, double, char[]) TYPES;//FIXME removed bool |
83 //BEGIN Templates: internal | 85 //BEGIN Templates: internal |
84 private { | 86 private { |
85 // Get name of a type. Basically just stringof, but special handling for arrays. | 87 // Get name of a type. Basically just stringof, but special handling for arrays. |
86 // Use TName!(T) for a valid symbol name, and T.stringof for a type. | 88 // Use TName!(T) for a valid symbol name, and T.stringof for a type. |
87 template TName(T : T[]) { | 89 template TName(T : T[]) { |
90 template TName(T) { | 92 template TName(T) { |
91 const char[] TName = T.stringof; | 93 const char[] TName = T.stringof; |
92 } | 94 } |
93 | 95 |
94 // Pointer lists | 96 // Pointer lists |
95 template PLists(T, A...) { | 97 template PLists(A...) { |
96 static if (A.length) { | 98 static if (A.length) { |
97 const char[] PLists = T.stringof~"*[ID] opts"~TName!(T)~";\n" ~ PLists!(A); | 99 static if (is (T == bool)) { |
98 } else | 100 const char[] PLists = PLists!(A[1..$]); |
99 const char[] PLists = T.stringof~"*[ID] opts"~TName!(T)~";\n"; | 101 } else |
102 const char[] PLists = A[0].stringof~"*[ID] opts"~TName!(A[0])~";\n" ~ PLists!(A[1..$]); | |
103 } else | |
104 const char[] PLists = ""; | |
100 } | 105 } |
101 | 106 |
102 // True if type is one of A | 107 // True if type is one of A |
103 template TIsIn(T, A...) { | 108 template TIsIn(T, A...) { |
104 static if (A.length) { | 109 static if (A.length) { |
110 const bool TIsIn = false; // no more possibilities | 115 const bool TIsIn = false; // no more possibilities |
111 } | 116 } |
112 | 117 |
113 // For addTag | 118 // For addTag |
114 template addTagMixin(T, A...) { | 119 template addTagMixin(T, A...) { |
115 const char[] ifBlock = `if (tp == "`~T.stringof~`") { | 120 static if (is(T == bool)) { |
116 `~T.stringof~`** p = id in opts`~TName!(T)~`; | 121 const char[] ifBlock = `if (tp == "`~T.stringof~`") { |
117 if (p !is null) **p = parseTo!(`~T.stringof~`) (dt); | 122 auto p = id in opts; |
118 }`; | 123 if (p) { |
124 auto q = cast(BoolContent) (*p); | |
125 if (q) q = parseTo!(`~T.stringof~`) (dt); | |
126 } | |
127 }`; | |
128 } else | |
129 const char[] ifBlock = `if (tp == "`~T.stringof~`") { | |
130 `~T.stringof~`** p = id in opts`~TName!(T)~`; | |
131 if (p !is null) **p = parseTo!(`~T.stringof~`) (dt); | |
132 }`; | |
119 static if (A.length) | 133 static if (A.length) |
120 const char[] addTagMixin = ifBlock~` else `~addTagMixin!(A).addTagMixin; | 134 const char[] addTagMixin = ifBlock~` else `~addTagMixin!(A).addTagMixin; |
121 else | 135 else |
122 const char[] addTagMixin = ifBlock; | 136 const char[] addTagMixin = ifBlock; |
123 } | 137 } |
127 static if (A.length) { | 141 static if (A.length) { |
128 const char[] writeAllMixin = | 142 const char[] writeAllMixin = |
129 `foreach (ID id, `~A[0].stringof~`* val; opts`~TName!(A[0])~`) dlg ("`~A[0].stringof~`", id, parseFrom!(`~A[0].stringof~`) (*val));` ~ writeAllMixin!(A[1..$]); | 143 `foreach (ID id, `~A[0].stringof~`* val; opts`~TName!(A[0])~`) dlg ("`~A[0].stringof~`", id, parseFrom!(`~A[0].stringof~`) (*val));` ~ writeAllMixin!(A[1..$]); |
130 } else | 144 } else |
131 const char[] writeAllMixin = ``; | 145 const char[] writeAllMixin = ``; |
146 } | |
147 | |
148 // For list | |
149 template listMixin(A...) { | |
150 static if (A.length) { | |
151 const char[] listMixin = `ret ~= opts`~TName!(A[0])~`.keys;` ~ listMixin!(A[1..$]); | |
152 } else | |
153 const char[] listMixin = ``; | |
132 } | 154 } |
133 } | 155 } |
134 //END Templates: internal | 156 //END Templates: internal |
135 | 157 |
136 | 158 |
142 void addOptionsClass (Options c, char[] i) | 164 void addOptionsClass (Options c, char[] i) |
143 in { // Trap a couple of potential coding errors: | 165 in { // Trap a couple of potential coding errors: |
144 assert (c !is null); // Instance must be created before calling addOptionsClass | 166 assert (c !is null); // Instance must be created before calling addOptionsClass |
145 assert (((cast(ID) i) in subClasses) is null); // Don't allow a silent replacement | 167 assert (((cast(ID) i) in subClasses) is null); // Don't allow a silent replacement |
146 } body { | 168 } body { |
169 c.secName = i; | |
147 subClasses[cast(ID) i] = c; | 170 subClasses[cast(ID) i] = c; |
148 } | 171 } |
149 | 172 |
150 // Track all sections for saving/loading/other generic handling. | 173 // Track all sections for saving/loading/other generic handling. |
151 Options[ID] subClasses; | 174 Options[ID] subClasses; |
231 * | 254 * |
232 * Due to the way options are handled generically, string IDs must be used to access the options | 255 * Due to the way options are handled generically, string IDs must be used to access the options |
233 * via hash-maps, which is a little slower than direct access but necessary since the option | 256 * via hash-maps, which is a little slower than direct access but necessary since the option |
234 * must be changed in two separate places. */ | 257 * must be changed in two separate places. */ |
235 void set(T) (char[] symbol, T val) { | 258 void set(T) (char[] symbol, T val) { |
236 static assert (TIsIn!(T,TYPES), "Options does not support type "~T.stringof); | 259 static assert (TIsIn!(T,TYPES) && !is(T == bool), "Options does not support type "~T.stringof); |
237 | 260 |
238 changed = true; // something got set (don't bother checking this isn't what it already was) | 261 changed = true; // something got set (don't bother checking this isn't what it already was) |
239 | 262 |
240 try { | 263 try { |
241 mixin (`*(opts`~TName!(T)~`[cast(ID) symbol]) = val;`); | 264 mixin (`*(opts`~TName!(T)~`[cast(ID) symbol]) = val;`); |
243 } catch (ArrayBoundsException) { | 266 } catch (ArrayBoundsException) { |
244 // log and ignore: | 267 // log and ignore: |
245 logger.error ("Options.set: invalid symbol"); | 268 logger.error ("Options.set: invalid symbol"); |
246 } | 269 } |
247 } | 270 } |
248 | 271 /+ |
249 /** Get option symbol of an Options sub-class. | 272 /** Get option symbol of an Options sub-class. |
250 * | 273 * |
251 * Using this method to read an option is not necessary, but allows for generic use. */ | 274 * Using this method to read an option is not necessary, but allows for generic use. */ |
252 T get(T) (char[] symbol) { | 275 T get(T) (char[] symbol) { |
253 static assert (TIsIn!(T,TYPES), "Options does not support type "~T.stringof); | 276 static assert (TIsIn!(T,TYPES), "Options does not support type "~T.stringof); |
258 return *(optsVars[cast(ID) symbol]); | 281 return *(optsVars[cast(ID) symbol]); |
259 } catch (ArrayBoundsException) { | 282 } catch (ArrayBoundsException) { |
260 // log and ignore: | 283 // log and ignore: |
261 logger.error ("Options.get: invalid symbol"); | 284 logger.error ("Options.get: invalid symbol"); |
262 } | 285 } |
263 } | 286 }+/ |
264 | 287 |
265 /** List the names of all options of a specific type. */ | 288 /** List the names of all options of a specific type. */ |
266 char[][] list(T) () { | 289 char[][] list () { |
267 static assert (TIsIn!(T,TYPES), "Options does not support type "~T.stringof); | 290 char[][] ret; |
268 | 291 mixin (listMixin!(TYPES)); |
269 mixin (`alias opts`~TName!(T)~` optsVars;`); | 292 return ret; |
270 | 293 } |
271 return optsVars.keys; | 294 |
295 /// Get all Options stored with a ValueContent. | |
296 ValueContent[char[]] content() { | |
297 return opts; | |
272 } | 298 } |
273 | 299 |
274 /// Variable validate function. This implementation does nothing. | 300 /// Variable validate function. This implementation does nothing. |
275 void validate() {} | 301 void validate() {} |
276 | 302 |
277 protected { | 303 protected { |
304 char[] secName; // name of this option setting; set null after translation is loaded | |
278 OptionChanges optionChanges; // all changes to options (for saving) | 305 OptionChanges optionChanges; // all changes to options (for saving) |
279 | 306 |
280 // The "pointer lists", e.g. char[]*[ID] optscharA; | 307 // The "pointer lists", e.g. char[]*[ID] optscharA; |
281 mixin (PLists!(TYPES)); | 308 mixin (PLists!(TYPES)); //FIXME adds unused optsbool |
309 ValueContent[char[]] opts; // generic list of option values | |
282 } | 310 } |
283 | 311 |
284 //BEGIN Mergetag loading/saving code | 312 //BEGIN Mergetag loading/saving code |
285 void addTag (char[] tp, ID id, char[] dt) { | 313 void addTag (char[] tp, ID id, char[] dt) { |
286 mixin(addTagMixin!(TYPES).addTagMixin); | 314 mixin(addTagMixin!(TYPES).addTagMixin); |
293 //END Non-static | 321 //END Non-static |
294 | 322 |
295 | 323 |
296 //BEGIN Templates: impl & optionsThis | 324 //BEGIN Templates: impl & optionsThis |
297 private { | 325 private { |
326 // Replace, e.g., bool, with BoolContent | |
327 template contentName(A) { | |
328 static if (is(A == bool)) { | |
329 const char[] contentName = "BoolContent"; | |
330 } else static if (is(A == int)) { | |
331 const char[] contentName = "int";// no IntContent yet | |
332 } else static if (is(A == double)) { | |
333 const char[] contentName = "double"; | |
334 } else static if (is(A == char[])) { | |
335 const char[] contentName = "char[]"; | |
336 } else | |
337 static assert (false, "unsuppurted type: "~ A); | |
338 } | |
298 // Return index of first comma, or halts if not found. | 339 // Return index of first comma, or halts if not found. |
299 template cIndex(char[] A) { | 340 template cIndex(char[] A) { |
300 static if (A.length == 0) | 341 static if (A.length == 0) |
301 static assert (false, "Error in implementation"); | 342 static assert (false, "Error in implementation"); |
302 else static if (A[0] == ',') | 343 else static if (A[0] == ',') |
311 else static if (A[0] == ';') | 352 else static if (A[0] == ';') |
312 const size_t scIndex = 0; | 353 const size_t scIndex = 0; |
313 else | 354 else |
314 const size_t scIndex = 1 + scIndex!(A[1..$]); | 355 const size_t scIndex = 1 + scIndex!(A[1..$]); |
315 } | 356 } |
316 // Look for "type symbols;" in A and return symbols as a comma separated list of names | 357 /* Look for "type symbols;" in A and return symbols as a comma separated list of names |
317 // (even if type is encountered more than once). Output may contain spaces and, if | 358 (even if type is encountered more than once). Output may contain spaces and will have a |
318 // non-empty, will contain a trailing comma. Assumes scIndex always returns less than A.$. | 359 trailing comma unless no match was found in which case an empty string is returned. |
360 Assumes scIndex always returns less than A.$ . */ | |
319 template parseT(char[] type, char[] A) { | 361 template parseT(char[] type, char[] A) { |
320 static if (A.length < type.length + 1) // end of input, no match | 362 static if (A.length < type.length + 1) // end of input, no match |
321 const char[] parseT = ""; | 363 const char[] parseT = ""; |
322 else static if (A[0] == ' ') // leading whitespace: skip | 364 else static if (A[0] == ' ') // leading whitespace: skip |
323 const char[] parseT = parseT!(type, A[1..$]); | 365 const char[] parseT = parseT!(type, A[1..$]); |
325 const char[] parseT = A[type.length+1 .. scIndex!(A)] ~ "," ~ | 367 const char[] parseT = A[type.length+1 .. scIndex!(A)] ~ "," ~ |
326 parseT!(type, A[scIndex!(A)+1 .. $]); | 368 parseT!(type, A[scIndex!(A)+1 .. $]); |
327 else // no match | 369 else // no match |
328 const char[] parseT = parseT!(type, A[scIndex!(A)+1 .. $]); | 370 const char[] parseT = parseT!(type, A[scIndex!(A)+1 .. $]); |
329 } | 371 } |
330 // May have a trailing comma. Assumes cIndex always returns less than A.$. | 372 // May have a trailing comma. Assumes cIndex always returns less than A.$ . |
331 template aaVars(char[] A) { | 373 template aaVars(char[] A) { |
332 static if (A.length == 0) | 374 static if (A.length == 0) |
333 const char[] aaVars = ""; | 375 const char[] aaVars = ""; |
334 else static if (A[0] == ' ') | 376 else static if (A[0] == ' ') |
335 const char[] aaVars = aaVars!(A[1..$]); | 377 const char[] aaVars = aaVars!(A[1..$]); |
336 else | 378 else |
337 const char[] aaVars = "\""~A[0..cIndex!(A)]~"\"[]:&"~A[0..cIndex!(A)] ~ "," ~ | 379 const char[] aaVars = "\""~A[0..cIndex!(A)]~"\"[]:&"~A[0..cIndex!(A)] ~ "," ~ |
338 aaVars!(A[cIndex!(A)+1..$]); | 380 aaVars!(A[cIndex!(A)+1..$]); |
381 } | |
382 // May have a trailing comma. Assumes cIndex always returns less than A.$ . | |
383 template aaVarsBool(char[] A) {//FIXME | |
384 static if (A.length == 0) | |
385 const char[] aaVarsBool = ""; | |
386 else static if (A[0] == ' ') | |
387 const char[] aaVarsBool = aaVarsBool!(A[1..$]); | |
388 else | |
389 const char[] aaVarsBool = "\""~A[0..cIndex!(A)]~"\"[]:"~A[0..cIndex!(A)] ~ "," ~ | |
390 aaVarsBool!(A[cIndex!(A)+1..$]); | |
339 } | 391 } |
340 // strip Trailing Comma | 392 // strip Trailing Comma |
341 template sTC(char[] A) { | 393 template sTC(char[] A) { |
342 static if (A.length && A[$-1] == ',') | 394 static if (A.length && A[$-1] == ',') |
343 const char[] sTC = A[0..$-1]; | 395 const char[] sTC = A[0..$-1]; |
351 else static if (A[0] == ' ') | 403 else static if (A[0] == ' ') |
352 const char[] listOrNull = listOrNull!(A[1..$]); | 404 const char[] listOrNull = listOrNull!(A[1..$]); |
353 else | 405 else |
354 const char[] listOrNull = "["~A~"]"; | 406 const char[] listOrNull = "["~A~"]"; |
355 } | 407 } |
408 // if B is empty return an empty string otherswise return what's below: | |
409 template catOrNothing(char[] A,char[] B) { | |
410 static if (B.length) | |
411 const char[] catOrNothing = A~` `~sTC!(B)~";\n"; | |
412 else | |
413 const char[] catOrNothing = ``; | |
414 } | |
415 // foreach decl... | |
416 template createBCs(char[] A) { | |
417 static if (A.length == 0) | |
418 const char[] createBCs = ""; | |
419 else static if (A[0] == ' ') | |
420 const char[] createBCs = createBCs!(A[1..$]); | |
421 else | |
422 const char[] createBCs = A[0..cIndex!(A)]~ " = new BoolContent (false);\n"~ | |
423 createBCs!(A[cIndex!(A)+1..$]); | |
424 } | |
356 // for recursing on TYPES | 425 // for recursing on TYPES |
357 template optionsThisInternal(char[] A, B...) { | 426 template optionsThisInternal(char[] A, B...) { |
358 static if (B.length) { | 427 static if (B.length) { |
428 static if (is(B[0] == bool)) {//FIXME | |
429 const char[] optionsThisInternal = createBCs!(parseT!(B[0].stringof,A))~ | |
430 `opts = `~listOrNull!(sTC!(aaVarsBool!(parseT!(B[0].stringof,A))))~";\n" ~ | |
431 optionsThisInternal!(A,B[1..$]); | |
432 } else | |
359 const char[] optionsThisInternal = `opts`~TName!(B[0])~` = `~listOrNull!(sTC!(aaVars!(parseT!(B[0].stringof,A))))~";\n" ~ optionsThisInternal!(A,B[1..$]); | 433 const char[] optionsThisInternal = `opts`~TName!(B[0])~` = `~listOrNull!(sTC!(aaVars!(parseT!(B[0].stringof,A))))~";\n" ~ optionsThisInternal!(A,B[1..$]); |
360 } else | 434 } else |
361 const char[] optionsThisInternal = ``; | 435 const char[] optionsThisInternal = ``; |
362 } | 436 } |
437 template declValsInternal(char[] A, B...) { | |
438 static if (B.length) { | |
439 const char[] declValsInternal = catOrNothing!(contentName!(B[0]),parseT!(B[0].stringof,A)) ~ declValsInternal!(A,B[1..$]); | |
440 } else | |
441 const char[] declValsInternal = ``; | |
442 } | |
363 } protected { | 443 } protected { |
444 /** Declares the values. | |
445 * | |
446 * Basic types are replaced with a ValueContent class to keep the option synchronized and | |
447 * generalize use. */ | |
448 template declVals(char[] A) { | |
449 const char[] declVals = declValsInternal!(A, TYPES,bool); | |
450 } | |
364 /** Produces the implementation code to go in the constuctor. */ | 451 /** Produces the implementation code to go in the constuctor. */ |
365 template optionsThis(char[] A) { | 452 template optionsThis(char[] A) { |
366 const char[] optionsThis = | 453 const char[] optionsThis = |
367 "optionChanges = new OptionChanges;\n" ~ | 454 "optionChanges = new OptionChanges;\n" ~ |
368 optionsThisInternal!(A,TYPES); | 455 optionsThisInternal!(A,TYPES,bool); |
369 } | 456 } |
370 /+ Needs too many custom parameters to be worth it? Plus makes class less readable. | 457 /+ Needs too many custom parameters to be worth it? Plus makes class less readable. |
371 /** Produces the implementation code to go in the static constuctor. */ | 458 /** Produces the implementation code to go in the static constuctor. */ |
372 template optClassAdd(char[] symb) { | 459 template optClassAdd(char[] symb) { |
373 const char[] optClassAdd = symb ~ "=new "~classinfo(this).name~";\n";//Options.addOptionsClass("~symb~", );\n"; | 460 const char[] optClassAdd = symb ~ "=new "~classinfo(this).name~";\n";//Options.addOptionsClass("~symb~", );\n"; |
379 * mixin (impl ("bool a, b; int i;")); | 466 * mixin (impl ("bool a, b; int i;")); |
380 * --- | 467 * --- |
381 * | 468 * |
382 * In case this() needs to be customized, mixin(impl!(A)) is equivalent to: | 469 * In case this() needs to be customized, mixin(impl!(A)) is equivalent to: |
383 * --- | 470 * --- |
384 * mixin (A~` | 471 * mixin (declVals!(A)~` |
385 this () { | 472 this () { |
386 `~optionsThis!(A)~` | 473 `~optionsThis!(A)~` |
387 }`); | 474 }`); |
388 * --- | 475 * --- |
389 * | 476 * |
393 * necessary. | 480 * necessary. |
394 * | 481 * |
395 * Extending: mixins could also be used for the static this() {...} or even the whole | 482 * Extending: mixins could also be used for the static this() {...} or even the whole |
396 * class, but doing so would rather decrease readability of any implementation. */ | 483 * class, but doing so would rather decrease readability of any implementation. */ |
397 template impl(char[] A /+, char[] symb+/) { | 484 template impl(char[] A /+, char[] symb+/) { |
398 const char[] impl = A~"\nthis(){\n"~optionsThis!(A)~"}"; | 485 const char[] impl = declVals!(A)~"\nthis(){\n"~optionsThis!(A)~"}"; |
399 // ~"\nstatic this(){\n"~optClassAdd!(symb)~"}" | 486 // ~"\nstatic this(){\n"~optClassAdd!(symb)~"}" |
400 } | 487 } |
401 } | 488 } |
402 //END Templates: impl & optionsThis | 489 //END Templates: impl & optionsThis |
403 } | 490 } |
464 * | 551 * |
465 * To create a new Options sub-class, just copy, paste and adjust. | 552 * To create a new Options sub-class, just copy, paste and adjust. |
466 */ | 553 */ |
467 | 554 |
468 /** A home for all miscellaneous options, at least for now. */ | 555 /** A home for all miscellaneous options, at least for now. */ |
469 OptionsMisc miscOpts; | 556 MiscOptions miscOpts; |
470 class OptionsMisc : Options { | 557 class MiscOptions : Options { |
471 mixin (impl!("bool exitImmediately; int maxThreads, logOptions; double pollInterval; char[] L10n, a,b,c,g,z;")); | 558 const A = "bool exitImmediately; int maxThreads, logOptions; double pollInterval; char[] L10n;"; |
559 //pragma (msg, impl!(A)); | |
560 mixin (impl!(A)); | |
472 | 561 |
473 void validate() { | 562 void validate() { |
474 // Try to enforce sensible values, whilst being reasonably flexible: | 563 // Try to enforce sensible values, whilst being reasonably flexible: |
475 if (miscOpts.maxThreads < 1 || miscOpts.maxThreads > 64) { | 564 if (miscOpts.maxThreads < 1 || miscOpts.maxThreads > 64) { |
476 logger.warn ("maxThreads must be in the range 1-64. Defaulting to 4."); | 565 logger.warn ("maxThreads must be in the range 1-64. Defaulting to 4."); |
479 if (pollInterval !<= 1.0 || pollInterval !>= 0.0) | 568 if (pollInterval !<= 1.0 || pollInterval !>= 0.0) |
480 set!(double) ("pollInterval", 0.01); | 569 set!(double) ("pollInterval", 0.01); |
481 } | 570 } |
482 | 571 |
483 static this() { | 572 static this() { |
484 miscOpts = new OptionsMisc; | 573 miscOpts = new MiscOptions; |
485 Options.addOptionsClass (miscOpts, "misc"); | 574 Options.addOptionsClass (miscOpts, "MiscOptions"); |
486 } | 575 } |
487 } | 576 } |