diff d2/qtd/Debug.d @ 372:a032df77b6ab

Simple debug helper. Unittests. Meta-object for polymorphic non-QObjects
author Max Samukha <maxter@spambox.com>
date Thu, 08 Jul 2010 17:19:05 +0300
parents
children 681af90e1d53
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/d2/qtd/Debug.d	Thu Jul 08 17:19:05 2010 +0300
@@ -0,0 +1,152 @@
+module qtd.Debug;
+
+version (QtdUnittest)
+    debug = UseQtdDebug;
+else debug (QtdDebug)
+    debug = UseQtdDebug;
+    
+debug (UseQtdDebug)
+{
+    import
+        std.string,
+        qtd.QtdObject;
+}
+
+string debugHandler(string handler, string[] args...)
+{
+    debug (UseQtdDebug)
+    {
+        string result = "qtdDebug." ~ handler ~ "(";
+        foreach (i, arg; args)
+        {
+            if (i)
+                result ~= ", ";
+            result ~= arg;
+        }
+        return result ~ ");";
+    }
+    else
+        return "";
+}
+
+debug (UseQtdDebug)
+{
+    debug (QtdVerbose)
+    {
+        import
+            std.stdio,
+            std.string;
+    }
+
+    final shared class QtdDebug
+    {
+        enum MessageType
+        {
+            info,
+            warning,
+            error
+        }
+
+        private
+        {
+            static immutable msgTypeStrs = ["Info", "Warning", "Error"];
+            int wrapperCount_;
+            int nativeDeletedCount_;
+
+            this() {}
+        }
+        
+        string wrapperToString(QtdObject wrapper)
+        {
+            static assert (QtdObjectFlags.sizeof == ubyte.sizeof);
+            auto flags = wrapper.qtdFlags;
+            return format("%s (nativeId: %s, this ptr: %s, flags: %b)", this, wrapper.qtdNativeId
+                , cast(void*)this, *cast(ubyte*)&flags);
+        }
+
+        void onWrapperConstructed(QtdObject wrapper)
+        {
+            info("QtdObject constructed: " ~ wrapperToString(wrapper));
+            wrapperCount_++;
+        }
+
+        void onWrapperDestruction(QtdObject wrapper)
+        {
+            info("Entering QtdObject destructor: " ~ wrapperToString(wrapper));
+        }
+
+        void onWrapperDestroyed(QtdObject wrapper)
+        {
+            info("Leaving QtdObject destructor: " ~ wrapperToString(wrapper));
+            wrapperCount_--;
+        }
+
+        void onNativeDeleted(QtdObject wrapper)
+        {
+            info("Native object deleted: " ~ wrapperToString(wrapper));
+            nativeDeletedCount_++;
+        }
+
+        void onWrapperOwnershipChanged(QtdObject wrapper)
+        {
+            info("Wrapper ownership chaged: " ~ wrapperToString(wrapper));
+        }
+
+        void onDeletingWrapperFromNative(void* dId)
+        {
+            info(format("Wrapper deletion initiated from C++ (wrapper id: %s)", dId));
+        }
+
+        @property int wrapperCount()
+        {
+            return wrapperCount_;
+        }
+
+        @property int nativeDeletedCount()
+        {
+            return nativeDeletedCount_;
+        }
+
+        void reset()
+        {
+            wrapperCount_ = 0;
+            nativeDeletedCount_ = 0;
+        }
+
+        static void info(lazy string msg)
+        {
+            message(msg, MessageType.info);
+        }
+
+        static void warning(lazy string msg)
+        {
+            message(msg, MessageType.warning);
+        }
+
+        static void error(lazy string msg)
+        {
+            message(msg, MessageType.error);
+        }
+
+        static void message(lazy string msg, MessageType msgType = MessageType.info)
+        {
+            // The check is deliberately placed here and not at the call sites.
+            // For simplicity, there are only two levels of debug verbosity:
+            // verbose and silent.
+            debug (QtdVerbose)
+                writefln("[QtD %s] %s",  msgTypeStrs[msgType], msg);
+        }
+    }
+
+    private shared QtdDebug _qtdDebug;
+    static QtdDebug qtdDebug()
+    {
+        return _qtdDebug;
+    }
+
+    shared static this()
+    {
+        _qtdDebug = new QtdDebug;
+    }
+}
+