Changeset 11:b940f267419e

Show
Ignore:
Timestamp:
02/21/08 04:05:33 (11 months ago)
Author:
Diggory Hardy <diggory.hardy@gmail.com>
branch:
default
convert_revision:
af0969213fc9be30ef4b4d65563d1da8d8290742
Message:

Options class created & changes to mergetag exception messages.

Options class created (barebones). Loading/saving from Init.
Init no longer runs cleanup functions after initialisation failure.
Improved mergetag exception messages & error reporting.

committer: Diggory Hardy <diggory.hardy@gmail.com>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • doc/jobs

    r10 r11  
    22 
    33To do: 
    4 *   Write Input unittests; remove untested notes 
    54*   Why doesn't input.config filtering via headers "Configs" work? 
    65*   add options support; in particular for whether or not to use threads (and adjust Init to use this). 
     
    3534 
    3635Done (for git log message): 
    37 *   Init threads now catch own exceptions. 
    38 *   Assigned some inputID devisions. 
    39 *   add remaining SDL event support 
    40 *   Rewrote most of mde.mergetag.defaultdata using generic programming to generate read & write rules for all types. As a result, defaultdata can now write properly. 
    41 *   Axis output now stored with short instead of real. 
    42 *   Input unittest 
    43 *       Moved mde/text to scrapple 
    44 *   DefaultData unittest. Then commit. 
     36*   Options class created (barebones). Loading/saving from Init. 
     37*   Init no longer runs cleanup functions after initialisation failure. 
     38*   Improved mergetag exception messages & error reporting. 
  • dsss.conf

    r10 r11  
    99 
    1010[mde/mde.d] 
    11 version (Posix) { 
    12     target=bin/mde 
    13 } else version (Windows) { 
    14     target=bin/mde.exe 
    15 
     11target=bin/mde 
    1612 
    1713[test/mdeTest.d] 
     14buildflags=-debug -debug=mdeUnitTest -unittest 
     15target=bin/mdeTest 
     16noinstall 
    1817version (Posix) { 
    19     buildflags=-L-ldl -debug=mdeUnitTest -unittest 
    20     target=bin/mdeTest 
    21 } else version (Windows) { 
    22     warn Extra linking probably needed! 
    23     buildflags=-debug=mdeUnitTest -unittest 
    24     target=bin/mdeTest.exe 
     18    buildflags+=-L-ldl 
     19} else { 
     20    warn Only posix builds have been tested; elsewhere other libraries will probably need to be linked. 
    2521} 
    26 noinstall 
  • mde/exception.d

    r10 r11  
    3939} 
    4040 
     41class optionsLoadException : mdeException { 
     42    // NOTE: if symbol is final, it can't be modified in the static this(), but as const it can 
     43    static const char[] symbol; 
     44    static this () {    symbol = super.symbol ~ ".options"; } 
     45    char[] getSymbol () { 
     46        return symbol; 
     47    } 
     48     
     49    this (char[] msg) { 
     50        super(msg); 
     51    } 
     52} 
     53 
    4154debug (mdeUnitTest) { 
    4255    import tango.util.log.Log : Log, Logger; 
     
    4558    static this() { 
    4659        logger = Log.getLogger ("mde.events"); 
     60        logger.info ("Got logger!"); 
    4761    } 
    4862     
  • mde/init.d

    r10 r11  
    88import mde.exception; 
    99 
     10import mde.options; 
    1011import mde.events; 
    1112import global = mde.global; 
     
    2223import derelict.sdl.sdl; 
    2324import derelict.util.exception; 
    24  
    25 private Logger logger; 
    2625 
    2726/** 
     
    4039        root.addAppender(new ConsoleAppender); 
    4140    } 
    42      
    43     logger = Log.getLogger ("mde.init"); 
    4441} 
    4542static ~this() 
     
    7976        * be run simultaneously in separate threads. */ 
    8077         
    81         bool initFailure = false;   // Set true if something goes wrong and we need to abort. 
    8278        void setFailure () {        // For synchronization, although shouldn't be necessary 
    8379            synchronized initFailure = true; 
     
    8581        void delegate() [] initFuncs = [ 
    8682        delegate void() { 
    87             logger = Log.getLogger ("mde.init.Init.SDL"); 
     83            Logger logger = Log.getLogger ("mde.init.Init.SDL"); 
     84             
    8885            // Inits SDL and related stuff (joystick). 
    8986            try { 
     
    114111            openJoysticks ();       // after SDL init 
    115112            addCleanupFct (&closeJoysticks); 
     113        }, 
     114        delegate void() { 
     115            Logger logger = Log.getLogger ("mde.init.Init.Options"); 
     116             
     117            try { 
     118                Options.load(); 
     119            } catch (optionsLoadException e) { 
     120                logger.fatal ("Loading options failed; message:"); 
     121                logger.fatal (e.msg); 
     122                setFailure(); 
     123                return; 
     124            } 
     125            addCleanupFct (&Options.save);  // not strictly cleanup, but needs to be called somewhere 
    116126        } 
    117127        ]; 
     
    158168            runCleanupFcts(); 
    159169             
     170            logger.fatal ("Init failed"); 
    160171            // Throw an exception to signal failure and prevent DTOR from also running. 
    161172            throw new initException ("Initialisation failed due to above exceptions."); 
     
    168179    ~this() 
    169180    { 
    170         runCleanupFcts();   // if threading, note not all functions can be called simultaeneously 
     181        if (!initFailure) { 
     182            logger.info ("Cleaning up..."); 
     183            runCleanupFcts();   // if threading, note not all functions can be called simultaeneously 
     184            logger.info ("Done!"); 
     185        } 
    171186    } 
    172187     
     
    189204        } 
    190205    } 
     206     
     207    /* This is set true by this() if something goes wrong and we need to abort. 
     208    * If it's true, no cleanup should be done by the DTOR (since the DTOR still runs after an 
     209    * exception has been thrown). */ 
     210    private bool initFailure = false; 
     211     
     212    debug (mdeUnitTest) unittest { 
     213        /* Fake init and cleanup. This happens before the CTOR runs so the extra Init.runCleanupFcts() 
     214        * call isn't going to mess things up. The extra function called by runCleanupFcts won't cause 
     215        * any harm either. */ 
     216        static bool initialised = false; 
     217        static void cleanup () {    initialised = false;    } 
     218         
     219        static void init () { 
     220            initialised = true; 
     221            Init.addCleanupFct (&cleanup); 
     222        } 
     223         
     224        init(); 
     225        assert (initialised); 
     226        Init.runCleanupFcts(); 
     227        assert (!initialised); 
     228 
     229        logger.info ("Unittest complete."); 
     230    } 
    191231} 
    192  
    193 debug (mdeUnitTest) unittest { 
    194     /* Fake init and cleanup. This happens before the CTOR runs so the extra Init.runCleanupFcts() 
    195     * call isn't going to mess things up. The extra function called by runCleanupFcts won't cause 
    196     * any harm either. */ 
    197     static bool initialised = false; 
    198     static void cleanup () {    initialised = false;    } 
    199          
    200     static void init () { 
    201         initialised = true; 
    202         Init.addCleanupFct (&cleanup); 
    203     } 
    204          
    205     init(); 
    206     assert (initialised); 
    207     Init.runCleanupFcts(); 
    208     assert (!initialised); 
    209  
    210     logger.info ("Unittest complete."); 
    211 } 
  • mde/input/input.d

    r10 r11  
    181181                break; 
    182182             
    183             case SDL_JOYBALLMOTION:    // NOTE: untested 
     183            case SDL_JOYBALLMOTION: 
    184184                outQueue[]* p = (Config.M.JOYBALL | (event.jball.which << 12) | event.jball.ball) in config.relMotion; 
    185185                if (p) foreach (outQueue q; *p) { 
     
    188188                break; 
    189189             
    190             case SDL_JOYHATMOTION: // NOTE: untested 
     190            case SDL_JOYHATMOTION: 
    191191                static ubyte[uint] oldJHatVals;     // necessary to store this to know which "axis" changed 
    192192         
     
    298298    short[inputID] axis;        // Table of axes states 
    299299    ushort mouse_x, mouse_y;        // Current screen coords of the window manager mouse 
    300     // FIXME: might need a bit of work... at any rate defining a default ID. 
    301300    RelPair[inputID] relMotion;     // Table of relative mouse / joystick ball motions 
    302301     
    303     // FIXME: these need to be more like multimaps, supporting multiple dgs (also some means of removal?) 
     302    // FIXME: currently no means of removal 
    304303    ButtonCallback[][inputID]   buttonCallbacks; 
    305304    AxisCallback[][inputID] axisCallbacks; 
  • mde/mde.d

    r10 r11  
    1010import mde.events; 
    1111import mde.scheduler; 
     12import mde.options;     // greeting message 
    1213import mde.exception; 
    1314 
     
    2425int main() 
    2526{ 
     27    //BEGIN Initialisation 
    2628    Logger logger = Log.getLogger ("mde.mde"); 
    2729     
     
    4143        } 
    4244    } ); 
     45    //END Initialisation 
     46     
     47    logger.info (options.greeting); 
    4348     
    4449    while (global.run) { 
  • mde/mergetag/exception.d

    r10 r11  
    1919        super(msg); 
    2020    } 
    21     this () {} 
     21    this () {   // Only called when an unexpected exception/error occurs 
     22        super ("Unknown exception"); 
     23    } 
    2224} 
    2325 
    2426/** Thrown on file IO errors. */ 
    2527class MTFileIOException : MTException { 
    26     this () {} 
     28    this () { 
     29        super ("File IO exception"); 
     30    } 
    2731} 
    2832 
    2933/** Thrown on unknown format errors; when reading or writing and the filetype cannot be guessed. */ 
    3034class MTFileFormatException : MTException { 
    31     this () {} 
     35    this () { 
     36        super ("File format exception"); 
     37    } 
     38
     39 
     40/** Thrown on syntax errors when reading; bad tags or unexpected EOF. */ 
     41class MTSyntaxException : MTException { 
     42    this () { 
     43        super ("Syntax exception"); 
     44    } 
    3245} 
    3346 
     
    3548 * unrecognised type field. */ 
    3649class MTUnknownTypeException : MTException { 
    37     this () {} 
     50    this () { 
     51        super ("Unknown type"); 
     52    } 
    3853    this (char[] msg) { 
    3954        super (msg); 
     
    4459* (really just to make whoever called addTag to log a warning saying where the error occured). */ 
    4560class MTaddTagParseException : MTException { 
    46     this () {} 
     61    this () { 
     62        super ("Parse exception within addTag"); 
     63    } 
    4764} 
    4865 
     66/+ 
    4967/// Thrown by TypeView.parse on errors. 
    5068class MTBadTypeStringException : MTException { 
    5169    this () {} 
    5270} 
     71+/ 
    5372 
    5473/// Thrown by *Writer.write. 
    5574class MTNoDataSetException : MTException { 
    56     this (char[] msg) { 
    57         super(msg); 
     75    this () { 
     76        super ("No dataset"); 
    5877    } 
    5978} 
  • mde/mergetag/read.d

    r10 r11  
    3939 * ----------------------- 
    4040 * 
    41  * Only a child-class of MTException will ever be thrown, currently MTFileIOException if the file 
    42  * could not be read or MTFileFormatException on any error when parsing the file. 
     41 * Throws: 
     42 *  $(TABLE 
     43 *  $(TR $(TH Exception) $(TH Thrown when)) 
     44 *  $(TR $(TD MTFileIOException) $(TD An error occurs while opening the file)) 
     45 *  $(TR $(TD MTFileFormatException) $(TD The file doesn't start with a recognised header/version)) 
     46 *  $(TR $(TD MTSyntaxException) $(TD A file syntax error occurs)) 
     47 *  $(TR $(TD MTException) $(TD An unexpected error occurs)) 
     48 *  ) 
     49 * Note that all exceptions extend MTException and when any exception is thrown the class is 
     50 * rendered unusable: any subsequent calls to read will be ignored. 
    4351 * 
    4452 * Threading: Separate instances of Reader should be thread-safe provided access to the same 
     
    162170        else endOfHeader = parseSection (6,null); 
    163171    } 
    164     // Was intended to close file, but file is closed within CTOR anyway. 
    165     public ~this () { 
    166     } 
    167172//END METHODS: CTOR / DTOR 
    168173     
     
    307312                uint pos_s = pos; 
    308313                fbufLocateDataTagChar (pos, false); // find end of type section 
    309                 if (fbuf[pos] != '|') throwMTErr (ErrDTAG); 
     314                if (fbuf[pos] != '|') throwMTErr (ErrDTAG, new MTSyntaxException); 
    310315                char[] type = fbuf[pos_s..pos]; 
    311316                 
     
    315320                pos_s = pos; 
    316321                fbufLocateDataTagChar (pos, false); // find end of type section 
    317                 if (fbuf[pos] != '=') throwMTErr (ErrDTAG); 
     322                if (fbuf[pos] != '=') throwMTErr (ErrDTAG, new MTSyntaxException); 
    318323                ID tagID = cast(ID) fbuf[pos_s..pos]; 
    319324                 
     
    322327                // Data section of tag: 
    323328                pos_s = pos; 
    324                 fbufLocateDataTagChar (pos, true); // find end of data section 
    325                 if (fbuf[pos] != '>') throwMTErr (ErrDTAG); 
     329                fbufLocateDataTagChar (pos, true);      // find end of data section 
     330                if (fbuf[pos] != '>') throwMTErr (ErrDTAG, new MTSyntaxException); 
    326331                char[] data = fbuf[pos_s..pos]; 
    327332                 
     
    342347                        logger.error ("Unknown error occured" ~ ErrInFile ~ ':'); 
    343348                        logger.error (e.msg); 
    344                         throw e;                        // Fatal to Reader 
     349                        throwMTErr (e.msg);             // Fatal to Reader 
    345350                    } 
    346351                } else comment = false;         // cancel comment status now 
     
    366371                                    // variable is reset at end of comment 
    367372            } else                  // must be an error 
    368                 throwMTErr ("Invalid character (or sequence starting \"!\") outside of tag" ~ ErrInFile); 
     373            throwMTErr ("Invalid character (or sequence starting \"!\") outside of tag" ~ ErrInFile, new MTSyntaxException); 
    369374        } 
    370375        // if code execution reaches here, we're at EOF 
     
    384389            if (fbuf[pos] == '}' || fbuf[pos] == '{') break; 
    385390         
    386         if (fbuf[pos] != '}') throwMTErr ("Bad section tag format: not {id}" ~ ErrInFile); 
     391        if (fbuf[pos] != '}') throwMTErr ("Bad section tag format: not {id}" ~ ErrInFile, new MTSyntaxException); 
    387392        ID id = cast(ID) fbuf[start..pos]; 
    388393        fbufIncrement(pos); 
     
    393398    private void fbufIncrement(inout uint pos) { 
    394399        ++pos; 
    395         if (pos >= fbuf.length) throwMTErr("Unexpected EOF" ~ ErrInFile); 
    396     } 
    397      
    398     private void throwMTErr (char[] msg, MTException exc = new MTFileFormatException) { 
     400        if (pos >= fbuf.length) throwMTErr("Unexpected EOF" ~ ErrInFile, new MTSyntaxException); 
     401    } 
     402     
     403    private void throwMTErr (char[] msg, MTException exc = new MTException) { 
    399404        fatal = true;   // if anyone catches the error and tries to do anything --- we're dead now 
    400405        logger.error (msg); // report the error 
  • mde/mergetag/write.d

    r10 r11  
    5252 * 
    5353 * An exception is thrown if neither test can deduce the writing method. 
     54 * 
     55 * Use as: 
     56 * ----------------------- 
     57 * DataSet dataset; // contains data to write 
     58 * IWriter foo; 
     59 * try { 
     60 *   foo = makeWriter("foo.mtt", dataset); 
     61 *   foo.write(); 
     62 * } 
     63 * catch (MTException) {} 
     64 * ----------------------- 
     65 * 
     66 * Throws: 
     67 *  MTFileFormatException if unable to determine writing format or use requested format. 
    5468 */ 
    5569IWriter makeWriter (char[] path, DataSet dataset = null, WriterMethod method = WriterMethod.Unspecified) { 
     
    5771} 
    5872/** ditto */ 
    59 IWriter makeWriter (PathView path, DataSet dataset = null, WriterMethod method = WriterMethod.Unspecified) { 
     73IWriter makeWriter (PathView path, DataSet dataset = null, WriterMethod method = WriterMethod.Unspecified) 
     74
    6075    void throwMTErr (char[] msg, Exception exc = new MTException) { 
    6176        logger.error (msg); 
     
    7186    else if (method == WriterMethod.Text) return new TextWriter (path, dataset); 
    7287    else if (method == WriterMethod.Both) throwMTErr ("Dual writing not supported yet!", new MTFileFormatException); 
     88    else debug throwMTErr ("Bad value of method", new MTFileFormatException); 
    7389} 
    7490 
     
    93109 * 
    94110 * Files are only actually open for writing while the write() method is running. 
     111 * 
     112 * Throws: 
     113 *  $(TABLE 
     114 *  $(TR $(TH Exception) $(TH Thrown when)) 
     115 *  $(TR $(TD MTNoDataSetException) $(TD No dataset is available to write from)) 
     116 *  $(TR $(TD MTFileIOException) $(TD An error occurs while attemting to write the file)) 
     117 *  $(TR $(TD MTException) $(TD An unexpected error occurs)) 
     118 *  ) 
     119 * Note that all exceptions extend MTException; unlike Reader exceptions don't block further calls. 
    95120 */ 
    96 scope class TextWriter : IWriter 
     121class TextWriter : IWriter 
    97122{ 
    98123//BEGIN DATA 
     
    113138    DataSet _dataset; 
    114139     
    115     PathView path; 
     140    PathView _path; 
    116141//END DATA 
    117142     
    118143//BEGIN CTOR / DTOR 
    119     /** Tries to open file path for writing. 
     144    /** Prepares to open file path for writing. 
     145    * 
     146    * The call doesn't actually execute any code so cannot fail (unless out of memory). 
    120147    * 
    121148    * Params: 
     
    125152    *     data into it. 
    126153    */ 
    127     public this (char[] _path, DataSet ds = null) { 
    128         this (new FilePath (_path), ds); 
     154    public this (char[] path, DataSet ds = null) { 
     155        this (new FilePath (path), ds); 
    129156    } 
    130157    /** ditto */ 
    131     public this (PathView _path, DataSet ds = null) { 
    132         path = _path; 
     158    public this (PathView path, DataSet ds = null) { 
     159        _path = path; 
    133160        _dataset = ds; 
    134161    } 
     
    142169     * multiple DataSets into one file without firstly merging them. Note that this behaviour may 
    143170     * be changed when binary support is added. 
    144      * 
    145      * Throws: 
    146      *  MTNoDataSetException if the dataset is null, 
    147      *  MTFileIOException if a file IO error occurs, 
    148      *  MTException on any other exception (unexpected). 
    149171     */ 
    150172    public void write () 
    151173    { 
    152         if (!_dataset) throw new MTNoDataSetException ("write(): Dataset needed to write from!"); 
     174        if (!_dataset) throwMTErr ("write(): no Dataset available to write from!", new MTNoDataSetException ()); 
    153175         
    154176        try { 
     
    157179             
    158180            // Open a conduit on the file: 
    159             conduit = new FileConduit (path, FileConduit.WriteCreate); 
     181            conduit = new FileConduit (_path, FileConduit.WriteCreate); 
    160182            scope(exit) conduit.close(); 
    161183             
  • test/mdeTest.d

    r10 r11  
    22*/ 
    33module test.mdeTest; 
    4  
    5 // Define this to run unittests: 
    6 debug=mdeUnitTest; 
    74 
    85// This module should import all mde modules containing unittests: