changeset 43:1530d9c04d4d

Column/row resizing implemented for GridLayoutWidget (finally)! Also new exitImmediately option and a few debug scope(failure) log messages. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 15 May 2008 10:39:57 +0100
parents 8bf53e711cc7
children 07bd1a09e161
files codeDoc/ideas.txt codeDoc/jobs.txt data/L10n/OptionsMisc.mtt data/conf/gui.mtt data/conf/options.mtt mde/Options.d mde/gui/Gui.d mde/gui/renderer/IRenderer.d mde/gui/renderer/SimpleRenderer.d mde/gui/widget/Widget.d mde/gui/widget/layout.d mde/mde.d mde/scheduler/Init.d
diffstat 13 files changed, 195 insertions(+), 116 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/codeDoc/ideas.txt	Thu May 15 10:39:57 2008 +0100
@@ -0,0 +1,5 @@
+Miscelaneous ideas for mde.
+
+Make a special "trace" logger which keeps the last 20, say, trace messages and only output them when asked to do so, which might happen when an exception is caught. It might output them via the normal mechanisms, but only when asked (and not all messages may be in the correct order: trace messages might be logged later than they were added to the list).
+
+Use debug scope(failure) to output log messages in many places.
\ No newline at end of file
--- a/codeDoc/jobs.txt	Wed May 14 12:31:09 2008 +0100
+++ b/codeDoc/jobs.txt	Thu May 15 10:39:57 2008 +0100
@@ -3,17 +3,18 @@
 
 
 In progress:
-Implement row/col sizing.
 
 
 
 To do (importance 0-5: 0 pointless, 1 no obvious impact now, 2 todo sometime, 3 useful, 4 important, 5 urgent):
 Also see todo.txt and FIXME/NOTE comment marks.
+4   Not guaranteed to catch up-click ending callback! Appears not to be a problem...
 4   OutOfMemoryException is not currently checked for − it should be at least in critical places (use high-level catching of all errors?).
 3   on-event draw support (mde.events and GUI need to tell mde.mde)
 3   Scheduler for drawing only windows which need redrawing.
 3   Update scheduler as outlined in FIXME.
 3   Windows building/compatibility (currently partial)
+2   Options need a "level": simple options, for advanced users, for debugging only, etc.
 2   Command-line options for paths to by-pass normal path finding functionality.
 2   Consider replacing byte/short types with int type
 2   File loading from compressed archives
@@ -49,4 +50,3 @@
 
 
 Done (for git log message):
-The renderer now controls which parts of the window border allow resizing.
--- a/data/L10n/OptionsMisc.mtt	Wed May 14 12:31:09 2008 +0100
+++ b/data/L10n/OptionsMisc.mtt	Thu May 15 10:39:57 2008 +0100
@@ -3,3 +3,5 @@
 <entry|useThreads=["Use threads","Global option for threading in mde."]>
 <entry|logLevel=["Logging level","Controls which messages are logged, from 0=trace to 6=none (default: 1=info)."]>
 <entry|L10n=["Localisation","Specifies the language to use."]>
+<entry|pollInterval=["Polling interval","Delay in main loop to limit CPU usage"]>
+<entry|exitImmediately=["Exit immediately","Load files and exit immediately, without running main loop (for debugging)"]>
--- a/data/conf/gui.mtt	Wed May 14 12:31:09 2008 +0100
+++ b/data/conf/gui.mtt	Thu May 15 10:39:57 2008 +0100
@@ -3,7 +3,7 @@
 {W1}
 <int|x=30>
 <int|y=80>
-<int[][int]|widgetData=[0:[0x4010,200,200]]>
+<int[][int]|widgetData=[0:[0xB004,2,1,1,2],1:[0x4010,200,200],2:[0x1,100,100]]>
 {W2}
 <int|x=150>
 <int|y=200>
--- a/data/conf/options.mtt	Wed May 14 12:31:09 2008 +0100
+++ b/data/conf/options.mtt	Thu May 15 10:39:57 2008 +0100
@@ -1,8 +1,9 @@
 {MT01}
 {misc}
 <bool|useThreads=false>
+<bool|exitImmediately=false>
 <char[]|L10n="en-GB">
-<int|logLevel=0>
+<int|logLevel=1>
 <double|pollInterval=0.01>
 
 {video}
