From 53c20f04989cffe3fee8215379f2b3aad60204ce Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Wed, 11 Nov 2015 14:56:25 +0300 Subject: [PATCH] fix crash in release mode --- dub.json | 19 ++++- examples/example1/dub.json | 8 +- examples/example1/src/example1.d | 4 +- src/dlangui/core/logger.d | 102 ++++++++++++++++-------- src/dlangui/graphics/ftfonts.d | 8 +- src/dlangui/platforms/common/platform.d | 21 ++++- src/dlangui/platforms/windows/winapp.d | 6 +- 7 files changed, 123 insertions(+), 45 deletions(-) diff --git a/dub.json b/dub.json index 135e3e24..a2eb57f9 100644 --- a/dub.json +++ b/dub.json @@ -40,7 +40,7 @@ "configurations": [ { "name": "default", - "versions": ["USE_OPENGL", "EmbedStandardResources", "USE_FREETYPE"], + "versions": ["USE_OPENGL", "EmbedStandardResources", "USE_FREETYPE", "ForceLogs"], "versions-posix": ["USE_SDL"], "versions-windows": ["Unicode"], "dependencies": { @@ -50,7 +50,7 @@ "gl3n": "~>1.2.0" }, "dependencies-posix": { - "derelict-sdl2": "~>1.9.1" + "derelict-sdl2": "~>1.9.7" }, "copyFiles-windows-x86_64": [ "libs/windows/x86_64/libfreetype-6.dll" @@ -59,6 +59,19 @@ "libs/windows/x86/libfreetype-6.dll" ] }, + { + "name": "minimal", + "versions": ["EmbedStandardResources", "ForceLogs"], + "versions-posix": ["USE_SDL", "USE_FREETYPE"], + "versions-windows": ["Unicode"], + "dependencies": { + "dlib": "~>0.7.0", + "gl3n": "~>1.2.0" + }, + "dependencies-posix": { + "derelict-sdl2": "~>1.9.7" + } + }, { "name": "sdl", "versions": ["USE_SDL", "USE_OPENGL", "USE_FREETYPE", "EmbedStandardResources"], @@ -88,7 +101,7 @@ "derelict-gl3": "~>1.0.16", "derelict-ft": "~>1.0.2", "gl3n": "~>1.2.0", - "dsfml": "~master" + "dsfml": "~>2.1.0" }, "copyFiles-windows-x86_64": [ "libs/windows/x86_64/libfreetype-6.dll" diff --git a/examples/example1/dub.json b/examples/example1/dub.json index 19c91784..cd670f62 100644 --- a/examples/example1/dub.json +++ b/examples/example1/dub.json @@ -9,11 +9,17 @@ "targetType": "executable", "targetName": "example1", + "versions": ["EmbedStandardResources", "ForceLogs"], + "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi"], "sourceFiles-windows": ["$PACKAGE_DIR/src/win_app.def"], "dependencies": { - "dlangui": "*" + "dlangui": {"path": "../../"} + }, + + "subConfigurations": { + "dlangui": "minimal" } } diff --git a/examples/example1/src/example1.d b/examples/example1/src/example1.d index e0bebf50..56dec3b6 100644 --- a/examples/example1/src/example1.d +++ b/examples/example1/src/example1.d @@ -189,8 +189,8 @@ enum : int { extern (C) int UIAppMain(string[] args) { // always use trace, even for release builds - Log.setLogLevel(LogLevel.Trace); - Log.setFileLogger(std.stdio.File("ui.log", "w")); + //Log.setLogLevel(LogLevel.Trace); + //Log.setFileLogger(new std.stdio.File("ui.log", "w")); // resource directory search paths // not required if only embedded resources are used diff --git a/src/dlangui/core/logger.d b/src/dlangui/core/logger.d index ef0cd05b..63220dec 100644 --- a/src/dlangui/core/logger.d +++ b/src/dlangui/core/logger.d @@ -76,33 +76,56 @@ Log.e("exception while reading file", e); ---- */ -synchronized class Log { - static: - __gshared private LogLevel logLevel = LogLevel.Info; - __gshared private std.stdio.File logFile; + +import core.sync.mutex; + +class Log { + static __gshared private LogLevel logLevel = LogLevel.Info; + static __gshared private std.stdio.File * logFile = null; + static __gshared private Mutex mutex = null; + + static this() { + Log.mutex = new Mutex(); + } /// Redirects output to stdout - void setStdoutLogger() { - logFile = stdout; + static public void setStdoutLogger() { + synchronized(mutex) { + logFile = &stdout; + } } /// Redirects output to stderr - void setStderrLogger() { - logFile = stderr; + static public void setStderrLogger() { + synchronized(mutex) { + logFile = &stderr; + } } /// Redirects output to file - void setFileLogger(File file) { - logFile = file; + static public void setFileLogger(File * file) { + synchronized(mutex) { + if (logFile !is null && logFile != &stdout && logFile != &stderr) { + logFile.close(); + destroy(logFile); + logFile = null; + } + logFile = file; + if (logFile !is null) + logFile.writeln("DlangUI log file"); + } } /// Sets log level (one of LogLevel) - void setLogLevel(LogLevel level) { - logLevel = level; + static public void setLogLevel(LogLevel level) { + synchronized(mutex) { + logLevel = level; + i("Log level changed to ", level); + } } /// Log level to name helper function - string logLevelName(LogLevel level) { + static public string logLevelName(LogLevel level) { switch (level) { case LogLevel.Fatal: return "F"; case LogLevel.Error: return "E"; @@ -114,8 +137,8 @@ synchronized class Log { } } /// Log message with arbitrary log level - void log(S...)(LogLevel level, S args) { - if (logLevel >= level && logFile.isOpen) { + static public void log(S...)(LogLevel level, S args) { + if (logLevel >= level && logFile !is null && logFile.isOpen) { SysTime ts = Clock.currTime(); logFile.writef("%04d-%02d-%02d %02d:%02d:%02d.%03d %s ", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, ts.fracSecs.split!("msecs").msecs, logLevelName(level)); logFile.writeln(args); @@ -123,34 +146,46 @@ synchronized class Log { } } /// Log verbose / trace message - void v(S...)(S args) { - if (logLevel >= LogLevel.Trace && logFile.isOpen) - log(LogLevel.Trace, args); + static public void v(S...)(S args) { + synchronized(mutex) { + if (logLevel >= LogLevel.Trace && logFile !is null && logFile.isOpen) + log(LogLevel.Trace, args); + } } /// Log debug message - void d(S...)(S args) { - if (logLevel >= LogLevel.Debug && logFile.isOpen) - log(LogLevel.Debug, args); + static public void d(S...)(S args) { + synchronized(mutex) { + if (logLevel >= LogLevel.Debug && logFile !is null && logFile.isOpen) + log(LogLevel.Debug, args); + } } /// Log info message - void i(S...)(S args) { - if (logLevel >= LogLevel.Info && logFile.isOpen) - log(LogLevel.Info, args); + static public void i(S...)(S args) { + synchronized(mutex) { + if (logLevel >= LogLevel.Info && logFile !is null && logFile.isOpen) + log(LogLevel.Info, args); + } } /// Log warn message - void w(S...)(S args) { - if (logLevel >= LogLevel.Warn && logFile.isOpen) - log(LogLevel.Warn, args); + static public void w(S...)(S args) { + synchronized(mutex) { + if (logLevel >= LogLevel.Warn && logFile !is null && logFile.isOpen) + log(LogLevel.Warn, args); + } } /// Log error message - void e(S...)(S args) { - if (logLevel >= LogLevel.Error && logFile.isOpen) - log(LogLevel.Error, args); + static public void e(S...)(S args) { + synchronized(mutex) { + if (logLevel >= LogLevel.Error && logFile !is null && logFile.isOpen) + log(LogLevel.Error, args); + } } /// Log fatal error message - void f(S...)(S args) { - if (logLevel >= LogLevel.Fatal && logFile.isOpen) - log(LogLevel.Fatal, args); + static public void f(S...)(S args) { + synchronized(mutex) { + if (logLevel >= LogLevel.Fatal && logFile !is null && logFile.isOpen) + log(LogLevel.Fatal, args); + } } } @@ -168,3 +203,4 @@ debug { void onResourceDestroyWhileShutdown(string resourceName, string objname = null) { Log.e("Resource leak: destroying resource while shutdown! ", resourceName, " ", objname); } + diff --git a/src/dlangui/graphics/ftfonts.d b/src/dlangui/graphics/ftfonts.d index 2140a6ec..0c1c0c80 100644 --- a/src/dlangui/graphics/ftfonts.d +++ b/src/dlangui/graphics/ftfonts.d @@ -9,6 +9,8 @@ Authors: Vadim Lopatin, coolreader.org@gmail.com */ module dlangui.graphics.ftfonts; +version(USE_FREETYPE): + import dlangui.graphics.fonts; import derelict.freetype.ft; @@ -524,12 +526,16 @@ class FreeTypeFontManager : FontManager { this() { // load dynaic library try { + Log.v("DerelictFT: Loading FreeType library"); DerelictFT.missingSymbolCallback = &missingSymFunc; + Log.v("DerelictFT: Missing symbols callback is registered"); DerelictFT.load(); - } catch (Exception e) { + Log.v("DerelictFT: Loaded"); + } catch (Throwable e) { Log.e("Derelict: cannot load freetype shared library: ", e.msg); throw new Exception("Cannot load freetype library"); } + Log.v("Initializing FreeType library"); // init library int error = FT_Init_FreeType(&_library); if (error) { diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index a7347f18..399f342d 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -1416,8 +1416,11 @@ version (Windows) { try { /// testing freetype font manager version(USE_FREETYPE) { + Log.v("Trying to init FreeType font manager"); + import dlangui.graphics.ftfonts; // trying to create font manager + Log.v("Creating FreeTypeFontManager"); FreeTypeFontManager ftfontMan = new FreeTypeFontManager(); import win32.shlobj; @@ -1444,6 +1447,7 @@ version (Windows) { } } } + Log.v("Registering fonts"); ftfontMan.registerFont(fontsPath ~ "arial.ttf", FontFamily.SansSerif, "Arial", false, FontWeight.Normal); ftfontMan.registerFont(fontsPath ~ "arialbd.ttf", FontFamily.SansSerif, "Arial", false, FontWeight.Bold); ftfontMan.registerFont(fontsPath ~ "arialbi.ttf", FontFamily.SansSerif, "Arial", true, FontWeight.Bold); @@ -1590,9 +1594,13 @@ void releaseResourcesOnAppExit() { void initLogs() { version (Windows) { debug { - Log.setFileLogger(std.stdio.File("ui.log", "w")); + Log.setFileLogger(new std.stdio.File("ui.log", "w")); } else { - // no logging + // no logging unless version ForceLogs is set + version(ForceLogs) { + Log.setFileLogger(new std.stdio.File("ui.log", "w")); + Log.i("Logging to file ui.log"); + } } } else { Log.setStderrLogger(); @@ -1600,6 +1608,13 @@ void initLogs() { debug { Log.setLogLevel(LogLevel.Trace); } else { - Log.setLogLevel(LogLevel.Warn); + version(ForceLogs) { + Log.setLogLevel(LogLevel.Trace); + Log.i("Log level: trace"); + } else { + Log.setLogLevel(LogLevel.Warn); + Log.i("Log level: warn"); + } } + Log.i("Logger is initialized"); } diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 302d8bfa..d4e4a7d9 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -905,8 +905,7 @@ int DLANGUIWinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int nCmdShow) { int result; - try - { + try { Runtime.initialize(); // call SetProcessDPIAware to support HI DPI - fix by Kapps @@ -973,7 +972,9 @@ int myWinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int iCmdSho _cmdShow = iCmdShow; _hInstance = hInstance; + Log.v("Creating platform"); w32platform = new Win32Platform(); + Log.v("Registering window class"); if (!w32platform.registerWndClass()) { MessageBoxA(null, "This program requires Windows NT!", "DLANGUI App".toStringz, MB_ICONERROR); return 0; @@ -981,6 +982,7 @@ int myWinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int iCmdSho Platform.setInstance(w32platform); + Log.v("Initializing font manager"); if (!initFontManager()) { Log.e("******************************************************************"); Log.e("No font files found!!!");