mirror of https://github.com/buggins/dlangui.git
resource leak detection - always enable for debug builds
This commit is contained in:
parent
d34ffd75a1
commit
195a8587be
|
@ -153,3 +153,18 @@ synchronized class Log {
|
|||
log(LogLevel.Fatal, args);
|
||||
}
|
||||
}
|
||||
|
||||
debug {
|
||||
private static __gshared bool _appShuttingDown = false;
|
||||
|
||||
@property bool appShuttingDown() { return _appShuttingDown; }
|
||||
|
||||
/// for debug purposes - sets shutdown flag to log widgets not destroyed in time.
|
||||
void setAppShuttingDownFlag() {
|
||||
_appShuttingDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
void onResourceDestroyWhileShutdown(string resourceName, string objname = null) {
|
||||
Log.e("Resource leak: destroying resource while shutdown! ", resourceName, " ", objname);
|
||||
}
|
||||
|
|
|
@ -81,13 +81,13 @@ class DrawBuf : RefCountedObject {
|
|||
version (USE_OPENGL) {
|
||||
_id = drawBufIdGenerator++;
|
||||
}
|
||||
debug(resalloc) _instanceCount++;
|
||||
debug _instanceCount++;
|
||||
}
|
||||
|
||||
debug(resalloc) private static int _instanceCount;
|
||||
debug(resalloc) @property static int instanceCount() { return _instanceCount; }
|
||||
debug private static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
~this() {
|
||||
debug(resalloc) _instanceCount--;
|
||||
debug _instanceCount--;
|
||||
clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ private class FontFileItem {
|
|||
|
||||
}
|
||||
|
||||
private class FreeTypeFontFile {
|
||||
class FreeTypeFontFile {
|
||||
private string _filename;
|
||||
private string _faceName;
|
||||
private FT_Library _library;
|
||||
|
@ -112,6 +112,7 @@ private class FreeTypeFontFile {
|
|||
@property bool italic() { return _italic; }
|
||||
|
||||
debug private static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
this(FT_Library library, string filename) {
|
||||
_library = library;
|
||||
_filename = filename;
|
||||
|
@ -119,12 +120,14 @@ private class FreeTypeFontFile {
|
|||
_matrix.yy = 0x10000;
|
||||
_matrix.xy = 0;
|
||||
_matrix.yx = 0;
|
||||
debug(FontResources) Log.d("Created FreeTypeFontFile, count=", ++_instanceCount);
|
||||
debug ++_instanceCount;
|
||||
debug(FontResources) Log.d("Created FreeTypeFontFile, count=", _instanceCount);
|
||||
}
|
||||
|
||||
~this() {
|
||||
clear();
|
||||
debug(FontResources) Log.d("Destroyed FreeTypeFontFile, count=", --_instanceCount);
|
||||
debug --_instanceCount;
|
||||
debug(FontResources) Log.d("Destroyed FreeTypeFontFile, count=", _instanceCount);
|
||||
}
|
||||
|
||||
private static string familyName(FT_Face face)
|
||||
|
@ -329,25 +332,29 @@ private class FreeTypeFontFile {
|
|||
}
|
||||
|
||||
/**
|
||||
* Font implementation based on Win32 API system fonts.
|
||||
* Font implementation based on FreeType.
|
||||
*/
|
||||
class FreeTypeFont : Font {
|
||||
private FontFileItem _fontItem;
|
||||
private Collection!(FreeTypeFontFile, true) _files;
|
||||
|
||||
debug(resalloc) static int _instanceCount;
|
||||
debug static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
|
||||
/// need to call create() after construction to initialize font
|
||||
this(FontFileItem item, int size) {
|
||||
_fontItem = item;
|
||||
_size = size;
|
||||
_height = size;
|
||||
debug(resalloc) Log.d("Created font, count=", ++_instanceCount);
|
||||
debug ++_instanceCount;
|
||||
debug(resalloc) Log.d("Created font, count=", _instanceCount);
|
||||
}
|
||||
|
||||
/// do cleanup
|
||||
~this() {
|
||||
clear();
|
||||
debug(resalloc) Log.d("Destroyed font, count=", --_instanceCount);
|
||||
debug --_instanceCount;
|
||||
debug(resalloc) Log.d("Destroyed font, count=", _instanceCount);
|
||||
}
|
||||
|
||||
private int _size;
|
||||
|
|
|
@ -211,12 +211,16 @@ immutable(ubyte[]) loadResourceBytes(string filename) {
|
|||
}
|
||||
|
||||
class Drawable : RefCountedObject {
|
||||
//private static int _instanceCount;
|
||||
debug static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
|
||||
this() {
|
||||
debug ++_instanceCount;
|
||||
//Log.d("Created drawable, count=", ++_instanceCount);
|
||||
}
|
||||
~this() {
|
||||
//Log.d("Destroyed drawable, count=", --_instanceCount);
|
||||
debug --_instanceCount;
|
||||
}
|
||||
abstract void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0);
|
||||
@property abstract int width();
|
||||
|
@ -329,27 +333,21 @@ class ImageDrawable : Drawable {
|
|||
protected DrawBufRef _image;
|
||||
protected bool _tiled;
|
||||
|
||||
debug(resalloc) private static int _instanceCount;
|
||||
debug static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
|
||||
this(ref DrawBufRef image, bool tiled = false, bool ninePatch = false) {
|
||||
_image = image;
|
||||
_tiled = tiled;
|
||||
if (ninePatch)
|
||||
_image.detectNinePatch();
|
||||
debug(resalloc) {
|
||||
_instanceCount++;
|
||||
Log.d("Created ImageDrawable, count=", _instanceCount);
|
||||
}
|
||||
debug _instanceCount++;
|
||||
debug(resalloc) Log.d("Created ImageDrawable, count=", _instanceCount);
|
||||
}
|
||||
debug(resalloc) {
|
||||
@property static int instanceCount() { return _instanceCount; }
|
||||
}
|
||||
~this() {
|
||||
_image.clear();
|
||||
debug(resalloc) {
|
||||
_instanceCount--;
|
||||
Log.d("Destroyed ImageDrawable, count=", _instanceCount);
|
||||
}
|
||||
debug _instanceCount--;
|
||||
debug(resalloc) Log.d("Destroyed ImageDrawable, count=", _instanceCount);
|
||||
}
|
||||
@property override int width() {
|
||||
if (_image.isNull)
|
||||
|
@ -857,20 +855,23 @@ class DrawableCache {
|
|||
DrawableRef _drawable;
|
||||
DrawableRef[ColorTransform] _transformed;
|
||||
|
||||
debug(resalloc) private static int _instanceCount;
|
||||
debug private static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
this(string id, string filename, bool tiled) {
|
||||
_id = id;
|
||||
_filename = filename;
|
||||
_tiled = tiled;
|
||||
_error = filename is null;
|
||||
debug(resalloc) Log.d("Created DrawableCacheItem, count=", ++_instanceCount);
|
||||
debug ++_instanceCount;
|
||||
debug(resalloc) Log.d("Created DrawableCacheItem, count=", _instanceCount);
|
||||
}
|
||||
~this() {
|
||||
_drawable.clear();
|
||||
foreach(ref t; _transformed)
|
||||
t.clear();
|
||||
_transformed.destroy();
|
||||
debug(resalloc) Log.d("Destroyed DrawableCacheItem, count=", --_instanceCount);
|
||||
debug --_instanceCount;
|
||||
debug(resalloc) Log.d("Destroyed DrawableCacheItem, count=", _instanceCount);
|
||||
}
|
||||
/// remove from memory, will cause reload on next access
|
||||
void compact() {
|
||||
|
|
|
@ -873,6 +873,7 @@ class SDLPlatform : Platform {
|
|||
Log.i("entering message loop");
|
||||
SDL_Event event;
|
||||
bool quit = false;
|
||||
bool skipNextQuit = false;
|
||||
while(!quit) {
|
||||
//redrawWindows();
|
||||
|
||||
|
@ -882,9 +883,12 @@ class SDLPlatform : Platform {
|
|||
//Log.d("Event.type = ", event.type);
|
||||
|
||||
if (event.type == SDL_QUIT) {
|
||||
Log.i("event.type == SDL_QUIT");
|
||||
quit = true;
|
||||
break;
|
||||
if (!skipNextQuit) {
|
||||
Log.i("event.type == SDL_QUIT");
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
skipNextQuit = false;
|
||||
}
|
||||
if (_redrawEventId && event.type == _redrawEventId) {
|
||||
// user defined redraw event
|
||||
|
@ -920,9 +924,13 @@ class SDLPlatform : Platform {
|
|||
w.redraw();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
debug(DebugSDL) Log.d("SDL_WINDOWEVENT_CLOSE win=", event.window.windowID);
|
||||
_windowMap.remove(windowID);
|
||||
destroy(w);
|
||||
if (w.handleCanClose()) {
|
||||
debug(DebugSDL) Log.d("SDL_WINDOWEVENT_CLOSE win=", event.window.windowID);
|
||||
_windowMap.remove(windowID);
|
||||
destroy(w);
|
||||
} else {
|
||||
skipNextQuit = true;
|
||||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
debug(DebugSDL) Log.d("SDL_WINDOWEVENT_SHOWN");
|
||||
|
@ -1344,15 +1352,13 @@ int sdlmain(string[] args) {
|
|||
Platform.setInstance(null);
|
||||
|
||||
//
|
||||
debug(resalloc) {
|
||||
Widget.shuttingDown();
|
||||
}
|
||||
debug setAppShuttingDownFlag();
|
||||
|
||||
currentTheme = null;
|
||||
drawableCache = null;
|
||||
imageCache = null;
|
||||
FontManager.instance = null;
|
||||
debug(resalloc) {
|
||||
debug {
|
||||
if (DrawBuf.instanceCount > 0) {
|
||||
Log.e("Non-zero DrawBuf instance count when exiting: ", DrawBuf.instanceCount);
|
||||
}
|
||||
|
@ -1365,6 +1371,14 @@ int sdlmain(string[] args) {
|
|||
if (ImageDrawable.instanceCount > 0) {
|
||||
Log.e("Non-zero ImageDrawable instance count when exiting: ", ImageDrawable.instanceCount);
|
||||
}
|
||||
version (USE_FREETYPE) {
|
||||
if (FreeTypeFontFile.instanceCount > 0) {
|
||||
Log.e("Non-zero FreeTypeFontFile instance count when exiting: ", FreeTypeFontFile.instanceCount);
|
||||
}
|
||||
if (FreeTypeFont.instanceCount > 0) {
|
||||
Log.e("Non-zero FreeTypeFont instance count when exiting: ", FreeTypeFont.instanceCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d("Exiting main");
|
||||
|
||||
|
|
|
@ -150,6 +150,9 @@ class ComboBoxBase : HorizontalLayout, OnClickHandler {
|
|||
addChild(_body);
|
||||
addChild(_button);
|
||||
}
|
||||
|
||||
~this() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -234,6 +237,13 @@ class ComboBox : ComboBoxBase {
|
|||
return res;
|
||||
}
|
||||
|
||||
~this() {
|
||||
if (_adapter) {
|
||||
destroy(_adapter);
|
||||
_adapter = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Editable ComboBox with list of strings. */
|
||||
|
|
|
@ -699,14 +699,14 @@ class Style {
|
|||
return this;
|
||||
}
|
||||
|
||||
debug(resalloc) private static int _instanceCount;
|
||||
debug(resalloc) @property static int instanceCount() { return _instanceCount; }
|
||||
debug private static __gshared int _instanceCount;
|
||||
debug @property static int instanceCount() { return _instanceCount; }
|
||||
|
||||
this(Theme theme, string id) {
|
||||
_theme = theme;
|
||||
_parentStyle = theme;
|
||||
_id = id;
|
||||
debug(resalloc) _instanceCount++;
|
||||
debug _instanceCount++;
|
||||
//Log.d("Created style ", _id, ", count=", ++_instanceCount);
|
||||
}
|
||||
|
||||
|
@ -725,7 +725,7 @@ class Style {
|
|||
_children.destroy();
|
||||
_backgroundDrawable.clear();
|
||||
_font.clear();
|
||||
debug(resalloc) _instanceCount--;
|
||||
debug _instanceCount--;
|
||||
//Log.d("Destroyed style ", _id, ", parentId=", _parentId, ", state=", _stateMask, ", count=", --_instanceCount);
|
||||
}
|
||||
|
||||
|
|
|
@ -174,9 +174,8 @@ class Widget {
|
|||
return CursorType.Arrow;
|
||||
}
|
||||
|
||||
debug(resalloc) {
|
||||
private static int _instanceCount = 0;
|
||||
private static bool _appShuttingDown = false;
|
||||
debug {
|
||||
private static __gshared int _instanceCount = 0;
|
||||
}
|
||||
/// empty parameter list constructor - for usage by factory
|
||||
this() {
|
||||
|
@ -186,15 +185,15 @@ class Widget {
|
|||
this(string ID) {
|
||||
_id = ID;
|
||||
_state = State.Enabled;
|
||||
debug(resalloc) _instanceCount++;
|
||||
debug _instanceCount++;
|
||||
//Log.d("Created widget, count = ", ++_instanceCount);
|
||||
}
|
||||
|
||||
~this() {
|
||||
debug(resalloc) {
|
||||
//Log.v("destroying widget ", _id);
|
||||
if (_appShuttingDown)
|
||||
Log.e("Destroying widget ", _id, " after app shutdown: probably, resource leak");
|
||||
debug {
|
||||
//Log.v("destroying widget ", _id, " ", this.classinfo.name);
|
||||
if (appShuttingDown)
|
||||
onResourceDestroyWhileShutdown(_id, this.classinfo.name);
|
||||
_instanceCount--;
|
||||
}
|
||||
if (_ownStyle !is null)
|
||||
|
@ -203,13 +202,9 @@ class Widget {
|
|||
//Log.d("Destroyed widget, count = ", --_instanceCount);
|
||||
}
|
||||
|
||||
debug(resalloc) {
|
||||
debug {
|
||||
/// for debug purposes - number of created widget objects, not yet destroyed
|
||||
static @property int instanceCount() { return _instanceCount; }
|
||||
/// for debug purposes - sets shutdown flag to log widgets not destroyed in time.
|
||||
static void shuttingDown() {
|
||||
_appShuttingDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// accessor to style - by lookup in theme by styleId (if style id is not set, theme base style will be used).
|
||||
|
|
Loading…
Reference in New Issue