Mercurial > projects > mde
annotate mde/scheduler/Init.d @ 30:467c74d4804d
Major changes to the scheduler, previously only used by the main loop.
Revamped Scheduler. Functions can be removed, have multiple schedules, have their scheduling changed, etc.
Scheduler has a unittest. Checked all pass.
Main loop scheduler moved to mde. Draw-on-demand currently disabled, simplifying this.
Made mtunitest.d remove the temporary file it uses afterwards.
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Mon, 28 Apr 2008 10:59:47 +0100 |
parents | f985c28c0ec9 |
children | baa87e68d7dc |
rev | line source |
---|---|
20 | 1 /* LICENSE BLOCK |
2 Part of mde: a Modular D game-oriented Engine | |
3 Copyright © 2007-2008 Diggory Hardy | |
4 | |
26
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify it under the terms |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
6 of the GNU General Public License as published by the Free Software Foundation, either |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
7 version 2 of the License, or (at your option) any later version. |
20 | 8 |
9 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; | |
10 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
11 See the GNU General Public License for more details. | |
12 | |
26
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
13 You should have received a copy of the GNU General Public License |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
20 | 15 |
16 /************************************************************************************************** | |
17 * Initialisation setup and exit cleanup module. | |
18 * | |
19 * This module provides an infrastructure for handling much of the initialisation and | |
20 * deinitialisation of the program. It does not, however, provide much of the (de)initialisation | |
21 * code; with the exception of that for the logger. | |
22 *************************************************************************************************/ | |
23 module mde.scheduler.Init; | |
24 | |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
25 import mde.scheduler.InitFunctions; |
20 | 26 import mde.scheduler.exception; |
27 | |
28 import mde.options; | |
29 import paths = mde.resource.paths; | |
30 import mde.exception; | |
31 | |
32 // tango imports | |
33 import tango.core.Thread; | |
34 import tango.core.Exception; | |
35 import tango.stdc.stringz : fromStringz; | |
36 import tango.util.log.Log : Log, Logger; | |
37 import tango.util.log.ConsoleAppender : ConsoleAppender; | |
38 | |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
39 //version = SwitchAppender; |
20 | 40 version (SwitchAppender) { // My own variation, currently just a test |
41 import tango.util.log.SwitchingFileAppender : SwitchingFileAppender; | |
42 } else { | |
43 import tango.util.log.RollingFileAppender : RollingFileAppender; | |
44 } | |
45 | |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
46 // Derelict imports |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
47 import derelict.opengl.gl; |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
48 import derelict.sdl.sdl; |
30
467c74d4804d
Major changes to the scheduler, previously only used by the main loop.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
29
diff
changeset
|
49 import derelict.freetype.ft; |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
50 import derelict.util.exception; |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
51 |
20 | 52 /** |
53 * Static CTOR | |
54 * | |
55 * This should handle a minimal amount of functionality where useful. For instance, configuring the | |
56 * logger here and not in Init allows unittests to use the logger. | |
57 */ | |
58 static this() | |
59 { | |
60 // Find/create paths: | |
61 try { | |
62 paths.resolvePaths(); | |
63 } catch (Exception e) { | |
28
b5fadd8d930b
Small addition to GUI, paths work-around for Windows.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
26
diff
changeset
|
64 // NOTE: an exception thrown here cannot be caught by main()! |
20 | 65 throw new InitException ("Resolving paths failed: " ~ e.msg); |
66 } | |
67 | |
68 // Set up the logger: | |
69 { | |
70 // Where logging is done to is determined at compile-time, currently just via static ifs. | |
71 Logger root = Log.getRootLogger(); | |
26
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
72 |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
73 static if (true ) { // Log to files (first appender so root seperator messages don't show on console) |
20 | 74 version (SwitchAppender) { |
75 root.addAppender (new SwitchingFileAppender (paths.logDir~"/log-.txt", 5)); | |
76 } else { | |
77 // Use 2 log files with a maximum size of 1 MB: | |
78 root.addAppender (new RollingFileAppender (paths.logDir~"/log-.txt", 2, 1024*1024)); | |
26
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
79 root.info (""); // some kind of separation between runs |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
80 root.info (""); |
20 | 81 } |
82 } | |
26
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
83 static if (true ) { // Log to the console |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
84 root.addAppender(new ConsoleAppender); |
611f7b9063c6
Changed the licensing and removed a few dead files.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
25
diff
changeset
|
85 } |
20 | 86 |
87 // Set the level here, but set it again once options have been loaded: | |
88 debug root.setLevel(root.Level.Trace); | |
89 else root.setLevel(root.Level.Info); | |
90 } | |
91 } | |
92 static ~this() | |
93 { | |
94 } | |
95 | |
96 /** | |
97 * Init class | |
98 * | |
99 * A scope class created at beginning of the program and destroyed at the end; thus the CTOR | |
100 * handles program initialisation and the DTOR handles program cleanup. | |
101 */ | |
102 scope class Init | |
103 { | |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
104 //private bool failure = false; // set true on failure during init, so that clean |
20 | 105 private static Logger logger; |
106 static this() { | |
107 logger = Log.getLogger ("mde.scheduler.Init.Init"); | |
108 } | |
109 | |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
110 /** this() − initialisation |
20 | 111 * |
112 * Runs general initialisation code, in a threaded manner where this isn't difficult. | |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
113 * If any init fails, cleanup is still handled by ~this(). |
20 | 114 * |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
115 * Init order: 1. Pre-init (loads components needed by most init functions). 2. Dynamic library |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
116 * loading (load any dynamic libraries first, so that if loading fails nothing else need be |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
117 * done). 3. Init functions (threaded functions handling the rest of initialisation). |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
118 */ |
20 | 119 /* In a single-threaded function this could be done with: |
120 * scope(failure) cleanup; | |
121 * This won't work with a threaded init function since any threads completing succesfully will | |
122 * not clean-up, and a fixed list of clean-up functions cannot be used since clean-up functions | |
123 * must not run where the initialisation functions have failed. | |
124 * Hence a list of clean-up functions is built similarly to scope(failure) --- see addCleanupFct. | |
125 */ | |
126 this() | |
127 { | |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
128 debug logger.trace ("Init: starting"); |
20 | 129 |
130 //BEGIN Pre-init (stage init0) | |
131 /* Load options now. Don't load in a thread since: | |
132 * Loading should be fast | |
133 * Most work is probably disk access | |
134 * It's a really good idea to let the options apply to all other loading. */ | |
135 try { | |
136 Options.load(); | |
137 } catch (optionsLoadException e) { | |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
138 throw new InitException ("Loading options failed: " ~ e.msg); |
20 | 139 } |
140 | |
141 // Now re-set the logging level: | |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
142 Log.getRootLogger.setLevel (cast(Log.Level) miscOpts.logLevel, true); // set the stored log level |
20 | 143 //END Pre-init |
144 | |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
145 debug logger.trace ("Init: pre-init done"); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
146 |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
147 //BEGIN Load dynamic libraries |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
148 /* Can be done by init functions but much neater to do here. |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
149 * Also means that init functions aren't run if a library fails to load. */ |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
150 try { |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
151 DerelictSDL.load(); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
152 DerelictGL.load(); |
30
467c74d4804d
Major changes to the scheduler, previously only used by the main loop.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
29
diff
changeset
|
153 DerelictFT.load(); |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
154 } catch (DerelictException de) { |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
155 logger.fatal ("Loading dynamic library failed:"); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
156 logger.fatal (de.msg); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
157 |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
158 throw new InitException ("Loading dynamic libraries failed (see above)."); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
159 } |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
160 //END Load dynamic libraries |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
161 |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
162 debug logger.trace ("Init: dynamic libraries loaded"); |
20 | 163 |
164 //BEGIN Init (stages init2, init4) | |
165 /* Call init functions. | |
166 * | |
167 * Current method is to try using threads, and on failure assume no threads were actually | |
168 * created and run functions in a non-threaded manner. */ | |
169 | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
170 try { |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
171 if (runStageThreaded (init)) runStageForward (init); |
20 | 172 } |
173 catch (InitStageException) { // This init stage failed. | |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
174 // FIXME: check DTOR still runs |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
175 throw new InitException ("An init function failed (see above message(s))"); |
20 | 176 } |
177 //END Init | |
178 | |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
179 debug logger.trace ("Init: done"); |
20 | 180 } |
181 | |
182 /** DTOR - runs cleanup functions. */ | |
183 ~this() | |
184 { | |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
185 debug logger.trace ("Cleanup: starting"); |
20 | 186 |
187 Options.save(); // save options... do so here for now | |
188 | |
25
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
189 // General cleanup: |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
190 try { |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
191 if (runStageThreaded (cleanup)) runStageReverse (cleanup); |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
192 } |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
193 catch (InitStageException) { |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
194 // Nothing else to do but report: |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
195 logger.error ("One or more cleanup functions failed!"); |
2c28ee04a4ed
Some minor and some futile efforts.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
24
diff
changeset
|
196 } |
20 | 197 |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
198 debug logger.trace ("Cleanup: done"); |
20 | 199 } |
200 | |
201 | |
202 //BEGIN runStage... | |
203 private static { | |
204 /* The following three functions, runStage*, each run all functions in a stage in some order, | |
205 * catching any exceptions thrown by the functions (although this isn't guaranteed for threads), | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
206 * and throw an InitStageException on initFailure. */ |
20 | 207 |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
208 const LOG_IF_MSG = "Init function "; |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
209 const LOG_CF_MSG = "Cleanup function "; |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
210 const LOG_F_START = " - running"; |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
211 const LOG_F_END = " - completed"; |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
212 const LOG_F_FAIL = " - failed: "; |
20 | 213 /* Runs all functions consecutively, first-to-last. |
214 * If any function fails, halts immediately. */ | |
215 void runStageForward (InitStage s) { | |
216 foreach (func; s.funcs) { | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
217 if (initFailure) break; |
20 | 218 try { |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
219 debug logger.trace (LOG_IF_MSG ~ func.name ~ LOG_F_START); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
220 func.func(); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
221 debug logger.trace (LOG_IF_MSG ~ func.name ~ LOG_F_END); |
20 | 222 } catch (Exception e) { |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
223 logger.fatal (LOG_IF_MSG ~ func.name ~ LOG_F_FAIL ~ |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
224 ((e.msg is null || e.msg == "") ? "(no failure message)" : e.msg) ); |
20 | 225 |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
226 setInitFailure(); |
20 | 227 } |
228 } | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
229 |
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
230 if (initFailure) throw new InitStageException; // Problem running; abort and cleanup from here. |
20 | 231 } |
232 /* Runs all functions consecutively, last-to-first. | |
233 * If any function fails, continue until all have been run. */ | |
234 void runStageReverse (InitStage s) { | |
235 foreach_reverse (func; s.funcs) { | |
236 try { | |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
237 debug logger.trace (LOG_CF_MSG ~ func.name ~ LOG_F_START); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
238 func.func(); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
239 debug logger.trace (LOG_CF_MSG ~ func.name ~ LOG_F_END); |
20 | 240 } catch (Exception e) { |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
241 logger.fatal (LOG_CF_MSG ~ func.name ~ LOG_F_FAIL ~ |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
242 ((e.msg is null || e.msg == "") ? "(no failure message)" : e.msg) ); |
20 | 243 |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
244 setInitFailure(); |
20 | 245 } |
246 } | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
247 if (initFailure) throw new InitStageException; // Problem running; abort and cleanup from here. |
20 | 248 } |
249 /* Tries running functions in a threaded way. Returns false if successful, true if not but | |
250 * functions should be run without threads. */ | |
251 bool runStageThreaded (InitStage s) { | |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
252 if (!miscOpts.useThreads) return true; // Use unthreaded route instead |
20 | 253 |
254 ThreadGroup tg; | |
255 try { // creating/starting threads could fail | |
256 tg = new ThreadGroup; | |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
257 foreach (func; s.funcs) { // Start all threads |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
258 debug logger.trace (LOG_IF_MSG ~ func.name ~ LOG_F_START); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
259 tg.create(func.func); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
260 debug logger.trace (LOG_IF_MSG ~ func.name ~ LOG_F_END); |
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
261 } |
20 | 262 } catch (ThreadException e) { // Problem with threading; try without threads |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
263 logger.error ("Caught ThreadException while trying to create threads:"); |
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
264 logger.error (e.msg); |
29
f985c28c0ec9
A new GUI widget plus changes to the init system.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
28
diff
changeset
|
265 logger.info ("Will disable threads and continue, assuming no threads were created."); |
20 | 266 |
24
32eff0e01c05
Only locally-changed options are stored in user-config now. Log levels revised.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
21
diff
changeset
|
267 Options.setBool("misc", "useThreads", false); // Disable threads entirely |
20 | 268 return true; // Try again without threads |
269 } | |
270 | |
271 /* Wait for all threads to complete. | |
272 * | |
273 * If something went wrong, we still need to do this before cleaning up. | |
274 */ | |
275 foreach (t; tg) { | |
276 try { | |
277 t.join (true); | |
278 } catch (Exception e) { | |
279 // Relying on catching exceptions thrown by other threads is a bad idea. | |
280 // Hence all threads should catch their own exceptions and return safely. | |
281 | |
282 logger.fatal ("Unhandled exception from Init function:"); | |
283 logger.fatal (e.msg); | |
284 | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
285 setInitFailure (); // abort (but join other threads first) |
20 | 286 } |
287 } | |
21
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
288 |
a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
Diggory Hardy <diggory.hardy@gmail.com>
parents:
20
diff
changeset
|
289 if (initFailure) throw new InitStageException; // Problem running; abort and cleanup from here. |
20 | 290 return false; // Done successfully |
291 } | |
292 } | |
293 //END runStage... | |
294 | |
295 debug (mdeUnitTest) unittest { | |
296 /* Fake init and cleanup. Use unittest-specific init and cleanup InitStages to avoid | |
297 * messing other init/cleanup up. */ | |
298 static InitStage initUT, cleanupUT; | |
299 | |
300 static bool initialised = false; | |
301 static void cleanupFunc1 () { | |
302 initialised = false; | |
303 } | |
304 static void cleanupFunc2 () { | |
305 assert (initialised == true); | |
306 } | |
307 | |
308 static void initFunc () { | |
309 initialised = true; | |
30
467c74d4804d
Major changes to the scheduler, previously only used by the main loop.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
29
diff
changeset
|
310 cleanupUT.addFunc (&cleanupFunc1, "UT cleanup 1"); |
467c74d4804d
Major changes to the scheduler, previously only used by the main loop.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
29
diff
changeset
|
311 cleanupUT.addFunc (&cleanupFunc2, "UT cleanup 2"); |
20 | 312 } |
313 | |
30
467c74d4804d
Major changes to the scheduler, previously only used by the main loop.
Diggory Hardy <diggory.hardy@gmail.com>
parents:
29
diff
changeset
|
314 initUT.addFunc (&initFunc, "UT init"); |
20 | 315 |
316 runStageForward (initUT); | |
317 assert (initialised); | |
318 | |
319 runStageReverse (cleanupUT); | |
320 assert (!initialised); | |
321 | |
322 logger.info ("Unittest complete."); | |
323 } | |
324 } |