Mercurial > projects > mde
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mde/setup/InitStage.d Thu Sep 11 11:33:51 2008 +0100 @@ -0,0 +1,110 @@ +/* LICENSE BLOCK +Part of mde: a Modular D game-oriented Engine +Copyright © 2007-2008 Diggory Hardy + +This program is free software: you can redistribute it and/or modify it under the terms +of the GNU General Public License as published by the Free Software Foundation, either +version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/************************************************************************************************** + * The infrastructure for handling external startup/shutdown code. + *************************************************************************************************/ +module mde.setup.InitStage; + +public import mde.setup.exception; +import tango.util.container.HashMap; +import tango.util.log.Log : Log, Logger; + + // use as hash type for better performance than char[] + alias uint StageName; + StageName toStageName (char[4] x) { + return *cast(uint*) x.ptr; // NOTE - little hack to read as a uint + } + + /** Initialization and cleanup functions for one stage. + * + * The init and cleanup functions should return the new StageState. Returning ERROR does not + * indicate that the program should abort but that the module in question is not usable and + * that init & cleanup should not be called. Throwing an exception sets the state to ERROR (or + * the value passed to an InitStageException) and indicates that the program should abort. + * If the program aborts, all stages with state ACTIVE have their cleanup run (as with a normal + * shutdown). + * + * Not setting a cleanup function will result in the state being left at ACTIVE on shutdown, so + * if a second initialization occurs (not currently possible), init will not be re-run. */ + struct InitStage { + StageState delegate() init; // the initialization function + StageState delegate() cleanup; // the associated cleanup function + StageName[] depends; // anything function depends on completing before its run + StageName[] rdepends; // reverse dependencies, set during init + StageState state = StageState.INACTIVE; + } + + /// Add a stage to be initialized. + void addInitStage (char[4] name, InitStage* stage) { + stages[toStageName(name)] = stage; + } + /// Add a stage to be initialized. + void addInitStage (char[4] name, StageState function() init, StageState function() cleanup = null, char[4][] depends = null) { + StageState delegate() i,c; + i.funcptr = init; + c.funcptr = cleanup; + addInitStage (name, i, c, depends); + } + /// Add a stage to be initialized. + void addInitStage (char[4] name, StageState delegate() init, StageState delegate() cleanup = null, char[4][] depends = null) { + InitStage* stage = new InitStage; + (*stage).init = init; + stage.cleanup = cleanup; + stage.depends.length = depends.length; + foreach (i,d; depends) + stage.depends[i] = toStageName(d); + stages[toStageName(name)] = stage; + } + + package HashMap!(StageName,InitStage*) stages; + + static this () { + stages = new typeof(stages); + logger = Log.getLogger ("mde.setup.InitStage"); + } + Logger logger; + + + +/************************************************************************************************** + * Initialization functions. + *************************************************************************************************/ +import imde = mde.imde; +import mde.input.Input; +import mde.setup.Screen; +import mde.input.joystick; +import mde.font.font; + +static this() { + addInitStage ("Inpt", &initInput); + addInitStage ("SSDL", &Screen.init, &Screen.cleanup ); + addInitStage ("SJoy", &openJoysticks, &closeJoysticks, ["SSDL"]); + addInitStage ("SWnd", &Screen.initWindow, null, ["SSDL"]); + addInitStage ("Font", &FontStyle.initialize, &FontStyle.cleanup); +} + +StageState initInput () { + imde.input.loadConfig ("input"); + + // Quit on escape. NOTE: quit via SDL_QUIT event is handled completely independently! + imde.input.addButtonCallback (cast(Input.inputID) 0x0u, delegate void(Input.inputID i, bool b) { + if (b) { + logger.info ("Quiting..."); + imde.run = false; + } + } ); + return StageState.ACTIVE; +}