--- a/mde/Options.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/Options.d	Thu May 15 10:39:57 2008 +0100
@@ -341,7 +341,7 @@
 /** A home for all miscellaneous options, at least for now. */
 OptionsMisc miscOpts;
 class OptionsMisc : Options {
-    alias store!("useThreads") BOOL;
+    alias store!("useThreads", "exitImmediately") BOOL;
     alias store!("logLevel") INT;
     alias store!("pollInterval") DOUBLE;
     alias store!("L10n") CHARA;
--- a/mde/gui/Gui.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/gui/Gui.d	Thu May 15 10:39:57 2008 +0100
@@ -145,6 +145,8 @@
     *
     * Sends the event on to the relevant windows and all click callbacks. */
     void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {
+        debug scope (failure)
+                logger.warn ("clickEvent: failed!");
         // NOTE: buttons receive the up-event even when drag-callbacks are in place.
         foreach (dg; clickCallbacks)
             if (dg (cx, cy, b, state)) return;      // See IGui.addClickCallback's documentation
@@ -165,6 +167,8 @@
     *
     * Sends the event on to all motion callbacks. */
     void motionEvent (ushort cx, ushort cy) {
+        debug scope (failure)
+                logger.warn ("motionEvent: failed!");
         foreach (dg; motionCallbacks)
             dg (cx, cy);
     }
--- a/mde/gui/renderer/IRenderer.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/gui/renderer/IRenderer.d	Thu May 15 10:39:57 2008 +0100
@@ -74,6 +74,9 @@
     /** Draws a widget background. Usually doesn't do anything since backgrounds are transparent. */
     void drawWidgetBack (int x, int y, int w, int h);
     
+    /** Draws a blank widget (temporary) */
+    void drawBlank (int x, int y, int w, int h);
+    
     /** Draws a button frame, in if pushed == true. */
     void drawButton (int x, int y, int w, int h, bool pushed);
     //END draw routines
--- a/mde/gui/renderer/SimpleRenderer.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/gui/renderer/SimpleRenderer.d	Thu May 15 10:39:57 2008 +0100
@@ -93,6 +93,11 @@
 
     void drawWidgetBack (int x, int y, int w, int h) {}
     
+    void drawBlank (int x, int y, int w, int h) {
+        gl.setColor (.4f, .4f, .4f);
+        gl.drawBox (x,y, w,h);
+    }
+    
     void drawButton (int x, int y, int w, int h, bool pushed) {
         if (pushed)
             gl.setColor (1f, 0f, 1f);
--- a/mde/gui/widget/Widget.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/gui/widget/Widget.d	Thu May 15 10:39:57 2008 +0100
@@ -128,6 +128,12 @@
         w = (nw >= 0 ? nw : 0);
         h = (nh >= 0 ? nh : 0);
     }
+    
+    void draw () {
+        super.draw;
+        
+        window.renderer.drawBlank (x,y, w,h);
+    }
 }
 
 //BEGIN Widgets
@@ -138,6 +144,11 @@
         if (data.length != 3) throw new WidgetDataException;
         super (wind, data);
     }
+    void draw () {
+        super.draw;
+        
+        window.renderer.drawBlank (x,y, w,h);
+    }
 }
 
 /// A completely resizable blank widget (initial size zero).
