Changeset 85:56c0ddd90193
- Timestamp:
- 09/11/08 06:33:51 (4 months ago)
- Files:
-
- codeDoc/debugCodes.txt (added)
- codeDoc/ideas.txt (modified) (1 diff)
- codeDoc/jobs.txt (modified) (3 diffs)
- codeDoc/staticCtors.txt (modified) (1 diff)
- data/conf/options.mtt (modified) (1 diff)
- doc/Readme.txt (modified) (3 diffs)
- dsss.conf (modified) (2 diffs)
- examples/guiDemo.d (copied) (copied from mde/mde.d) (4 diffs)
- mde/events.d (modified) (2 diffs)
- mde/file/mergetag/Reader.d (modified) (3 diffs)
- mde/file/mergetag/Writer.d (modified) (4 diffs)
- mde/file/mergetag/iface/IReader.d (modified) (2 diffs)
- mde/font/FontTexture.d (modified) (1 diff)
- mde/font/font.d (modified) (5 diffs)
- mde/gl/draw.d (deleted)
- mde/gui/WidgetManager.d (modified) (14 diffs)
- mde/gui/widget/Ifaces.d (modified) (1 diff)
- mde/gui/widget/createWidget.d (modified) (2 diffs)
- mde/gui/widget/layout.d (modified) (1 diff)
- mde/input/Config.d (modified) (3 diffs)
- mde/input/joystick.d (modified) (3 diffs)
- mde/lookup/Options.d (modified) (5 diffs)
- mde/mde.d (modified) (2 diffs)
- mde/scheduler/Scheduler.d (modified) (4 diffs)
- mde/setup/Init.d (modified) (5 diffs)
- mde/setup/InitStage.d (moved) (moved from mde/setup/init2.d) (1 diff)
- mde/setup/Screen.d (moved) (moved from mde/setup/sdl.d) (2 diffs)
- mde/setup/exception.d (modified) (2 diffs)
- mde/setup/initFunctions.d (deleted)
- mde/setup/paths.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
codeDoc/ideas.txt
r43 r85 1 Copyright © 2007-2008 Diggory Hardy 2 License: GNU General Public License version 2 or later (see COPYING) 3 4 1 5 Miscelaneous ideas for mde. 2 6 codeDoc/jobs.txt
r84 r85 4 4 5 5 In progress: 6 why is nothing drawn until a resize? seems to be working now (??) 7 why isn't font texture drawn in mde? 8 why does mde&guiDemo hang on exit, only if no resize occurred? 9 wierd things with options.mtt (font section getting output twice) 10 CircularIterator 11 unittest again! 6 12 7 13 … … 9 15 To do (importance 0-5: 0 pointless, 1 no obvious impact now, 2 todo sometime, 3 useful, 4 important, 5 urgent): 10 16 Also see todo.txt and FIXME/NOTE comment marks. 11 5 setting widgets' default size? setMinSize/setDefaultSize fct? 17 4 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. 12 18 4 Try to correlate names of option sections more. (i.e. symbol name, class name, name of i18n translation file) 13 19 4 Not guaranteed to catch up-click ending callback! Appears not to be a problem... … … 19 25 3 Update scheduler as outlined in FIXME. 20 26 3 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.22 27 2 Remove ability to scan, then load, mergetag sections. Not so necessary with section creator callback and allows "sliding window" type partial buffering. 23 28 2 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): 1 Copyright © 2007-2008 Diggory Hardy 2 License: GNU General Public License version 2 or later (see COPYING) 3 4 5 Map of what happens in static CTORs (excluding creating loggers). From August 2008. 2 6 3 7 mde data/conf/options.mtt
r55 r85 1 1 {MT01} 2 2 {misc} 3 < bool|useThreads=false>3 <int|numThreads=2> 4 4 <bool|exitImmediately=false> 5 5 <char[]|L10n="en-GB"> 6 <int|logOptions=0x300 1>6 <int|logOptions=0x3000> 7 7 <double|pollInterval=0.01> 8 8 doc/Readme.txt
r70 r85 34 34 Also thanks to: 35 35 Walter Bright and Digital Mars for D and DMD. 36 The tango team for Tango.36 The tango team. 37 37 [derelict] 38 38 [sdl] … … 60 60 + How many lines are there? 61 61 # wc -l $(find . -name "*.d") 62 As of last count, that was 3908.62 As of my last count, that was 10227. 63 63 64 64 + Why is the code so DENSE? … … 67 67 + What toolkits/external libraries are used? 68 68 tango 69 tango.scrapple 70 SDL (possibly will be replaced) 69 derelict (SDL, OpenGL, FreeType 2) 71 70 72 71 + 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 2 2 # License: GNU General Public License version 2 or later (see COPYING) 3 3 4 defaulttargets = mde/mde.d 4 defaulttargets = mde/mde.d examples/guiDemo.d 5 5 6 6 [*] … … 15 15 target=bin/mde 16 16 17 [examples/guiDemo.d] 18 target=bin/guiDemo 19 17 20 [util/mtcp.d] 18 21 target=bin/mtcp examples/guiDemo.d
r84 r85 14 14 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 15 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. */ 17 module examples.guiDemo; 22 18 23 19 import mde.imde; // this module's interface for external modules … … 26 22 import mde.lookup.Options; // pollInterval option 27 23 import mde.scheduler.Scheduler; // mainSchedule 28 import gl = mde.gl.draw; // gl.draw() 24 import mde.setup.Screen; // Screen.draw() 25 import mde.setup.InitStage; // StageState 26 import mde.gui.WidgetManager; 29 27 30 28 import tango.core.Thread : Thread; // Thread.sleep() … … 38 36 int main(char[][] args) 39 37 { 38 Logger logger = Log.getLogger ("mde.mde"); 40 39 // If compiled with unittests, notify that they completed and exit: 41 40 debug (mdeUnitTest) { 42 Logger logger = Log.getLogger ("mde.mde");43 41 logger.info ("Compiled unittests have completed; terminating."); 44 42 return 0; 45 43 } 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"]); 46 57 47 58 scope Init init = new Init(args); // initialize mde … … 57 68 * Note: probably drawing should start at the beginning of the loop and glFlush()/swapBuffers 58 69 * 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. 60 71 mainSchedule.add (mainSchedule.getNewID, &mde.events.pollEvents).frame = true; 61 72 //END Main loop setup mde/events.d
r63 r85 21 21 22 22 import imde = mde.imde; 23 import sdl = mde.setup.sdl; // resizeWindow23 import mde.setup.Screen; 24 24 25 25 import mde.input.Input; … … 45 45 break; 46 46 case SDL_VIDEORESIZE: 47 sdl.resizeWindow(event.resize.w, event.resize.h);47 Screen.resizeEvent (event.resize.w, event.resize.h); 48 48 imde.mainSchedule.request(imde.SCHEDULE.DRAW); 49 49 break; mde/file/mergetag/Reader.d
r82 r85 33 33 import Util = tango.text.Util; 34 34 import ConvInt = tango.text.convert.Integer; 35 //import tango.util.collection.model.View : View; 36 import tango.util.collection.HashSet : HashSet; 35 import tango.util.container.HashSet; 37 36 import tango.util.log.Log : Log, Logger; 38 37 … … 306 305 } 307 306 /** ditto */ 308 public void read ( View!(ID) secSet) {307 public void read (IContainer!(ID) secSet) { 309 308 if (allRead || fatal) return; // never do anything in either case 310 309 … … 517 516 void read () {} /// Commence reading 518 517 void read (ID[] secSet) {} /// ditto 519 void read ( View!(ID) secSet) {}/// ditto518 void read (IContainer!(ID) secSet) {}/// ditto 520 519 } mde/file/mergetag/Writer.d
r82 r85 37 37 // tango imports 38 38 import tango.core.Exception; 39 import tango.io. FileConduit;39 import tango.io.device.FileConduit; 40 40 import tango.io.Buffer : Buffer, IBuffer; 41 41 import tango.io.Print : Print; … … 163 163 _path = path; 164 164 _dataset = ds; 165 foreach (i,s; _dataset.sec) 166 debug logger.trace ("sec ID length: {}", i.length); 165 167 } 166 168 //END CTOR / DTOR … … 179 181 180 182 try { 183 debug logger.trace ("W.w: 1"); 181 184 FileConduit conduit; // actual conduit; don't use directly when there's content in the buffer 182 185 IBuffer buffer; // write strings directly to this (use opCall(void[]) ) 183 186 187 debug logger.trace ("W.w: 2"); 184 188 // Open a conduit on the file: 185 189 conduit = new FileConduit (_path, FileConduit.WriteCreate); 186 190 scope(exit) conduit.close(); 187 191 192 debug logger.trace ("W.w: 3"); 188 193 buffer = new Buffer(conduit); // And a buffer 189 194 scope(exit) buffer.flush(); 190 195 196 debug logger.trace ("W.w: 4"); 191 197 // Write the header: 192 198 buffer ("{MT" ~ MTFormatVersion.CurrentString ~ "}" ~ Eol); 199 debug logger.trace ("W.w: 5"); 193 200 if (_dataset.header !is null) writeSection (buffer, _dataset.header); 194 201 202 debug logger.trace ("W.w: 6"); 195 203 // Write the rest: 196 204 foreach (ID id, IDataSection sec; _dataset.sec) { 205 debug logger.trace ("W.w: 71"); 197 206 writeSectionIdentifier (buffer, id); 207 debug logger.trace ("W.w: 72"); 198 208 writeSection (buffer, sec); 199 209 } 200 210 211 debug logger.trace ("W.w: 8"); 201 212 buffer.flush(); 202 213 214 debug logger.trace ("W.w: 9"); 203 215 } 204 216 catch (IOException e) { … … 211 223 212 224 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"); 214 233 } 215 234 mde/file/mergetag/iface/IReader.d
r81 r85 21 21 import mde.file.mergetag.DataSet; 22 22 23 import tango.util.collection.model.View : View;23 public import tango.util.container.model.IContainer; 24 24 25 25 /** Interface for all mergetag readers (MTTReader etc.). … … 34 34 void read (); /// Commence reading 35 35 void read (ID[] secSet); /// ditto 36 void read ( View!(ID) secSet); /// ditto36 void read (IContainer!(ID) secSet); /// ditto 37 37 } mde/font/FontTexture.d
r83 r85 53 53 { 54 54 this () {} 55 ~this () { 56 foreach (t; tex) { 57 glDeleteTextures (1, &(t.texID)); 58 } 59 } 55 ~this () {} 60 56 61 57 // Call if font(s) have been changed and glyphs must be recached. mde/font/font.d
r84 r85 25 25 import mde.file.mergetag.DataSet; 26 26 import mde.setup.paths; 27 import mde.setup.exception; // InitStage stuff 27 28 28 29 import derelict.freetype.ft; … … 56 57 } 57 58 58 /** Load the freetype library from the file fileName. */59 /** Load the freetype library with settings from the file fileName. */ 59 60 private const fileName = "fonts"; 60 voidinitialize () {61 StageState initialize () { 61 62 if (FT_Init_FreeType (&library)) 62 63 throw new fontException ("error initialising the FreeType library"); … … 77 78 * is not compiled into the library. */ 78 79 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."); 80 81 81 82 // Reset the default filter (in case an invalid value was set in config files). … … 123 124 // Also note that get() doesn't make sure the fallback is loaded before returning it. 124 125 fallback.load; 126 127 return StageState.ACTIVE; 125 128 } 126 129 127 130 //FIXME: don't use GC for FontStyle resources 128 131 /** 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; 131 143 } 132 144 … … 286 298 287 299 ~this () { 300 debug logger.trace ("{}.~this: start", this); 288 301 FT_Done_Face (face); 302 debug logger.trace ("{}.~this: done", this); 289 303 } 290 304 mde/gui/WidgetManager.d
r84 r85 30 30 import mde.input.Input; 31 31 import mde.scheduler.Scheduler; 32 import mde.setup.Screen; 32 33 33 34 import tango.core.sync.Mutex; … … 37 38 static this () { 38 39 logger = Log.getLogger ("mde.gui.WidgetManager"); 39 40 gui = new WidgetManager ("gui");41 40 } 42 43 WidgetManager gui;44 45 41 46 42 /************************************************************************************************* … … 55 51 * Aside from the IWidgetManager methods, this class should be thread-safe. 56 52 *************************************************************************************************/ 57 class WidgetManager : WidgetLoader {53 class WidgetManager : WidgetLoader, Screen.Drawable { 58 54 /** Construct a new widget manager. 59 55 * … … 63 59 this (char[] file) { 64 60 super(file); 61 62 Screen.addDrawable (this); 65 63 } 66 64 … … 68 66 // called during init 69 67 void init () { 68 // Doesn't need a lock - cannot conflict with other class functions. 70 69 // Events we want to know about: 71 70 imde.input.addMouseClickCallback(&clickEvent); … … 76 75 /** Draw the gui. */ 77 76 void draw() { 77 debug logger.trace ("drawing; w,h = {},{}",w,h); 78 78 synchronized(mutex) 79 child.draw; 79 if (child) 80 child.draw; 80 81 } 81 82 … … 89 90 mutex.lock; 90 91 scope(exit) mutex.unlock; 92 if (child is null) return; 91 93 92 94 // NOTE: buttons receive the up-event even when drag-callbacks are in place. … … 96 98 97 99 // NOTE: do we need to test if the click was on the gui (and thus child)? 100 // FIXME: yes, unless we can guarantee this! 98 101 IChildWidget widg = child.getWidget (cast(wdabs)cx,cast(wdabs)cy); 99 102 if (widg !is null) 100 103 widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state); 101 /+ FIXME: remove102 foreach (i,w; windows) {103 IWidget widg = w.getWidget (cast(wdabs)cx,cast(wdabs)cy);104 if (widg !is null) {105 // Bring to front106 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 front110 return; // only pass to first window111 }112 }+/113 104 } 114 105 … … 127 118 128 119 129 void s etSize (int x, int y) {120 void sizeEvent (int nw, int nh) { // Drawable function 130 121 mutex.lock; 131 122 scope(exit) mutex.unlock; 132 123 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. 138 132 child.setWidth (w, -1); 139 133 child.setHeight (h, -1); … … 166 160 167 161 protected: 168 /* Second stage of widget loading. */ 162 /* Second stage of widget loading. 163 * Note: sizeEvent should be called with window size before this. */ 169 164 void createRootWidget () { 170 165 // The renderer needs to be created on the first load, but not after this. … … 173 168 174 169 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); 175 176 176 177 child.setWidth (w, -1); … … 185 186 IRenderer rend; 186 187 wdim w,h; // area available to the widgets 188 wdim mw,mh; // minimal area available to the widgets 187 189 } 188 190 … … 212 214 mutex = new Mutex; // Used on functions intended to be called from outside the gui package. 213 215 fileName = file; 214 }215 ~this () {216 save;217 216 } 218 217 … … 381 380 /** Create a widget by ID. */ 382 381 IChildWidget makeWidget (widgetID id, IParentWidget parent = null) { 383 debug logger.trace ("Creating widget \""~id~'"');382 debug (mdeWidgets) logger.trace ("Creating widget \""~id~'"'); 384 383 return createWidget (this, curData[id], parent); 385 384 } mde/gui/widget/Ifaces.d
r80 r85 125 125 * 126 126 * 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(). 129 130 * It should use Ddoc to explain what initialization data is used. 130 131 * ---------------------------------- mde/gui/widget/createWidget.d
r80 r85 54 54 55 55 //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]); 57 57 58 58 // Not returned a new widget... … … 124 124 foreach (c; consts) { 125 125 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" ~ 127 127 " static if (WIDGET_TYPE."~c~" & WIDGET_TYPE.TAKES_PARENT)\n" ~ 128 128 " return new " ~ c ~ "Widget (mgr, data, parent);\n" ~ mde/gui/widget/layout.d
r78 r85 429 429 --i; 430 430 } // 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)"); 432 433 return -i - 1; // note: i might be 0 so cannot just return -i 434 } 433 435 return i; 434 436 } mde/input/Config.d
r84 r85 25 25 26 26 import tango.util.log.Log : Log, Logger; 27 import tango.util.co llection.TreeBag : TreeBag;27 import tango.util.container.HashSet; 28 28 29 29 /** Class to hold the configuration for the input system. Thus loading and switching between … … 116 116 117 117 static Config[char[]] configs; /// All configs loaded by load(). 118 private static TreeBag!(char[]) loadedFiles; // all filenames load tried to read118 private static HashSet!(char[]) loadedFiles; // all filenames load tried to read 119 119 private static Logger logger; 120 120 … … 122 122 static this () { 123 123 logger = Log.getLogger ("mde.input.Config"); 124 loadedFiles = new TreeBag!(char[]);124 loadedFiles = new HashSet!(char[]); 125 125 } 126 126 mde/input/joystick.d
r67 r85 19 19 module mde.input.joystick; 20 20 21 import mde.setup.exception; // InitStage 21 22 import tango.util.log.Log : Log, Logger; 22 23 … … 36 37 * closeJoysticks must be run to cleanup afterwards. 37 38 */ 38 voidopenJoysticks () {39 StageState openJoysticks () { 39 40 joysticks = new SDL_Joystick*[SDL_NumJoysticks ()]; 40 41 … … 42 43 if ((joysticks[i] = SDL_JoystickOpen (i)) is null) { // null on failure 43 44 logger.error ("Unable to open joystick {} via SDL", i); 45 return StageState.ERROR; // prevent closeJoysticks running, but don't halt program 44 46 } 45 47 } 46 48 47 49 logger.info ("Opened {} joysticks via SDL, succesfully unless preceding errors say otherwise.", joysticks.length); 50 return StageState.ACTIVE; 48 51 } 49 52 50 53 /// Cleanup fct. 51 voidcloseJoysticks () {54 StageState closeJoysticks () { 52 55 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. 55 57 debug logger.trace ("Closing joysticks (this sometimes fails when mde exits prematurely)"); 56 58 if(js !is null) SDL_JoystickClose(js); // only close if successfully opened 57 59 debug logger.trace ("Done closing joysticks"); 58 60 } 61 return StageState.INACTIVE; 59 62 } mde/lookup/Options.d
r84 r85 137 137 assert (((cast(ID) i) in subClasses) is null); // Don't allow a silent replacement 138 138 } body { 139 debug logger.trace ("Adding Options subClass: "~i); 139 140 subClasses[cast(ID) i] = c; 140 141 } … … 169 170 void save () { 170 171 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; 172 178 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 175 187 // Read locally-stored options 176 188 try { … … 178 190 reader = confDir.makeMTReader (fileName, PRIORITY.HIGH_ONLY, ds); 179 191 reader.dataSecCreator = delegate IDataSection(ID id) { 192 debug logger.trace ("New section to save ignored: "~id); 180 193 return null; // All recognised sections are already in the dataset. 181 194 }; … … 189 202 190 203 try { 204 debug logger.trace ("1"); 191 205 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"); 194 213 } catch (Exception e) { 195 214 logger.error ("Saving options aborted: "~e.msg); … … 458 477 OptionsMisc miscOpts; 459 478 class OptionsMisc : Options { 460 mixin (impl!("bool useThreads, exitImmediately; intlogOptions; double pollInterval; char[] L10n, a,b,c;"));479 mixin (impl!("bool exitImmediately; int numThreads, logOptions; double pollInterval; char[] L10n, a,b,c;")); 461 480 462 481 static this() { mde/mde.d
r84 r85 26 26 import mde.lookup.Options; // pollInterval option 27 27 import mde.scheduler.Scheduler; // mainSchedule 28 import gl = mde.gl.draw; // gl.draw()28 import mde.setup.Screen; // Screen.draw() 29 29 30 30 import tango.core.Thread : Thread; // Thread.sleep() … … 57 57 * Note: probably drawing should start at the beginning of the loop and glFlush()/swapBuffers 58 58 * 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. 60 60 mainSchedule.add (mainSchedule.getNewID, &mde.events.pollEvents).frame = true; 61 61 //END Main loop setup mde/scheduler/Scheduler.d
r63 r85 77 77 * Use the returned pointer to set the scheduling, e.g.: 78 78 * ----- 79 * scheduler.add(scheduler.getNewID, myFunction).set(false, TimeSpan. millis (10));79 * scheduler.add(scheduler.getNewID, myFunction).set(false, TimeSpan.fromMillis (10)); 80 80 * scheduler.get(15).frame = true; 81 81 */ … … 177 177 s.add(1,&inc1).frame = true; 178 178 179 TimeSpan interval = TimeSpan. millis(1);// non-zero so we can check zero after first call179 TimeSpan interval = TimeSpan.fromMillis(1);// non-zero so we can check zero after first call 180 180 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)); 182 182 183 183 Time t = Time.epoch1970; // starting time (value isn't important) … … 186 186 assert (interval == TimeSpan.zero); // initial interval 187 187 188 t += TimeSpan. millis (5); // 5ms later...188 t += TimeSpan.fromMillis (5); // 5ms later... 189 189 s.execute (t); 190 190 assert (ctr1 == 2); … … 194 194 s.get(1).request = true; // but request next call 195 195 196 t += TimeSpan. millis (5);196 t += TimeSpan.fromMillis (5); 197 197 s.execute (t); 198 198 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!) 200 200 201 201 s.request(2); // request this 202 202 203 t += TimeSpan. millis (8);203 t += TimeSpan.fromMillis (8); 204 204 s.execute (t); 205 205 assert (ctr1 == 3); // inc1 shouldn't run 206 assert (interval == TimeSpan. millis (8)); // perInt was requested207 208 t += TimeSpan. millis (4);206 assert (interval == TimeSpan.fromMillis (8)); // perInt was requested 207 208 t += TimeSpan.fromMillis (4); 209 209 s.execute (t); 210 210 // 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)); 212 212 213 213 logger.info ("Unittest complete."); mde/setup/Init.d
r77 r85 15 15 16 16 /************************************************************************************************** 17 * Initialisation setup and exit cleanupmodule.17 * Initialisation and cleanup (shutdown) module. 18 18 * 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. 22 40 *************************************************************************************************/ 23 41 module mde.setup.Init; 24 42 25 import mde.setup.init2; // This module is responsible for setting up some init functions. 26 import mde.setup.initFunctions; 43 import mde.setup.InitStage; // Controls external delegates run by init 27 44 import mde.setup.exception; 28 45 29 46 import mde.lookup.Options; 30 47 import paths = mde.setup.paths; 31 import mde.exception; 48 import mde.exception; // optionsLoadException 32 49 33 50 // tango imports 34 51 import tango.core.Thread; 52 import tango.core.sync.Condition; 35 53 import tango.core.Exception; 36 import tango.stdc.stringz : fromStringz; 54 import tango.util.container.LinkedList; 55 56 //import tango.stdc.stringz : fromStringz; 37 57 import tango.io.Console; // for printing command-line usage 38 58 import TimeStamp = tango.text.convert.TimeStamp, tango.time.WallClock; // output date in log file 39 59 import tango.util.Arguments; 40 import tango.util.log.Log : Log, Logger, Level;60 import tango.util.log.Log; 41 61 import tango.util.log.AppendConsole; 42 62 import tango.util.log.AppendFiles; … … 49 69 import derelict.util.exception; 50 70 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,
