Changeset 85:56c0ddd90193

Show
Ignore:
Timestamp:
09/11/08 06:33:51 (4 months ago)
Author:
Diggory Hardy <diggory.hardy@gmail.com>
branch:
default
Message:

Intermediate commit (not stable). Changes to init system.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • codeDoc/ideas.txt

    r43 r85  
     1Copyright © 2007-2008 Diggory Hardy 
     2License: GNU General Public License version 2 or later (see COPYING) 
     3 
     4 
    15Miscelaneous ideas for mde. 
    26 
  • codeDoc/jobs.txt

    r84 r85  
    44 
    55In progress: 
     6why is nothing drawn until a resize? seems to be working now (??) 
     7why isn't font texture drawn in mde? 
     8why does mde&guiDemo hang on exit, only if no resize occurred? 
     9wierd things with options.mtt (font section getting output twice) 
     10CircularIterator 
     11unittest again! 
    612 
    713 
     
    915To do (importance 0-5: 0 pointless, 1 no obvious impact now, 2 todo sometime, 3 useful, 4 important, 5 urgent): 
    1016Also see todo.txt and FIXME/NOTE comment marks. 
    11 5   setting widgets' default size? setMinSize/setDefaultSize fct? 
     174   Why does mde.events need to be imported before mde.setup.Init to make fonts display properly? Analysis of static CTORs doesn't seem to have helped. Could be to do with order init functions are run in? Crash in threaded mode. 
    12184   Try to correlate names of option sections more. (i.e. symbol name, class name, name of i18n translation file) 
    13194   Not guaranteed to catch up-click ending callback! Appears not to be a problem... 
     
    19253   Update scheduler as outlined in FIXME. 
    20263   Windows building/compatibility (currently partial) - tango/sys/win32/SpecialPath.d 
    21 2   Why does mde.events need to be imported before mde.setup.Init to make fonts display properly? Analysis of static CTORs doesn't seem to have helped. 
    22272   Remove ability to scan, then load, mergetag sections. Not so necessary with section creator callback and allows "sliding window" type partial buffering. 
    23282   Options need a "level": simple options, for advanced users, for debugging only, etc. 
  • codeDoc/staticCtors.txt

    r84 r85  
    1 Map of what happens in static CTORs (excluding creating loggers): 
     1Copyright © 2007-2008 Diggory Hardy 
     2License: GNU General Public License version 2 or later (see COPYING) 
     3 
     4 
     5Map of what happens in static CTORs (excluding creating loggers). From August 2008. 
    26 
    37mde 
  • data/conf/options.mtt

    r55 r85  
    11{MT01} 
    22{misc} 
    3 <bool|useThreads=false
     3<int|numThreads=2
    44<bool|exitImmediately=false> 
    55<char[]|L10n="en-GB"> 
    6 <int|logOptions=0x3001
     6<int|logOptions=0x3000
    77<double|pollInterval=0.01> 
    88 
  • doc/Readme.txt

    r70 r85  
    3434Also thanks to: 
    3535Walter Bright and Digital Mars for D and DMD. 
    36 The tango team for Tango
     36The tango team
    3737[derelict] 
    3838[sdl] 
     
    6060+ How many lines are there? 
    6161# wc -l $(find . -name "*.d") 
    62 As of last count, that was 3908
     62As of my last count, that was 10227
    6363 
    6464+ Why is the code so DENSE? 
     
    6767+ What toolkits/external libraries are used? 
    6868    tango 
    69     tango.scrapple 
    70     SDL (possibly will be replaced) 
     69    derelict (SDL, OpenGL, FreeType 2) 
    7170 
    7271+ What libraries are planned to be used? 
    73     OpenGL (of course...) 
    74     OpenAL (most likely; however audio support is a LONG way off) 
    75     Schooner: GLD & fonts (or conversions to tango) ? 
    76     GLFW ? 
     72    OpenAL, if I get around to doing anything with audio. 
  • dsss.conf

    r68 r85  
    22# License: GNU General Public License version 2 or later (see COPYING) 
    33 
    4 defaulttargets = mde/mde.d 
     4defaulttargets = mde/mde.d examples/guiDemo.d 
    55 
    66[*] 
     
    1515target=bin/mde 
    1616 
     17[examples/guiDemo.d] 
     18target=bin/guiDemo 
     19 
    1720[util/mtcp.d] 
    1821target=bin/mtcp 
  • examples/guiDemo.d

    r84 r85  
    1414along with this program.  If not, see <http://www.gnu.org/licenses/>. */ 
    1515 
    16 /** Modular D Engine 
    17  * 
    18  * This module contains a minimal main() function. Practically, it is useful for running unittests 
    19  * and some other testing. It also serves as a basic example program. 
    20  */ 
    21 module mde.mde; 
     16/** Main module for a gui demo & testing executable. */ 
     17module examples.guiDemo; 
    2218 
    2319import mde.imde;                        // this module's interface for external modules 
     
    2622import mde.lookup.Options;              // pollInterval option 
    2723import mde.scheduler.Scheduler;         // mainSchedule 
    28 import gl = mde.gl.draw;                // gl.draw() 
     24import mde.setup.Screen;                // Screen.draw() 
     25import mde.setup.InitStage;             // StageState 
     26import mde.gui.WidgetManager; 
    2927 
    3028import tango.core.Thread : Thread;  // Thread.sleep() 
     
    3836int main(char[][] args) 
    3937{ 
     38    Logger logger = Log.getLogger ("mde.mde"); 
    4039    // If compiled with unittests, notify that they completed and exit: 
    4140    debug (mdeUnitTest) { 
    42         Logger logger = Log.getLogger ("mde.mde"); 
    4341        logger.info ("Compiled unittests have completed; terminating."); 
    4442        return 0; 
    4543    } 
     44     
     45    // Set up the gui 
     46    scope WidgetManager gui = new WidgetManager ("gui"); 
     47    StageState guiLoad () {   // init func 
     48        gui.init; 
     49        gui.loadDesign(); 
     50        return StageState.ACTIVE; 
     51    } 
     52    StageState guiSave () { 
     53        gui.save; 
     54        return StageState.INACTIVE; 
     55    } 
     56    addInitStage ("GuiM", &guiLoad, &guiSave, ["SWnd", "Font"]); 
    4657     
    4758    scope Init init = new Init(args);   // initialize mde 
     
    5768     * Note: probably drawing should start at the beginning of the loop and glFlush()/swapBuffers 
    5869     * be called at the end to optimise. */ 
    59     mainSchedule.add (SCHEDULE.DRAW, &gl.draw); // Draw, per event only. 
     70    mainSchedule.add (SCHEDULE.DRAW, &Screen.draw); // Draw, per event only. 
    6071    mainSchedule.add (mainSchedule.getNewID, &mde.events.pollEvents).frame = true; 
    6172    //END Main loop setup 
  • mde/events.d

    r63 r85  
    2121 
    2222import imde = mde.imde; 
    23 import sdl = mde.setup.sdl;    // resizeWindow 
     23import mde.setup.Screen; 
    2424 
    2525import mde.input.Input; 
     
    4545                break; 
    4646            case SDL_VIDEORESIZE: 
    47                 sdl.resizeWindow (event.resize.w, event.resize.h); 
     47                Screen.resizeEvent (event.resize.w, event.resize.h); 
    4848                imde.mainSchedule.request(imde.SCHEDULE.DRAW); 
    4949                break; 
  • mde/file/mergetag/Reader.d

    r82 r85  
    3333import Util = tango.text.Util; 
    3434import ConvInt = tango.text.convert.Integer; 
    35 //import tango.util.collection.model.View : View; 
    36 import tango.util.collection.HashSet : HashSet; 
     35import tango.util.container.HashSet; 
    3736import tango.util.log.Log : Log, Logger; 
    3837 
     
    306305    } 
    307306    /** ditto */ 
    308     public void read (View!(ID) secSet) { 
     307    public void read (IContainer!(ID) secSet) { 
    309308        if (allRead || fatal) return;           // never do anything in either case 
    310309         
     
    517516    void read () {}                     /// Commence reading 
    518517    void read (ID[] secSet) {}          /// ditto 
    519     void read (View!(ID) secSet) {}     /// ditto 
     518    void read (IContainer!(ID) secSet) {}/// ditto 
    520519} 
  • mde/file/mergetag/Writer.d

    r82 r85  
    3737// tango imports 
    3838import tango.core.Exception; 
    39 import tango.io.FileConduit; 
     39import tango.io.device.FileConduit; 
    4040import tango.io.Buffer : Buffer, IBuffer; 
    4141import tango.io.Print : Print; 
     
    163163        _path = path; 
    164164        _dataset = ds; 
     165        foreach (i,s; _dataset.sec) 
     166            debug logger.trace ("sec ID length: {}", i.length); 
    165167    } 
    166168//END CTOR / DTOR 
     
    179181         
    180182        try { 
     183            debug logger.trace ("W.w: 1"); 
    181184            FileConduit conduit;    // actual conduit; don't use directly when there's content in the buffer 
    182185            IBuffer buffer;     // write strings directly to this (use opCall(void[]) ) 
    183186             
     187            debug logger.trace ("W.w: 2"); 
    184188            // Open a conduit on the file: 
    185189            conduit = new FileConduit (_path, FileConduit.WriteCreate); 
    186190            scope(exit) conduit.close(); 
    187191             
     192            debug logger.trace ("W.w: 3"); 
    188193            buffer = new Buffer(conduit);   // And a buffer 
    189194            scope(exit) buffer.flush(); 
    190195             
     196            debug logger.trace ("W.w: 4"); 
    191197            // Write the header: 
    192198            buffer ("{MT" ~ MTFormatVersion.CurrentString ~ "}" ~ Eol); 
     199            debug logger.trace ("W.w: 5"); 
    193200            if (_dataset.header !is null) writeSection (buffer, _dataset.header); 
    194201         
     202            debug logger.trace ("W.w: 6"); 
    195203            // Write the rest: 
    196204            foreach (ID id, IDataSection sec; _dataset.sec) { 
     205                debug logger.trace ("W.w: 71"); 
    197206                writeSectionIdentifier (buffer, id); 
     207                debug logger.trace ("W.w: 72"); 
    198208                writeSection (buffer, sec); 
    199209            } 
    200          
     210             
     211            debug logger.trace ("W.w: 8"); 
    201212            buffer.flush(); 
    202213             
     214            debug logger.trace ("W.w: 9"); 
    203215        } 
    204216        catch (IOException e) { 
     
    211223         
    212224    private void writeSectionIdentifier (IBuffer buffer, ID id) { 
    213         buffer ("{" ~ cast(char[])id ~ "}" ~ Eol); 
     225        debug logger.trace ("W.wSI: 0"); 
     226        debug logger.trace ("W.wSI: id ({})",id.length); 
     227        debug logger.trace ("W.wSI: Eol ({})",Eol.length); 
     228        char[] tp = "{" ~ cast(char[])id ~ "}" ~ Eol; 
     229        debug logger.trace ("W.wSI: 0.1"); 
     230        debug logger.trace ("W.wSI: string ({}): {}",tp.length, tp); 
     231        buffer (tp); 
     232        debug logger.trace ("W.wSI: 1"); 
    214233    } 
    215234     
  • mde/file/mergetag/iface/IReader.d

    r81 r85  
    2121import mde.file.mergetag.DataSet; 
    2222 
    23 import tango.util.collection.model.View : View
     23public import tango.util.container.model.IContainer
    2424 
    2525/** Interface for all mergetag readers (MTTReader etc.). 
     
    3434    void read ();                       /// Commence reading 
    3535    void read (ID[] secSet);            /// ditto 
    36     void read (View!(ID) secSet);       /// ditto 
     36    void read (IContainer!(ID) secSet);       /// ditto 
    3737} 
  • mde/font/FontTexture.d

    r83 r85  
    5353{ 
    5454    this () {} 
    55     ~this () { 
    56         foreach (t; tex) { 
    57             glDeleteTextures (1, &(t.texID)); 
    58         } 
    59     } 
     55    ~this () {} 
    6056     
    6157    // Call if font(s) have been changed and glyphs must be recached. 
  • mde/font/font.d

    r84 r85  
    2525import mde.file.mergetag.DataSet; 
    2626import mde.setup.paths; 
     27import mde.setup.exception;     // InitStage stuff 
    2728 
    2829import derelict.freetype.ft; 
     
    5657        } 
    5758         
    58         /** Load the freetype library from the file fileName. */ 
     59        /** Load the freetype library with settings from the file fileName. */ 
    5960        private const fileName = "fonts"; 
    60         void initialize () { 
     61        StageState initialize () { 
    6162            if (FT_Init_FreeType (&library)) 
    6263                throw new fontException ("error initialising the FreeType library"); 
     
    7778                * is not compiled into the library. */ 
    7879                logger.warn ("Bad/unsupported LCD filter option; disabling LCD font rendering."); 
    79                 logger.warn ("Your FreeType 2 library may compiled without support for LCD/sub-pixel rendering."); 
     80                logger.warn ("Your FreeType 2 library may be compiled without support for LCD/sub-pixel rendering."); 
    8081                 
    8182                // Reset the default filter (in case an invalid value was set in config files). 
     
    123124            // Also note that get() doesn't make sure the fallback is loaded before returning it. 
    124125            fallback.load; 
     126             
     127            return StageState.ACTIVE; 
    125128        } 
    126129         
    127130        //FIXME: don't use GC for FontStyle resources 
    128131        /** Cleanup: delete all fonts. */ 
    129         void cleanup () { 
    130             FT_Done_FreeType (library); 
     132        StageState cleanup () { 
     133            // Clear loaded fonts: 
     134            foreach (fs; fonts) 
     135                delete fs; 
     136            fonts = null; 
     137            delete fallback; 
     138             
     139            delete fontTex;     // clear texture 
     140            FT_Done_FreeType (library); // free the library 
     141             
     142            return StageState.INACTIVE; 
    131143        } 
    132144         
     
    286298     
    287299    ~this () { 
     300        debug logger.trace ("{}.~this: start", this); 
    288301        FT_Done_Face (face); 
     302        debug logger.trace ("{}.~this: done", this); 
    289303    } 
    290304     
  • mde/gui/WidgetManager.d

    r84 r85  
    3030import mde.input.Input; 
    3131import mde.scheduler.Scheduler; 
     32import mde.setup.Screen; 
    3233 
    3334import tango.core.sync.Mutex; 
     
    3738static this () { 
    3839    logger = Log.getLogger ("mde.gui.WidgetManager"); 
    39  
    40     gui = new WidgetManager ("gui"); 
    4140} 
    42  
    43 WidgetManager gui; 
    44  
    4541 
    4642/************************************************************************************************* 
     
    5551 * Aside from the IWidgetManager methods, this class should be thread-safe. 
    5652 *************************************************************************************************/ 
    57 class WidgetManager : WidgetLoader
     53class WidgetManager : WidgetLoader, Screen.Drawable
    5854    /** Construct a new widget manager. 
    5955     *  
     
    6359    this (char[] file) { 
    6460        super(file); 
     61         
     62        Screen.addDrawable (this); 
    6563    } 
    6664     
     
    6866    // called during init 
    6967    void init () { 
     68        // Doesn't need a lock - cannot conflict with other class functions. 
    7069        // Events we want to know about: 
    7170        imde.input.addMouseClickCallback(&clickEvent); 
     
    7675    /** Draw the gui. */ 
    7776    void draw() { 
     77        debug logger.trace ("drawing; w,h = {},{}",w,h); 
    7878        synchronized(mutex) 
    79             child.draw; 
     79            if (child) 
     80                child.draw; 
    8081    } 
    8182     
     
    8990        mutex.lock; 
    9091        scope(exit) mutex.unlock; 
     92        if (child is null) return; 
    9193         
    9294        // NOTE: buttons receive the up-event even when drag-callbacks are in place. 
     
    9698         
    9799        // NOTE: do we need to test if the click was on the gui (and thus child)? 
     100        // FIXME: yes, unless we can guarantee this! 
    98101        IChildWidget widg = child.getWidget (cast(wdabs)cx,cast(wdabs)cy); 
    99102        if (widg !is null) 
    100103            widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state); 
    101         /+ FIXME: remove 
    102         foreach (i,w; windows) { 
    103             IWidget widg = w.getWidget (cast(wdabs)cx,cast(wdabs)cy); 
    104             if (widg !is null) { 
    105                 // Bring to front 
    106                 windows = w ~ windows[0..i] ~ windows[i+1..$]; 
    107                  
    108                 widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state); 
    109                 requestRedraw;  // in case we've only moved to front 
    110                 return;     // only pass to first window 
    111             } 
    112         }+/ 
    113104    } 
    114105     
     
    127118     
    128119     
    129     void setSize (int x, int y) { 
     120    void sizeEvent (int nw, int nh) {   // Drawable function 
    130121        mutex.lock; 
    131122        scope(exit) mutex.unlock; 
    132123         
    133         w = cast(wdim) x; 
    134         h = cast(wdim) y; 
    135          
    136         if (child is null) 
    137             return;     // May not have been created before this is first run. 
     124        w = cast(wdim) nw; 
     125        h = cast(wdim) nh; 
     126         
     127        debug logger.trace ("Resize to: {},{}", nw, nh); 
     128        if (w < mw || h < mh) 
     129            logger.warn ("Minimal dimensions ({},{}) not met: ({},{}), but I cannot resize myself!",mw,mh,w,h); 
     130         
     131        if (!child) return;     // if not created yet. 
    138132        child.setWidth  (w, -1); 
    139133        child.setHeight (h, -1); 
     
    166160     
    167161protected: 
    168     /* Second stage of widget loading. */ 
     162    /* Second stage of widget loading. 
     163     * Note: sizeEvent should be called with window size before this. */ 
    169164    void createRootWidget () { 
    170165        // The renderer needs to be created on the first load, but not after this. 
     
    173168         
    174169        child = makeWidget ("root"); 
     170         
     171        mw = child.minWidth; 
     172        mh = child.minHeight; 
     173         
     174        if (w < mw || h < mh) 
     175            logger.warn ("Minimal dimensions ({},{}) not met: ({},{}), but I cannot resize myself!",mw,mh,w,h); 
    175176         
    176177        child.setWidth  (w, -1); 
     
    185186    IRenderer rend; 
    186187    wdim w,h;       // area available to the widgets 
     188    wdim mw,mh;     // minimal area available to the widgets 
    187189} 
    188190 
     
    212214        mutex = new Mutex;  // Used on functions intended to be called from outside the gui package. 
    213215        fileName = file; 
    214     } 
    215     ~this () { 
    216         save; 
    217216    } 
    218217     
     
    381380    /** Create a widget by ID. */ 
    382381    IChildWidget makeWidget (widgetID id, IParentWidget parent = null) { 
    383         debug logger.trace ("Creating widget \""~id~'"'); 
     382        debug (mdeWidgets) logger.trace ("Creating widget \""~id~'"'); 
    384383        return createWidget (this, curData[id], parent); 
    385384    } 
  • mde/gui/widget/Ifaces.d

    r80 r85  
    125125 * 
    126126 * If a widget is to be creatable by IWidgetManager.makeWidget, it must be listed in the 
    127  * createWidget module, have a constructor of the following form, and should update it's 
    128  * creation data as necessary via IWidgetManager.setData(). 
     127 * createWidget module, and have a constructor of the following form. It should also update it's 
     128 * creation data if necessary, either when changed or when saveChanges() is called, using 
     129 * IWidgetManager.setData(). 
    129130 * It should use Ddoc to explain what initialization data is used. 
    130131 * ---------------------------------- 
  • mde/gui/widget/createWidget.d

    r80 r85  
    5454     
    5555    //pragma (msg, binarySearch ("type", WIDGETS)); 
    56     mixin (binarySearch ("type", WIDGETS)); // creates widget by type as new *Widget (mgr, data); 
     56    mixin (binarySearch ("type", WIDGETS)); // creates widget by type: new XWidget (mgr, data [, parent]); 
    5757     
    5858    // Not returned a new widget... 
     
    124124        foreach (c; consts) { 
    125125            ret ~=  "if (" ~ var ~ " == WIDGET_TYPE." ~ c ~ ") {\n" ~ 
    126                     "   debug logger.trace (\"Creating new "~c~"Widget.\");\n" ~ 
     126                    "   debug (mdeWidgets) logger.trace (\"Creating new "~c~"Widget.\");\n" ~ 
    127127                    "   static if (WIDGET_TYPE."~c~" & WIDGET_TYPE.TAKES_PARENT)\n" ~ 
    128128                    "       return new " ~ c ~ "Widget (mgr, data, parent);\n" ~ 
  • mde/gui/widget/layout.d

    r78 r85  
    429429                --i; 
    430430            }                   // now (l >= pos[i]) 
    431             if (l >= pos[i] + width[i])     // between columns 
     431            if (l >= pos[i] + width[i]) {   // between columns 
     432                debug assert (i+1 < minWidth.length, "getCell: l >= pos[$-1] + width[$-1] (code error)"); 
    432433                return -i - 1;          // note: i might be 0 so cannot just return -i 
     434            } 
    433435            return i; 
    434436        } 
  • mde/input/Config.d

    r84 r85  
    2525 
    2626import tango.util.log.Log : Log, Logger; 
    27 import tango.util.collection.TreeBag : TreeBag
     27import tango.util.container.HashSet
    2828 
    2929/** Class to hold the configuration for the input system. Thus loading and switching between 
     
    116116     
    117117    static Config[char[]] configs;  /// All configs loaded by load(). 
    118     private static TreeBag!(char[]) loadedFiles;  // all filenames load tried to read 
     118    private static HashSet!(char[]) loadedFiles;  // all filenames load tried to read 
    119119    private static Logger logger; 
    120120     
     
    122122    static this () { 
    123123        logger = Log.getLogger ("mde.input.Config"); 
    124         loadedFiles = new TreeBag!(char[]); 
     124        loadedFiles = new HashSet!(char[]); 
    125125    } 
    126126     
  • mde/input/joystick.d

    r67 r85  
    1919module mde.input.joystick; 
    2020 
     21import mde.setup.exception;     // InitStage 
    2122import tango.util.log.Log : Log, Logger; 
    2223 
     
    3637* closeJoysticks must be run to cleanup afterwards. 
    3738*/ 
    38 void openJoysticks () { 
     39StageState openJoysticks () { 
    3940    joysticks = new SDL_Joystick*[SDL_NumJoysticks ()]; 
    4041     
     
    4243        if ((joysticks[i] = SDL_JoystickOpen (i)) is null) {    // null on failure 
    4344            logger.error ("Unable to open joystick {} via SDL", i); 
     45            return StageState.ERROR;    // prevent closeJoysticks running, but don't halt program 
    4446        } 
    4547    } 
    4648     
    4749    logger.info ("Opened {} joysticks via SDL, succesfully unless preceding errors say otherwise.", joysticks.length); 
     50    return StageState.ACTIVE; 
    4851} 
    4952 
    5053/// Cleanup fct. 
    51 void closeJoysticks () { 
     54StageState closeJoysticks () { 
    5255    foreach (js; joysticks) { 
    53         // FIXME: this is sometimes causing a SIGSEGV (Address boundary error) 
    54         // FIXME: when init fails 
     56        // FIXME: This sometimes causes a SIGSEGV (Address boundary error) when init fails. 
    5557        debug logger.trace ("Closing joysticks (this sometimes fails when mde exits prematurely)"); 
    5658        if(js !is null) SDL_JoystickClose(js);  // only close if successfully opened 
    5759        debug logger.trace ("Done closing joysticks"); 
    5860    } 
     61    return StageState.INACTIVE; 
    5962} 
  • mde/lookup/Options.d

    r84 r85  
    137137            assert (((cast(ID) i) in subClasses) is null);  // Don't allow a silent replacement 
    138138        } body { 
     139            debug logger.trace ("Adding Options subClass: "~i); 
    139140            subClasses[cast(ID) i] = c; 
    140141        } 
     
    169170        void save () { 
    170171            if (!changed) return;   // no changes to save 
    171          
     172            // Types: 
     173            // interface IDataSection {...} 
     174            // class Options {...} 
     175            // alias char[] ID; 
     176            // IDataSection[ID] ds.sec; 
     177            // Options[ID] subClasses; 
    172178            DataSet ds = new DataSet(); 
    173             foreach (id, subOpts; subClasses) ds.sec[id] = subOpts.optionChanges; 
    174          
     179            foreach (id, subOpts; subClasses) { 
     180                ds.sec[id] = subOpts.optionChanges; 
     181                debug logger.trace ("Saving options section: "~id); 
     182            } 
     183            foreach (i,s; ds.sec) 
     184                debug logger.trace ("sec ID length: {}", i.length); 
     185            debug logger.trace ("0"); 
     186             
    175187            // Read locally-stored options 
    176188            try { 
     
    178190                reader = confDir.makeMTReader (fileName, PRIORITY.HIGH_ONLY, ds); 
    179191                reader.dataSecCreator = delegate IDataSection(ID id) { 
     192                    debug logger.trace ("New section to save ignored: "~id); 
    180193                    return null;    // All recognised sections are already in the dataset. 
    181194                }; 
     
    189202         
    190203            try { 
     204                debug logger.trace ("1"); 
    191205                IWriter writer; 
    192                 writer = confDir.makeMTWriter (fileName, ds); 
    193                 writer.write(); 
     206                foreach (i,s; ds.sec) 
     207                    debug logger.trace ("sec ID length: {}", i.length); 
     208                debug logger.trace ("2"); 
     209                writer = confDir.makeMTWriter (fileName, ds);   // FIXME - sometimes SIGSEGV 
     210                debug logger.trace ("3"); 
     211                writer.write(); // FIXME - this is causing hang at exit! 
     212                debug logger.trace ("4"); 
    194213            } catch (Exception e) { 
    195214                logger.error ("Saving options aborted: "~e.msg); 
     
    458477OptionsMisc miscOpts; 
    459478class OptionsMisc : Options { 
    460     mixin (impl!("bool useThreads, exitImmediately; int logOptions; double pollInterval; char[] L10n, a,b,c;")); 
     479    mixin (impl!("bool exitImmediately; int numThreads, logOptions; double pollInterval; char[] L10n, a,b,c;")); 
    461480     
    462481    static this() { 
  • mde/mde.d

    r84 r85  
    2626import mde.lookup.Options;              // pollInterval option 
    2727import mde.scheduler.Scheduler;         // mainSchedule 
    28 import gl = mde.gl.draw;                // gl.draw() 
     28import mde.setup.Screen;                // Screen.draw() 
    2929 
    3030import tango.core.Thread : Thread;  // Thread.sleep() 
     
    5757     * Note: probably drawing should start at the beginning of the loop and glFlush()/swapBuffers 
    5858     * be called at the end to optimise. */ 
    59     mainSchedule.add (SCHEDULE.DRAW, &gl.draw); // Draw, per event only. 
     59    mainSchedule.add (SCHEDULE.DRAW, &Screen.draw);    // Draw, per event only. 
    6060    mainSchedule.add (mainSchedule.getNewID, &mde.events.pollEvents).frame = true; 
    6161    //END Main loop setup 
  • mde/scheduler/Scheduler.d

    r63 r85  
    7777    * Use the returned pointer to set the scheduling, e.g.: 
    7878    * ----- 
    79     * scheduler.add(scheduler.getNewID, myFunction).set(false, TimeSpan.millis (10)); 
     79    * scheduler.add(scheduler.getNewID, myFunction).set(false, TimeSpan.fromMillis (10)); 
    8080    * scheduler.get(15).frame = true; 
    8181    */ 
     
    177177        s.add(1,&inc1).frame = true; 
    178178         
    179         TimeSpan interval = TimeSpan.millis(1);// non-zero so we can check zero after first call 
     179        TimeSpan interval = TimeSpan.fromMillis(1);// non-zero so we can check zero after first call 
    180180        void perInt (TimeSpan i) {  interval = i;    } 
    181         s.add(2,&perInt).set(false, TimeSpan.millis(10)); 
     181        s.add(2,&perInt).set(false, TimeSpan.fromMillis(10)); 
    182182         
    183183        Time t = Time.epoch1970;    // starting time (value isn't important) 
     
    186186        assert (interval == TimeSpan.zero); // initial interval 
    187187         
    188         t += TimeSpan.millis (5);   // 5ms later... 
     188        t += TimeSpan.fromMillis (5);   // 5ms later... 
    189189        s.execute (t); 
    190190        assert (ctr1 == 2); 
     
    194194        s.get(1).request = true;    // but request next call 
    195195         
    196         t += TimeSpan.millis (5); 
     196        t += TimeSpan.fromMillis (5); 
    197197        s.execute (t); 
    198198        assert (ctr1 == 3);         // as requested 
    199         assert (interval == TimeSpan.millis (10));  // perInt should get called (just!) 
     199        assert (interval == TimeSpan.fromMillis (10));  // perInt should get called (just!) 
    200200         
    201201        s.request(2);               // request this 
    202202         
    203         t += TimeSpan.millis (8); 
     203        t += TimeSpan.fromMillis (8); 
    204204        s.execute (t); 
    205205        assert (ctr1 == 3);         // inc1 shouldn't run 
    206         assert (interval == TimeSpan.millis (8));  // perInt was requested 
    207          
    208         t += TimeSpan.millis (4); 
     206        assert (interval == TimeSpan.fromMillis (8));  // perInt was requested 
     207         
     208        t += TimeSpan.fromMillis (4); 
    209209        s.execute (t); 
    210210        // check perInt's last call-time was updated by the request, so it doesn't get run now: 
    211         assert (interval == TimeSpan.millis (8)); 
     211        assert (interval == TimeSpan.fromMillis (8)); 
    212212         
    213213        logger.info ("Unittest complete."); 
  • mde/setup/Init.d

    r77 r85  
    1515 
    1616/************************************************************************************************** 
    17  * Initialisation setup and exit cleanup module. 
     17 * Initialisation and cleanup (shutdown) module. 
    1818 * 
    19  * This module provides an infrastructure for handling much of the initialisation and 
    20  * deinitialisation of the program. It does not, however, provide much of the (de)initialisation 
    21  * code; with the exception of that for the logger. 
     19 * Program startup follows this sequence: static this() functions, pre-init, init. 
     20 * Shutdown consists of: cleanup, post-cleanup, static ~this() functions. 
     21 *  
     22 * static this and ~this functions should not use any external resources, such as dynamically 
     23 * loaded libraries or files, and should not interact with other modules. They should be almost 
     24 * guaranteed not to fail. Preferably, they shouldn't involve large amounts of memory or 
     25 * processing, but this is not a requirement. 
     26 *  
     27 * Pre-init: init code written in this module. Generally only prerequisets of most other stages 
     28 * go here. 
     29 *  
     30 * Init: This is where init code from external modules gets hooked in. Each stage consists of an 
     31 * initialization function, a corresponding cleanup function, a state, and any dependencies (other 
     32 * init functions which must be run before this one). Init functions are run according to these 
     33 * dependencies, potentially threaded simultaeneously with other init functions. 
     34 *  
     35 * Cleanup: Cleanup happens similarly to init for all stages requiring shutdown (according to their 
     36 * state). The init dependencies are applied in reverse order (so if X depended on Y, Y's cleanup 
     37 * will not run until X's cleanup has completed), and again the functions may be threaded. 
     38 *  
     39 * Post-cleanup: like pre-init, this is code written in Init. 
    2240 *************************************************************************************************/ 
    2341module mde.setup.Init; 
    2442 
    25 import mde.setup.init2;     // This module is responsible for setting up some init functions. 
    26 import mde.setup.initFunctions; 
     43import mde.setup.InitStage;     // Controls external delegates run by init 
    2744import mde.setup.exception; 
    2845 
    2946import mde.lookup.Options; 
    3047import paths = mde.setup.paths; 
    31 import mde.exception; 
     48import mde.exception;           // optionsLoadException 
    3249 
    3350// tango imports 
    3451import tango.core.Thread; 
     52import tango.core.sync.Condition; 
    3553import tango.core.Exception; 
    36 import tango.stdc.stringz : fromStringz; 
     54import tango.util.container.LinkedList; 
     55 
     56//import tango.stdc.stringz : fromStringz; 
    3757import tango.io.Console;    // for printing command-line usage 
    3858import TimeStamp = tango.text.convert.TimeStamp, tango.time.WallClock;  // output date in log file 
    3959import tango.util.Arguments; 
    40 import tango.util.log.Log : Log, Logger, Level
     60import tango.util.log.Log
    4161import tango.util.log.AppendConsole; 
    4262import tango.util.log.AppendFiles; 
     
    4969import derelict.util.exception; 
    5070 
    51 /** 
    52  * Static CTOR 
    53  * 
    54  * This should handle a minimal amount of functionality where useful. For instance, configuring the 
    55  * logger here and not in Init allows unittests to use the logger. 
    56  */ 
    57 static this() 
    58 
    59     Logger root = Log.root; 
    60     // Set the level here,