@@ -175,14 +186,16 @@
     }
     // Called when a mouse motion/click event occurs while (held == true)
     bool clickWhileHeld (ushort cx, ushort cy, ubyte b, bool state) {
-        //NOTE: which button? test
-        if (cx >= x && cx < x+w && cy >= y && cy < y+h) // button event
-            Stdout ("Button clicked!").newline;
-        
-        pushed = false;
-        window.requestRedraw;
-        window.gui.removeCallbacks (cast(void*) this);
-        
+        if (b == 1 && state == false) {
+            if (cx >= x && cx < x+w && cy >= y && cy < y+h) // button event
+                Stdout ("Button clicked!").newline;
+            
+            pushed = false;
+            window.requestRedraw;
+            window.gui.removeCallbacks (cast(void*) this);
+            
+            return true;
+        }
         return false;
     }
     void motionWhileHeld (ushort cx, ushort cy) {
--- a/mde/gui/widget/layout.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/gui/widget/layout.d	Thu May 15 10:39:57 2008 +0100
@@ -19,6 +19,15 @@
 import mde.gui.widget.Widget;
 import mde.gui.exception;
 
+import tango.io.Stdout;
+debug {
+    import tango.util.log.Log : Log, Logger;
+    private Logger logger;
+    static this () {
+        logger = Log.getLogger ("mde.gui.widget.layout");
+    }
+}
+
 /** Encapsulates a grid of Widgets.
 *
 * Currently there is no support for changing number of cells, sub-widgets or sub-widget properties
@@ -58,14 +67,6 @@
         foreach (widget; subWidgets)
             data = widget.adjust (data);
         
-        // colWMin/rowHMin are needed as absolute quantities in this function:
-        int[] cwMin = new int[colWMin.length];
-        foreach (i,x; colWMin)
-            cwMin[i] = x>=0 ? x : -x;
-        int[] rhMin = new int[rowHMin.length];
-        foreach (i,x; rowHMin)
-            rhMin[i] = x>=0 ? x : -x;
-        
         /* We basically short-cut setSize by loading previous col/row sizes and doing the final
          * calculations.
          * Note: if setSize gets called afterwards, it should have same dimensions and so not do
@@ -73,8 +74,8 @@
         
         int lenUsed = 0;
         if (data.length < rows + cols) {    // data error; use defaults
-            colW = cwMin;
-            rowH = rhMin;
+            colW = colWMin.dup;
+            rowH = rowHMin.dup;
         } else {                            // sufficient data
             lenUsed = rows+cols;
             colW = data[0..cols];
@@ -84,9 +85,9 @@
             //NOTE: this could be made optional
             //NOTE: could also check non-resizable sizes are not too large
             foreach (i, ref w; colW)
-                if (w < cwMin[i]) w = cwMin[i];
+                if (w < colWMin[i]) w = colWMin[i];
             foreach (i, ref h; rowH)
-                if (h < rhMin[i]) h = rhMin[i];
+                if (h < rowHMin[i]) h = rowHMin[i];
         }
         
         genCachedMutableData;
@@ -117,18 +118,11 @@
     }
     
     bool isWSizable () {
-        // True if any column is resizable:
-        foreach (d; colWMin)
-            if (d >= 0)
-                return true;
-        return false;
+        return (sizableCols.length != 0);
     }
     
     bool isHSizable () {
-        foreach (d; rowHMin)
-            if (d >= 0)
-                return true;
-        return false;
+        return (sizableRows.length != 0);
     }
     
     /* Calculates the minimal size from all rows and columns of widgets. */
@@ -139,10 +133,10 @@
     
     void setSize (int nw, int nh) {
         // Step 1: calculate the row/column sizes.
-        w += adjustCellSizes (colW, colWMin, nw - w, true);
-        h += adjustCellSizes (rowH, rowHMin, nh - h, true);
+        w += adjustCellSizes (colW, colWMin, sizableCols, nw - w, true);
+        h += adjustCellSizes (rowH, rowHMin, sizableRows, nh - h, true);
         
-        // Step 2: calculate the row/column offsets (positions) and set the sub-widgets sizes.
+        // Step 2: calculate the row/column offsets (positions) and set the sub-widget's sizes.
         genCachedMutableData;
         
         // Step 3: position needs to be set
@@ -165,7 +159,7 @@
         // Find the column
         int i = cols - 1;                   // starting from right...
         while (lx < colX[i]) {              // decrement while left of this column
-            assert (i > 0, "getWidget: left of first column");  // should be impossible
+            debug assert (i > 0, "getWidget: left of first column");  // should be impossible
             --i;
         }                                   // now (lx >= colX[i])
         if (lx >= colX[i] + colW[i]) return this;   // between columns
@@ -173,7 +167,7 @@
         // Find the row;
         int j = rows - 1;
         while (ly < rowY[j]) {
-            assert (j > 0, "getWidget: above first row");   // should be impossible
+            debug assert (j > 0, "getWidget: above first row");   // should be impossible
             --j;
         }
         if (ly >= rowY[j] + rowH[j]) return this;
@@ -190,28 +184,59 @@
     
     // Resizing columns & rows
     void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {
+        debug scope (failure)
+                logger.warn ("clickEvent: failure");
         if (b == 1 && state == true) {
-            int l = cx - x;    // use relative coords
+            /* Note: Because of getWidget, this function is only called if the click is not on a
+            * sub-widget, so we know it's on some divisor (so at least one of resizeCol and
+            * resizeRow is non-negative). */
             
             // Find the column
-            resizeCol = cols - 1;           // from the right...
-            while (l < colX[resizeCol]) {   // decrement while left of this column
-                assert (resizeCol > 0, "clickEvent: left of first column");
-                --resizeCol;
-            }                               // now (l >= colX[resizeCol])
-            if (l < colX[resizeCol] + colW[resizeCol]) resizeCol = -1;  // on a sub-widget
+            if (sizableCols.length != 0) {
+                int l = cx - x;                 // use relative coords
+                size_t i = cols - 1;            // index, from right
+                while (l < colX[i]) {           // decrement while left of this column
+                    debug assert (i > 0, "clickEvent: left of first column");
+                    --i;
+                }                               // now (l >= colX[resizeCol])
+                if (l < colX[i] + colW[i]) i = -1;  // on a sub-widget
+                
+                // Set resizeColsL / resizeColsH
+                // Want to find j such that [0..j],[j..$] divide sizableCols about i:
+                size_t j = 0;
+                while (j < sizableCols.length && sizableCols[j] <= i) ++j;
+                
+                resizeColsL = sizableCols[0..j];
+                resizeColsH = sizableCols[j..$];
+                
+                // Cannot resize if either list is empty. resizeCallback checks the length of L,
+                // but to save it checking R too, we set L's length zero if R's is.
+                if (resizeColsH.length == 0)
+                    resizeColsL = null;
+            }
             
             // Find the row
-            resizeRow = rows - 1;
-            while (l < rowY[resizeRow]) {
-                assert (resizeRow > 0, "clickEvent: left of first column");
-                --resizeRow;
+            if (sizableRows.length != 0) {
+                int l = cy - y;
+                size_t i = rows - 1;
+                while (l < rowY[i]) {
+                    debug assert (i > 0, "clickEvent: above first row");
+                    --i;
+                }
+                if (l < rowY[i] + rowH[i]) i = -1;
+                
+                size_t j = 0;
+                while (j < sizableRows.length && sizableRows[j] <= i) ++j;
+                
+                resizeRowsL = sizableRows[0..j];
+                resizeRowsH = sizableRows[j..$];
+                
+                if (resizeRowsH.length == 0)
+                    resizeRowsL = null;
             }
-            if (l < rowY[resizeRow] + rowH[resizeRow]) resizeRow = -1;  // on a sub-widget
             
-            /* Note: Because of getWidget, this function is only called if the click is not on a
-             * sub-widget, so we know it's on some divisor (so at least one of resizeCol and
-             * resizeRow is non-negative). */
+            if (resizeColsL is null && resizeRowsL is null)
+                return;     // no resizing to do
             
             dragX = cx;
             dragY = cy;
@@ -260,26 +285,25 @@
         
         
         // Find which cols/rows are resizable:
+        sizableCols = sizableRows = null;   // reset; we're about to concatenate to them
+        
         forCols:
         for (uint i = 0; i < cols; ++i) {                       // for each column
             for (uint j = 0; j < subWidgets.length; j += cols)  // for each row
-                if (!subWidgets[i+j].isWSizable) {      // column not resizable
-                    colWMin[i] = -colWMin[i];           // negate to show not resizable
+                if (!subWidgets[i+j].isWSizable)        // column not resizable
                     continue forCols;                   // continue the outer for loop
-                }
                 
             // column is resizable if we get to here
-            // entry is left positive, meaning it is resizable
+            sizableCols ~= i;
         }
         
         forRows:
         for (uint i = 0; i < subWidgets.length; i += cols) {    // for each row
             for (uint j = 0; j < cols; ++j)                     // for each column
-                if (!subWidgets[i+j].isHSizable) {
-                    j = i / cols;       // reuse: will be reinitialised next iteration
-                    rowHMin[j] = -rowHMin[j];
+                if (!subWidgets[i+j].isHSizable)
                     continue forRows;
-                }
+            
+            sizableRows ~= i / cols;
         }
     }
     
@@ -314,50 +338,46 @@
      * Params:
      *  cellD       = current sizes; is adjusted by the function to new sizes
      *  cellDMin    = minimal sizes (see colWMin/rowHMin)
+     *  sizableCells= List of indexes in cellD for cells which are resizable
      *  diff        = amount to increase/decrease the total size
      *  startHigh   = if true, start resizing from the tail end of cellD, instead of the beginning
      *
      * Returns:
      *  The amount adjusted. This may be larger than diff, since cellD is clamped by cellDMin.
      */
-    int adjustCellSizes (ref int[] cellD, ref int[] cellDMin, int diff, bool startHigh)
+    int adjustCellSizes (ref int[] cellD, ref int[] cellDMin, ref size_t[] sizableCells, int diff, bool startHigh)
     in {// Could occur if adjust isn't called first, but this would be a code error:
         assert (cellD !is null, "adjustCellSizes: cellD is null");
     } body {
-        size_t i = (startHigh ? cellD.length-1 : 0);
-        size_t ic = (startHigh ? -1 : 1);   // amount to iterate to next cell
+        // Cannot resize if no cells are sizable:
+        if (sizableCells.length == 0) return 0;
+        
+        size_t si = (startHigh ? sizableCells.length-1 : 0);    // starting index of sizableCells
         
         // FIXME: could do with an overhaul
         if (diff > 0) {         // increase size of first resizable cell
-            do {
-                if (cellDMin[i] >= 0) { // cell is resizable
-                    cellD[i] += diff;
-                    return diff;
-                }
-                i += ic;
-            } while (i >= 0 && i < cellD.length);
-            // no resizable cell: revert to original
-            cellD[(startHigh ? cellD.length-1 : 0)] += diff;
+            cellD[sizableCells[si]] += diff;
             return diff;
         }
         else if (diff < 0) {    // decrease
+            size_t sc = (startHigh ? -1 : 1);   // amount to iterate
+            size_t ci;          // index in cellD
             int rd = diff;      // running diff
             while (true) {
-                // NOTE: could do this differently so that enlarged cells can be shrunk
-                if (cellDMin[i] >= 0) { // i.e., if resizable:
-                    cellD[i] += rd; // decrease this cell's size (but may be too much)
-                    rd = cellD[i] - cellDMin[i];
-                    if (rd >= 0)    // OK; we're done
-                        return diff;// we hit the mark exactly
-                    
-                    // else we decreased it too much!
-                    cellD[i] = cellDMin[i];
-                    // rd is remainder to decrease by
-                }
+                ci = sizableCells[si];
+                
+                cellD[ci] += rd; // decrease this cell's size (but may be too much)
+                rd = cellD[ci] - cellDMin[ci];
+                if (rd >= 0)    // OK; we're done
+                    return diff;// we hit the mark exactly
                 
-                i += (startHigh ? -1 : 1);  // next cell
-                if (i < 0 || i >= cellD.length) // run out of next cells
-                    return diff - rd;       // still had rd left to decrease
+                // else we decreased it too much!
+                cellD[ci] = cellDMin[ci];
+                // rd is remainder to decrease by
+                
+                si += sc;       // iterate
+                if (si < 0 || si >= sizableCells.length)        // run out of next cells
+                    return diff - rd;   // still had rd left to decrease
             }
         }
         else                   // no adjustment needed
@@ -368,30 +388,48 @@
     void resizeCallback (ushort cx, ushort cy) {
         int move;           // NOTE: all resizing is relative, unlike in Window
         
-        if (resizeCol >= 0) {
+        if (resizeColsL.length != 0) {
             move = cx - dragX;
-            int[] d0 = colW[0..resizeCol];
-            int[] d1 = colW[resizeCol..$];
-            int[] m0 = colWMin[0..resizeCol];
-            int[] m1 = colWMin[resizeCol..$];
             
             // do shrinking first (in case we hit the minimum)
             // Note: we rely on x[a..b] pointing to the same memory as x
-            if (move > 0) {
-                move = -adjustCellSizes (d1, m1, -move, false);
-                adjustCellSizes (d0, m0, move, true);
+            if (move < 0) {
+                move = -adjustCellSizes (colW, colWMin, resizeColsL, move, false);
+                adjustCellSizes (colW, colWMin, resizeColsH, move, true);
             } else {
-                move = -adjustCellSizes (d0, m0, move, true);
-                adjustCellSizes (d1, m1, move, false);
+                move = -adjustCellSizes (colW, colWMin, resizeColsH, -move, true);
+                adjustCellSizes (colW, colWMin, resizeColsL, move, false);
             }
+            
+            dragX = cx;
         }
-        // FIXME: vertical
         
+        if (resizeRowsL.length != 0) {
+            move = cy - dragY;
+            
+            // do shrinking first (in case we hit the minimum)
+            // Note: we rely on x[a..b] pointing to the same memory as x
+            if (move < 0) {
+                move = -adjustCellSizes (rowH, rowHMin, resizeRowsL, move, false);
+                adjustCellSizes (rowH, rowHMin, resizeRowsH, move, true);
+            } else {
+                move = -adjustCellSizes (rowH, rowHMin, resizeRowsH, -move, true);
+                adjustCellSizes (rowH, rowHMin, resizeRowsL, move, false);
+            }
+            
+            dragY = cy;
+        }
+        
+        // NOTE: this might be able to be made more efficient, but basically this all needs to happen:
+        genCachedMutableData;
+        setPosition (x,y);
         window.requestRedraw;
     }
     bool endCallback (ushort cx, ushort cy, ubyte b, bool state) {
         if (b == 1 && state == false) {
             window.gui.removeCallbacks (cast(void*) this);
+            // Remove unwanted data (although it shouldn't free any memory):
+            resizeColsL = resizeColsH = resizeRowsL = resizeRowsH = null;
             return true;    // we've handled the up-click
         }
         return false;       // we haven't handled it
@@ -399,27 +437,33 @@
     
 protected:
     // Data for resizing cols/rows:
-    int resizeCol = -1, // col/row being resized;
-        resizeRow = -1; // negative if none
     int dragX, dragY;   // coords where drag starts
+    // Lists of columns/rows with lower/higher index than the resize position
+    size_t[] resizeColsL, resizeColsH, resizeRowsL, resizeRowsH;
     //END Col/row resizing
     
-    // Construction data (saved):
+    
+    //BEGIN Construction (i.e. non-mutable) data
     int cols, rows;     // number of cells in grid
-    IWidget[] subWidgets;   // all widgets in the grid (by row):
-    /* SubWidget order:    [ 0 1 ]
-    *                      [ 2 3 ] */
+    
+    /* All widgets in the grid, by row. Order:  [ 0 1 ]
+     *                                          [ 2 3 ] */
+    IWidget[] subWidgets;
     
     // Cached data calculated from construction data:
-    int[] colWMin;      // absolute value is minimal column width / row height
-    int[] rowHMin;      // negative if fixed size, entry >= 0 if resizible
+    // Minimal column width / row height:
+    int[] colWMin, rowHMin;
     int mw, mh;         // minimal dimensions
     
-    // Mutable data (saved):
-    int[] colW;         // column width (widest widget)
-    int[] rowH;         // row height (highest widget in the row)
+    // All resizable cols/rows, in order:
+    size_t[] sizableCols, sizableRows;
+    //END Construction data
+    
+    
+    //BEGIN Mutable data
+    int[] colW, rowH;   // column width / row height (largest size in col/row)
     
     // Cached data calculated from construction and mutable data:
-    int[] colX;         // cumulative colW[i-1] + padding (add x to get column's left x-coord)
-    int[] rowY;         // cumulative rowH[i-1] + padding
+    int[] colX, rowY;   // cumulative colW[i-1] + padding (add x to get column's left x-coord)
+    //END Mutable data
 }
--- a/mde/mde.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/mde.d	Thu May 15 10:39:57 2008 +0100
@@ -54,8 +54,8 @@
         return 1;
     }
     
-    if (miscOpts.pollInterval !<= 0.1 || miscOpts.pollInterval !>= 0.0)
-        Options.setDouble ("misc", "pollInterval", 0.0);
+    if (miscOpts.pollInterval !<= 1.0 || miscOpts.pollInterval !>= 0.0)
+        Options.setDouble ("misc", "pollInterval", 0.01);
     //END Initialisation
     
     //BEGIN Main loop setup
--- a/mde/scheduler/Init.d	Wed May 14 12:31:09 2008 +0100
+++ b/mde/scheduler/Init.d	Thu May 15 10:39:57 2008 +0100
@@ -139,8 +139,10 @@
             throw new InitException ("Loading options failed: " ~ e.msg);
         }
         
-        // Now re-set the logging level:
-        Log.getRootLogger.setLevel (cast(Log.Level) miscOpts.logLevel, true);  // set the stored log level
+        // Now re-set the logging level, using the value from the config file:
+        Log.getRootLogger.setLevel (cast(Log.Level) miscOpts.logLevel, true);
+        // And set this (debug option):
+        imde.run = !miscOpts.exitImmediately;
         //END Pre-init
         
         debug logger.trace ("Init: pre-init done");