# HG changeset patch # User Diggory Hardy # Date 1221237374 -3600 # Node ID 79d816b3e2d26b515976027b05211f402ff51490 # Parent 56c0ddd901934a1eaf4d9648746136a94d808c70 New InitStage system, Screen & Screen.Drawable, separate testing and guiDemo binaries. This (and the previous) commit are the result of several quite significant changes to mde. All the unittests run, but it hasn't had a huge amount of testing so don't be surprised if bugs show up. diff -r 56c0ddd90193 -r 79d816b3e2d2 codeDoc/jobs.txt --- a/codeDoc/jobs.txt Thu Sep 11 11:33:51 2008 +0100 +++ b/codeDoc/jobs.txt Fri Sep 12 17:36:14 2008 +0100 @@ -3,10 +3,7 @@ In progress: -why is nothing drawn until a resize? seems to be working now (??) -why isn't font texture drawn in mde? -why does mde&guiDemo hang on exit, only if no resize occurred? -wierd things with options.mtt (font section getting output twice) +Sometimes nothing is drawn until a resize, and fonts are blocks? External bug? CircularIterator unittest again! diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/file/deserialize.d --- a/mde/file/deserialize.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/file/deserialize.d Fri Sep 12 17:36:14 2008 +0100 @@ -525,7 +525,6 @@ dg(); } catch (Exception e) { r = true; - logger.trace ("Exception caught: "~e.msg); } return r; } diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/file/mergetag/Writer.d --- a/mde/file/mergetag/Writer.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/file/mergetag/Writer.d Fri Sep 12 17:36:14 2008 +0100 @@ -162,8 +162,6 @@ public this (char[] path, DataSet ds = null) { _path = path; _dataset = ds; - foreach (i,s; _dataset.sec) - debug logger.trace ("sec ID length: {}", i.length); } //END CTOR / DTOR @@ -180,38 +178,28 @@ if (!_dataset) throwMTErr ("write(): no Dataset available to write from!", new MTNoDataSetException ()); try { - debug logger.trace ("W.w: 1"); FileConduit conduit; // actual conduit; don't use directly when there's content in the buffer IBuffer buffer; // write strings directly to this (use opCall(void[]) ) - debug logger.trace ("W.w: 2"); // Open a conduit on the file: conduit = new FileConduit (_path, FileConduit.WriteCreate); scope(exit) conduit.close(); - debug logger.trace ("W.w: 3"); buffer = new Buffer(conduit); // And a buffer scope(exit) buffer.flush(); - debug logger.trace ("W.w: 4"); // Write the header: buffer ("{MT" ~ MTFormatVersion.CurrentString ~ "}" ~ Eol); - debug logger.trace ("W.w: 5"); if (_dataset.header !is null) writeSection (buffer, _dataset.header); - debug logger.trace ("W.w: 6"); // Write the rest: foreach (ID id, IDataSection sec; _dataset.sec) { - debug logger.trace ("W.w: 71"); writeSectionIdentifier (buffer, id); - debug logger.trace ("W.w: 72"); writeSection (buffer, sec); } - debug logger.trace ("W.w: 8"); buffer.flush(); - debug logger.trace ("W.w: 9"); } catch (IOException e) { throwMTErr ("Error writing to file: " ~ e.msg, new MTFileIOException); @@ -222,14 +210,8 @@ } private void writeSectionIdentifier (IBuffer buffer, ID id) { - debug logger.trace ("W.wSI: 0"); - debug logger.trace ("W.wSI: id ({})",id.length); - debug logger.trace ("W.wSI: Eol ({})",Eol.length); char[] tp = "{" ~ cast(char[])id ~ "}" ~ Eol; - debug logger.trace ("W.wSI: 0.1"); - debug logger.trace ("W.wSI: string ({}): {}",tp.length, tp); buffer (tp); - debug logger.trace ("W.wSI: 1"); } private void writeSection (IBuffer buffer, IDataSection sec) { diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/file/serialize.d --- a/mde/file/serialize.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/file/serialize.d Fri Sep 12 17:36:14 2008 +0100 @@ -311,7 +311,6 @@ dg(); } catch (Exception e) { r = true; - logger.trace ("Exception caught: "~e.msg); } return r; } diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/font/FontTexture.d --- a/mde/font/FontTexture.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/font/FontTexture.d Fri Sep 12 17:36:14 2008 +0100 @@ -329,7 +329,6 @@ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR); float[4] Cc = [ 1.0f, 1f, 1f, 1f ]; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Cc.ptr); - glColor3f (1f, 0f, 0f); glBegin (GL_QUADS); glTexCoord2f (0f, 0f); glVertex2i (0, 0); diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/font/font.d --- a/mde/font/font.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/font/font.d Fri Sep 12 17:36:14 2008 +0100 @@ -130,13 +130,10 @@ //FIXME: don't use GC for FontStyle resources /** Cleanup: delete all fonts. */ StageState cleanup () { - // Clear loaded fonts: + // Clear loaded fonts (each has an FT_Face object needing to be freed): foreach (fs; fonts) delete fs; - fonts = null; - delete fallback; - delete fontTex; // clear texture FT_Done_FreeType (library); // free the library return StageState.INACTIVE; @@ -226,7 +223,10 @@ * * This function will only actually update the cache if it is invalid, caused either by the * font being changed or if cache.cacheVer < 0. */ - void updateBlock (char[] str, ref TextBlock cache) { + void updateBlock (char[] str, ref TextBlock cache) + in { + debug assert (face, "FontStyle: face is null"); + } body { try { fontTex.updateCache (face, str, cache); } catch (Exception e) { @@ -259,7 +259,10 @@ * than this cache only serves as a small optimisation. However, the only way to get the size * of a text block is to use a TextBlock cache and update it, either with this function or with * the updateBlock function. */ - void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col) { + void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col) + in { + debug assert (face, "FontStyle: face is null"); + } body { try { fontTex.drawCache (face, str, cache, x, y, col); } catch (Exception e) { @@ -267,7 +270,10 @@ } } /** ditto */ - void textBlock (int x, int y, char[] str, Colour col) { + void textBlock (int x, int y, char[] str, Colour col) + in { + debug assert (face, "FontStyle: face is null"); + } body { try { // Using the cache method for one-time use is slightly less than optimal, but doing so // isn't really recommended anyway (and maintaining two versions of fontTex.drawText @@ -283,7 +289,10 @@ * * Set the alpha by calling glColor*() first. See FontTexture.drawCacheA()'s documentation for * details. */ - void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col) { + void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col) + in { + debug assert (face, "FontStyle: face is null"); + } body { try { fontTex.drawCacheA (face, str, cache, x, y, col); } catch (Exception e) { @@ -297,9 +306,7 @@ } ~this () { - debug logger.trace ("{}.~this: start", this); FT_Done_Face (face); - debug logger.trace ("{}.~this: done", this); } private: diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/gui/WidgetManager.d --- a/mde/gui/WidgetManager.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/gui/WidgetManager.d Fri Sep 12 17:36:14 2008 +0100 @@ -50,7 +50,7 @@ * * Aside from the IWidgetManager methods, this class should be thread-safe. *************************************************************************************************/ -class WidgetManager : WidgetLoader, Screen.Drawable { +class WidgetManager : WidgetLoader, Screen.IDrawable { /** Construct a new widget manager. * * params: @@ -74,7 +74,6 @@ /** Draw the gui. */ void draw() { - debug logger.trace ("drawing; w,h = {},{}",w,h); synchronized(mutex) if (child) child.draw; @@ -117,7 +116,7 @@ } - void sizeEvent (int nw, int nh) { // Drawable function + void sizeEvent (int nw, int nh) { // IDrawable function mutex.lock; scope(exit) mutex.unlock; diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/input/Config.d --- a/mde/input/Config.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/input/Config.d Fri Sep 12 17:36:14 2008 +0100 @@ -161,16 +161,6 @@ if (c) configs[i] = c; // Check, because we don't want null entries in configs else debug logger.error ("Ended up with DataSection of wrong type; this should never happen."); } - - debug (MDE_CONFIG_DUMP) { - logger.trace ("Loaded {} config sections.", configs.length); - foreach (id, cfg; configs) { - logger.trace ("Section " ~ id ~ - ":\n\tbutton:\t\t" ~ parseFrom!(uint[][][uint])(cfg.button) ~ - "\n\taxis:\t\t" ~ parseFrom!(uint[][][uint])(cfg.axis) ~ - "\n\trelMotion:\t" ~ parseFrom!(uint[][][uint])(cfg.relMotion) ); - } - } } private this() {} // Private since this class should only be created from here. diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/input/joystick.d --- a/mde/input/joystick.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/input/joystick.d Fri Sep 12 17:36:14 2008 +0100 @@ -54,9 +54,7 @@ StageState closeJoysticks () { foreach (js; joysticks) { // FIXME: This sometimes causes a SIGSEGV (Address boundary error) when init fails. - debug logger.trace ("Closing joysticks (this sometimes fails when mde exits prematurely)"); if(js !is null) SDL_JoystickClose(js); // only close if successfully opened - debug logger.trace ("Done closing joysticks"); } return StageState.INACTIVE; } diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/lookup/Options.d --- a/mde/lookup/Options.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/lookup/Options.d Fri Sep 12 17:36:14 2008 +0100 @@ -136,7 +136,6 @@ assert (c !is null); // Instance must be created before calling addOptionsClass assert (((cast(ID) i) in subClasses) is null); // Don't allow a silent replacement } body { - debug logger.trace ("Adding Options subClass: "~i); subClasses[cast(ID) i] = c; } @@ -169,27 +168,18 @@ } void save () { if (!changed) return; // no changes to save - // Types: - // interface IDataSection {...} - // class Options {...} - // alias char[] ID; - // IDataSection[ID] ds.sec; - // Options[ID] subClasses; + debug logger.trace ("Saving options..."); + DataSet ds = new DataSet(); - foreach (id, subOpts; subClasses) { + foreach (id, subOpts; subClasses) ds.sec[id] = subOpts.optionChanges; - debug logger.trace ("Saving options section: "~id); - } - foreach (i,s; ds.sec) - debug logger.trace ("sec ID length: {}", i.length); - debug logger.trace ("0"); // Read locally-stored options try { IReader reader; reader = confDir.makeMTReader (fileName, PRIORITY.HIGH_ONLY, ds); reader.dataSecCreator = delegate IDataSection(ID id) { - debug logger.trace ("New section to save ignored: "~id); + debug logger.warn ("New section appearing in options.mtt during save (ignored & overwritten): "~id); return null; // All recognised sections are already in the dataset. }; reader.read; @@ -201,15 +191,9 @@ } try { - debug logger.trace ("1"); IWriter writer; - foreach (i,s; ds.sec) - debug logger.trace ("sec ID length: {}", i.length); - debug logger.trace ("2"); - writer = confDir.makeMTWriter (fileName, ds); // FIXME - sometimes SIGSEGV - debug logger.trace ("3"); - writer.write(); // FIXME - this is causing hang at exit! - debug logger.trace ("4"); + writer = confDir.makeMTWriter (fileName, ds); + writer.write(); } catch (Exception e) { logger.error ("Saving options aborted: "~e.msg); } diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/mde.d --- a/mde/mde.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/mde.d Fri Sep 12 17:36:14 2008 +0100 @@ -30,22 +30,45 @@ import tango.core.Thread : Thread; // Thread.sleep() import tango.time.Clock; // Clock.now() import tango.util.log.Log : Log, Logger; -debug (mdeUnitTest) { +debug (mdeUnitTest) { // These modules contain unittests which wouldn't be run otherwise. import mde.file.ssi; import mde.file.mergetag.mdeUT; } +//BEGIN A simple drawable to print a message in the window. +import mde.font.font; +class SimpleDrawable : Screen.IDrawable { + this () { + msg = "Welcome to mde.\nThis executable is only for testing, and\nas such doesn't do anything interesting."; + debug msg ~= "\nRunning in debug mode."; + font = FontStyle.get("default");// get the default or fallback font + } + void sizeEvent (int,int) {}; // Don't care what the size is + void draw () { + font.textBlock (16,32, msg, textCache, Colour.WHITE); + } + char[] msg; + FontStyle font; + TextBlock textCache; +} +//END A simple drawable to print a message in the window. + + int main(char[][] args) { + Logger logger = Log.getLogger ("mde.mde"); + // If compiled with unittests, notify that they completed and exit: debug (mdeUnitTest) { - Logger logger = Log.getLogger ("mde.mde"); logger.info ("Compiled unittests have completed; terminating."); return 0; } scope Init init = new Init(args); // initialize mde + // Note: must create the drawable after init, since it uses font (initialized in init). + Screen.addDrawable (new SimpleDrawable); // a drawable to print a message. + // Make sure pollInterval has a sane value. FIXME: get Options class to enforce range if (miscOpts.pollInterval !<= 1.0 || miscOpts.pollInterval !>= 0.0) miscOpts.set!(double) ("pollInterval", 0.01); diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/setup/Init.d --- a/mde/setup/Init.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/setup/Init.d Fri Sep 12 17:36:14 2008 +0100 @@ -257,7 +257,6 @@ } } } - debug logger.trace ("Added {} init/cleanup stages", toRun.size); int numWorking = miscOpts.numThreads; bool abortInit = false; Mutex toRunM = new Mutex; // synchronization on toRun, numWorking @@ -275,7 +274,6 @@ * if no other threads are working, notify waiting threads and terminate (finished) * When notified, threads start at 1. */ void initThreadFct () { - debug logger.trace ("initThreadFct: starting"); try { // created as a thread - must not throw exceptions InitStage* stage; @@ -346,7 +344,6 @@ abortInit = true; } toRunC.notifyAll(); // Most likely if we're exiting, we should make sure others aren't waiting. - debug logger.trace ("initThreadFct: returning"); return; } @@ -396,8 +393,6 @@ } debug (mdeUnitTest) unittest { - logger.trace ("Starting unittest"); - auto realInit = stages; // backup the real init stages stages = new typeof(stages); // an empty test-bed diff -r 56c0ddd90193 -r 79d816b3e2d2 mde/setup/Screen.d --- a/mde/setup/Screen.d Thu Sep 11 11:33:51 2008 +0100 +++ b/mde/setup/Screen.d Fri Sep 12 17:36:14 2008 +0100 @@ -35,7 +35,7 @@ struct Screen { // TYPES (these mustn't be static): /** Interface for anything hooking into the screen for drawing, etc. */ - interface Drawable { + interface IDrawable { /** Called on window creation and whenever the window manager resizes the window, before * the new size is set. The new size is passed. * @@ -63,7 +63,6 @@ throw new InitException ("SDL Initialization failed"); } - debug logger.trace ("SDL initialised"); return StageState.ACTIVE; } /** SDL shutdown */ @@ -99,7 +98,6 @@ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); // Open a window - debug logger.trace ("Opening a window (this can crash if the libraries are messed up)"); if (setWindow (w, h)) { throw new InitException ("Failed to open a window"); } @@ -169,11 +167,12 @@ imde.run = false; } - /** Add a drawable element to the screen (see Drawable interface). + /** Add a drawable element to the screen (see IDrawable interface). * - * Should be called before Init to get initial size. Currently no means to remove drawables, - * and not really designed for more than one. */ - void addDrawable (Drawable d) { + * Should be called before Init to get the initial size (sizeEvent is only called when the size + * is set). Currently no means to remove drawables, and not really designed for more than one. + */ + void addDrawable (IDrawable d) { drawables ~= d; } @@ -181,13 +180,10 @@ void draw (TimeSpan) { glClear(GL_COLOR_BUFFER_BIT); - foreach (Drawable d; drawables) + foreach (IDrawable d; drawables) d.draw; - debug (drawGlyphCache) { - logger.trace ("Drawing font texture"); - FontStyle.drawTexture; - } + debug (drawGlyphCache) FontStyle.drawTexture; // Error check: GLenum err = glGetError(); @@ -206,7 +202,7 @@ foreach (d; drawables) // Tell all drawables the new window size. d.sizeEvent (w,h); - debug logger.trace ("Setting video mode {}x{}, 32-bit, flags: {}", w,h,flags); + //debug logger.trace ("Setting video mode {}x{}, 32-bit, flags: {}", w,h,flags); if (SDL_SetVideoMode (w, h, 32, flags) is null) { logger.fatal ("Unable to set video mode:"); char* msg = SDL_GetError (); @@ -263,7 +259,7 @@ // DATA: private: uint flags = 0; - Drawable[] drawables; + IDrawable[] drawables; Logger logger; OptionsVideo vidOpts; }