comparison mde/setup/InitStage.d @ 85:56c0ddd90193

Intermediate commit (not stable). Changes to init system.
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 11 Sep 2008 11:33:51 +0100
parents mde/setup/init2.d@e0f1ec7fe73a
children 4d5d53e4f881
comparison
equal deleted inserted replaced
84:e0f1ec7fe73a 85:56c0ddd90193
1 /* LICENSE BLOCK
2 Part of mde: a Modular D game-oriented Engine
3 Copyright © 2007-2008 Diggory Hardy
4
5 This program is free software: you can redistribute it and/or modify it under the terms
6 of the GNU General Public License as published by the Free Software Foundation, either
7 version 2 of the License, or (at your option) any later version.
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
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */
15
16 /**************************************************************************************************
17 * The infrastructure for handling external startup/shutdown code.
18 *************************************************************************************************/
19 module mde.setup.InitStage;
20
21 public import mde.setup.exception;
22 import tango.util.container.HashMap;
23 import tango.util.log.Log : Log, Logger;
24
25 // use as hash type for better performance than char[]
26 alias uint StageName;
27 StageName toStageName (char[4] x) {
28 return *cast(uint*) x.ptr; // NOTE - little hack to read as a uint
29 }
30
31 /** Initialization and cleanup functions for one stage.
32 *
33 * The init and cleanup functions should return the new StageState. Returning ERROR does not
34 * indicate that the program should abort but that the module in question is not usable and
35 * that init & cleanup should not be called. Throwing an exception sets the state to ERROR (or
36 * the value passed to an InitStageException) and indicates that the program should abort.
37 * If the program aborts, all stages with state ACTIVE have their cleanup run (as with a normal
38 * shutdown).
39 *
40 * Not setting a cleanup function will result in the state being left at ACTIVE on shutdown, so
41 * if a second initialization occurs (not currently possible), init will not be re-run. */
42 struct InitStage {
43 StageState delegate() init; // the initialization function
44 StageState delegate() cleanup; // the associated cleanup function
45 StageName[] depends; // anything function depends on completing before its run
46 StageName[] rdepends; // reverse dependencies, set during init
47 StageState state = StageState.INACTIVE;
48 }
49
50 /// Add a stage to be initialized.
51 void addInitStage (char[4] name, InitStage* stage) {
52 stages[toStageName(name)] = stage;
53 }
54 /// Add a stage to be initialized.
55 void addInitStage (char[4] name, StageState function() init, StageState function() cleanup = null, char[4][] depends = null) {
56 StageState delegate() i,c;
57 i.funcptr = init;
58 c.funcptr = cleanup;
59 addInitStage (name, i, c, depends);
60 }
61 /// Add a stage to be initialized.
62 void addInitStage (char[4] name, StageState delegate() init, StageState delegate() cleanup = null, char[4][] depends = null) {
63 InitStage* stage = new InitStage;
64 (*stage).init = init;
65 stage.cleanup = cleanup;
66 stage.depends.length = depends.length;
67 foreach (i,d; depends)
68 stage.depends[i] = toStageName(d);
69 stages[toStageName(name)] = stage;
70 }
71
72 package HashMap!(StageName,InitStage*) stages;
73
74 static this () {
75 stages = new typeof(stages);
76 logger = Log.getLogger ("mde.setup.InitStage");
77 }
78 Logger logger;
79
80
81
82 /**************************************************************************************************
83 * Initialization functions.
84 *************************************************************************************************/
85 import imde = mde.imde;
86 import mde.input.Input;
87 import mde.setup.Screen;
88 import mde.input.joystick;
89 import mde.font.font;
90
91 static this() {
92 addInitStage ("Inpt", &initInput);
93 addInitStage ("SSDL", &Screen.init, &Screen.cleanup );
94 addInitStage ("SJoy", &openJoysticks, &closeJoysticks, ["SSDL"]);
95 addInitStage ("SWnd", &Screen.initWindow, null, ["SSDL"]);
96 addInitStage ("Font", &FontStyle.initialize, &FontStyle.cleanup);
97 }
98
99 StageState initInput () {
100 imde.input.loadConfig ("input");
101
102 // Quit on escape. NOTE: quit via SDL_QUIT event is handled completely independently!
103 imde.input.addButtonCallback (cast(Input.inputID) 0x0u, delegate void(Input.inputID i, bool b) {
104 if (b) {
105 logger.info ("Quiting...");
106 imde.run = false;
107 }
108 } );
109 return StageState.ACTIVE;
110 }