Mercurial > projects > mde
view 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 source
/* 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; }