]> O.S.I.I.S - jp/crow.git/commitdiff
Debug Events
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 19 Mar 2018 00:52:07 +0000 (01:52 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 19 Mar 2018 00:52:07 +0000 (01:52 +0100)
Crow.csproj
CrowIDE/CrowIDE.csproj
CrowIDE/src/DesignInterface.cs
Tests/InterfaceControler.cs
src/DebugEvents/DebugEvent.cs [new file with mode: 0644]
src/Interface.cs
src/LayoutingQueueItem.cs

index 466e5b0adc3c99c626656387fe8027ca4e382d41..0d8d85dbae44c79c7b9fede01a8c698333ad2c8c 100644 (file)
@@ -32,7 +32,7 @@
     <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
     <Optimize>false</Optimize>
     <OutputPath>$(SolutionDir)build\Debug</OutputPath>
-    <DefineConstants>DESIGN_MODE;DEBUG_LAYOUTING;DEBUG_UPDATE0;DEBUG_FOCUS0;DEBUG_DISPOSE0;TRACE0;DEBUG;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0</DefineConstants>
+    <DefineConstants>DESIGN_MODE;DBG_EVENTS;DEBUG_LAYOUTING0;DEBUG_UPDATE0;DEBUG_FOCUS0;DEBUG_DISPOSE0;TRACE0;DEBUG;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <Optimize>true</Optimize>
     <Compile Include="src\ParsingException.cs" />
     <Compile Include="src\IMLAttributes.cs" />
     <Compile Include="src\GraphicObjects\DockStack.cs" />
+    <Compile Include="src\DebugEvents\DebugEvent.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
     <Folder Include="src\rsvg\" />
     <Folder Include="src\IML\" />
     <Folder Include="Icons\" />
+    <Folder Include="src\DebugEvents\" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Images\Icons\updown.svg" />
index 1cae7289c95a09b3ad0899e9c7a0ef6902841203..c1c92cde345af787c1cc5dbb50c87d091d4a54ba 100644 (file)
@@ -24,7 +24,7 @@
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <DefineConstants>DEBUG;</DefineConstants>
+    <DefineConstants>DEBUG;DBG_EVENTS</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <ConsolePause>false</ConsolePause>
index 04666b110a7487c904b4c0bf32f269d9ce8a6f07..9ac9e9a5ab1c259c863f7bd623053d5edc793f56 100644 (file)
@@ -158,8 +158,8 @@ namespace Crow.Coding
        
                protected override void processLayouting ()
                {
-                       #if MEASURE_TIME
-                       layoutingMeasure.StartCycle();
+                       #if DBG_EVENTS
+                       DbgStartSubEvt(DbgEvtType.IFaceLayouting);
                        #endif
 
                        if (Monitor.TryEnter (LayoutMutex)) {
@@ -167,20 +167,21 @@ namespace Crow.Coding
                                LayoutingQueueItem lqi;
                                while (LayoutingQueue.Count > 0) {
                                        lqi = LayoutingQueue.Dequeue ();
-                                       //Console.WriteLine (lqi.ToString ());
-                                       #if DEBUG_LAYOUTING
-                                       currentLQI = lqi;
-                                       curLQIsTries.Add(currentLQI);
+                                       #if DBG_EVENTS
+                                       DbgStartSubEvt (new LayoutingDebugEvent(lqi.LayoutType,lqi.Layoutable as GraphicObject));
                                        #endif
                                        lqi.ProcessLayouting ();
+                                       #if DBG_EVENTS
+                                       DbgEndSubEvt();
+                                       #endif
                                }
                                LayoutingQueue = DiscardQueue;
                                Monitor.Exit (LayoutMutex);
                                DiscardQueue = null;
                        }
 
-                       #if MEASURE_TIME
-                       layoutingMeasure.StopCycle();
+                       #if DBG_EVENTS
+                       DbgEndSubEvt();
                        #endif
                }
        }
index 034cab39334911ef337ac2a523f1204cda0d6f0c..f3f9cc9dcc0970fbe6598ca40d9d60a519f69f18 100644 (file)
@@ -148,24 +148,12 @@ namespace Crow
                        );
                        #endif
 
-                       Thread t = new Thread (interfaceThread);
-                       t.IsBackground = true;
-                       t.Start ();
+                       CrowInterface.StartThread ();
 
                        initGL ();
                }
                #endregion
 
-               void interfaceThread()
-               {
-                       while (CrowInterface.ClientRectangle.Size.Width == 0)
-                               Thread.Sleep (5);
-
-                       while (true) {
-                               CrowInterface.Update ();
-                               Thread.Sleep (2);
-                       }
-               }
 
                #region Mouse And Keyboard handling
                public virtual void ProcessResize(Rectangle newSize){
diff --git a/src/DebugEvents/DebugEvent.cs b/src/DebugEvents/DebugEvent.cs
new file mode 100644 (file)
index 0000000..68ae40e
--- /dev/null
@@ -0,0 +1,125 @@
+//
+// DebugEvent.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Crow
+{
+       #if DBG_EVENTS
+       public enum DbgEvtType {
+               Clipping                = 8,
+               Interface               = 0x10,
+               IfaceStart              = 0x11,
+               IFaceUpdate             = 0x12,
+               IFaceClipping   = 0x13,
+               IFaceDrawing    = 0x14,
+               Drawnig                 = 0x20,
+               OnDraw                  = 0x21,
+               Paint                   = 0x22,
+               UpdateCache             = 0x23,
+               RecreateCache   = 0x24,
+               IFaceLayouting  = 0x80,
+               UpdateLayout    = 0x81,
+               RegisterLayouting= 0x82,
+       }
+
+       public class DebugEvent
+       {
+               public DebugEvent (DbgEvtType type, string message = "")
+               {
+                       EventType = type;
+                       ThreadId = Thread.CurrentThread.ManagedThreadId;
+               }
+
+               public int ThreadId;
+               public DbgEvtType EventType;
+               public Stopwatch Time;
+               public string Message;
+
+               public DebugEvent Parent;
+               public List<DebugEvent> ChildEvents = new List<DebugEvent>();
+
+               public virtual void Start () {
+                       Time = Stopwatch.StartNew();
+               }
+               public virtual void Finished () {
+                       Time.Stop();
+               }
+       }
+       public class WidgetDebugEvent : DebugEvent {            
+               public GraphicObject Target;
+               public LayoutingType RegisteredLayoutings;
+               public LayoutingType RequestedLayoutings;
+               public Rectangle Slot;
+               public Measure Width;
+               public Measure Height;
+
+               public WidgetDebugEvent (DbgEvtType type, GraphicObject go, string message = "") : base(type, message)
+               {
+                       Target = go;
+                       saveTargetState ();
+               }
+               protected virtual void saveTargetState () {
+                       RegisteredLayoutings = Target.registeredLayoutings;
+                       RequestedLayoutings = Target.requestedLayoutings;
+                       Width = Target.Width;
+                       Height = Target.Height;
+                       Slot = Target.Slot;
+               }
+               public override void Finished ()
+               {                       
+                       base.Finished ();
+                       saveTargetState ();
+               }
+       }
+       public class LayoutingDebugEvent : WidgetDebugEvent
+       {
+               public enum Result {
+                       Ok,
+                       Requeued,
+                       Discarded,
+                       Deleted,
+               }
+               public LayoutingDebugEvent (LayoutingType layoutingType, GraphicObject go) : base(DbgEvtType.IFaceLayouting, go)
+               {
+                       LayoutingType = layoutingType;
+                       Target = go;
+               }       
+               public LayoutingType LayoutingType;
+               public Rectangle PreviousSlot;
+               public Result EndResult;
+               public override void Finished ()
+               {
+                       base.Finished ();
+                       saveTargetState ();
+                       PreviousSlot = Target.LastSlots;
+               }
+       }
+       #endif
+}
+
index 7902424d00b6c9b56801377c676e741a02fd9c2b..4fc7e669185db513cee62e6efea45c409ef8737f 100644 (file)
@@ -65,6 +65,40 @@ namespace Crow
        /// </remarks>
        public class Interface : ILayoutable
        {
+               #if DBG_EVENTS
+               const int MAX_THREAD = 20;
+
+               public DebugEvent[] PerThreadCurDbgEvt = new DebugEvent[MAX_THREAD];
+               public DebugEvent CurDbgEvt {
+                       get { return PerThreadCurDbgEvt [Thread.CurrentThread.ManagedThreadId]; }
+                       set { PerThreadCurDbgEvt [Thread.CurrentThread.ManagedThreadId] = value; }
+               }
+               public void DbgLogEvent (DebugEvent de) {                       
+                       if (CurDbgEvt == null)
+                               CurDbgEvt = new DebugEvent(DbgEvtType.IfaceStart) ;                     
+                       de.Parent = CurDbgEvt;
+                       if (CurDbgEvt != null)                          
+                               CurDbgEvt.ChildEvents.Add(de);
+               }
+               public DebugEvent DbgStartSubEvt (DbgEvtType dbgType){
+                       DebugEvent de = new DebugEvent(dbgType); 
+                       DbgStartSubEvt(de);
+                       return de;
+               }
+               public void DbgStartSubEvt (DebugEvent de){
+                       if (CurDbgEvt == null)
+                               CurDbgEvt = new DebugEvent(DbgEvtType.IfaceStart) ;
+                       de.Parent = CurDbgEvt;
+                       CurDbgEvt.ChildEvents.Add(de);
+                       CurDbgEvt = de;
+                       CurDbgEvt.Start ();
+               }
+               public void DbgEndSubEvt () {
+                       CurDbgEvt.Finished ();
+                       CurDbgEvt = CurDbgEvt.Parent;
+               }
+               #endif
+
                #region CTOR
                static Interface(){
                        if (Type.GetType ("Mono.Runtime") == null) {
@@ -99,6 +133,25 @@ namespace Crow
                }
                #endregion
 
+               public void StartThread () {
+                       Thread t = new Thread (interfaceThread);
+                       t.IsBackground = true;
+                       t.Start ();
+               }
+               void interfaceThread()
+               {
+                       #if DBG_EVENTS
+                       CurDbgEvt = new DebugEvent(DbgEvtType.IfaceStart);
+                       #endif
+
+                       while (ClientRectangle.Size.Width == 0)
+                               Thread.Sleep (5);
+
+                       while (true) {
+                               Update ();
+                               Thread.Sleep (2);
+                       }
+               }
                public void Init () {
                        CurrentInterface = this;
                        loadCursors ();
@@ -134,7 +187,7 @@ namespace Crow
                public const int MaxCacheSize = 2048;
                /// <summary> Above this count, the layouting is discard from the current
                /// update cycle and requeued for the next</summary>
-               public const int MaxLayoutingTries = 30;
+               public const int MaxLayoutingTries = 20;
                /// <summary> Above this count, the layouting is discard for the widget and it
                /// will not be rendered on screen </summary>
                public const int MaxDiscardCount = 3;
@@ -535,6 +588,10 @@ namespace Crow
                /// Result: the Interface bitmap is drawn in memory (byte[] bmp) and a dirtyRect and bitmap are available
                /// </summary>
                public void Update(){
+                       #if DBG_EVENTS
+                       DbgStartSubEvt(DbgEvtType.IFaceUpdate);
+                       #endif
+
                        if (armedClickSender != null && clickTimer.ElapsedMilliseconds >= Interface.DoubleClick) {
                                armedClickSender.onMouseClick (armedClickSender, armedClickEvtArgs);                            
                                armedClickSender = null;
@@ -562,30 +619,17 @@ namespace Crow
                        if (!Monitor.TryEnter (UpdateMutex))
                                return;
 
-                       #if MEASURE_TIME
-                       updateMeasure.StartCycle();
-                       #endif
-
                        processLayouting ();
 
-                       #if DEBUG_LAYOUTING
-                       if (curLQIsTries.Count > 0){
-                               LQIsTries.Add(curLQIsTries);
-                               curLQIsTries = new LQIList();
-                               LQIs.Add(curLQIs);
-                               curLQIs = new LQIList();
-                       }
-                       #endif
-
                        clippingRegistration ();
 
                        processDrawing ();
 
-                       #if MEASURE_TIME
-                       updateMeasure.StopCycle();
-                       #endif
-
                        Monitor.Exit (UpdateMutex);
+
+                       #if DBG_EVENTS
+                       DbgEndSubEvt ();
+                       #endif
                }
                #if DEBUG_LAYOUTING
                public string BreakingName;
@@ -594,39 +638,38 @@ namespace Crow
                /// Layouting queue items. Failing LQI's are requeued in this cycle until MaxTry is reached which
                /// trigger an enqueue for the next Update Cycle</summary>
                protected virtual void processLayouting(){
-                       #if MEASURE_TIME
-                       layoutingMeasure.StartCycle();
+                       #if DBG_EVENTS
+                       DbgStartSubEvt(DbgEvtType.IFaceLayouting);
                        #endif
 
                        if (Monitor.TryEnter (LayoutMutex)) {
                                DiscardQueue = new Queue<LayoutingQueueItem> ();
-                               //Debug.WriteLine ("======= Layouting queue start =======");
                                LayoutingQueueItem lqi;
                                while (LayoutingQueue.Count > 0) {
                                        lqi = LayoutingQueue.Dequeue ();
-                                       #if DEBUG_LAYOUTING
-                                       currentLQI = lqi;
-                                       curLQIsTries.Add(currentLQI);
-                                       if (lqi.graphicObject.Name == BreakingName)
-                                               Debugger.Break();
+                                       #if DBG_EVENTS
+                                       DbgStartSubEvt (new LayoutingDebugEvent(lqi.LayoutType,lqi.Layoutable as GraphicObject));
                                        #endif
                                        lqi.ProcessLayouting ();
+                                       #if DBG_EVENTS
+                                       DbgEndSubEvt();
+                                       #endif
                                }
                                LayoutingQueue = DiscardQueue;
                                Monitor.Exit (LayoutMutex);
                                DiscardQueue = null;
                        }
 
-                       #if MEASURE_TIME
-                       layoutingMeasure.StopCycle();
+                       #if DBG_EVENTS
+                       DbgEndSubEvt();
                        #endif
                }
                /// <summary>Degueue Widget to clip from DrawingQueue and register the last painted slot and the new one
                /// Clipping rectangles are added at each level of the tree from leef to root, that's the way for the painting
                /// operation to known if it should go down in the tree for further graphic updates and repaints</summary>
                void clippingRegistration(){
-                       #if MEASURE_TIME
-                       clippingMeasure.StartCycle();
+                       #if DBG_EVENTS
+                       DbgStartSubEvt(DbgEvtType.IFaceClipping);
                        #endif
                        GraphicObject g = null;
                        while (ClippingQueue.Count > 0) {
@@ -637,15 +680,15 @@ namespace Crow
                                g.ClippingRegistration ();
                        }
 
-                       #if MEASURE_TIME
-                       clippingMeasure.StopCycle();
+                       #if DBG_EVENTS
+                       DbgEndSubEvt();
                        #endif
                }
                /// <summary>Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be
                /// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place</summary>
                void processDrawing(){
-                       #if MEASURE_TIME
-                       drawingMeasure.StartCycle();
+                       #if DBG_EVENTS
+                       DbgStartSubEvt(DbgEvtType.IFaceDrawing);
                        #endif
                        if (DragImage != null)
                                clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight));
@@ -725,8 +768,8 @@ namespace Crow
                                        //surf.WriteToPng (@"/mnt/data/test.png");
                                }
                        }
-                       #if MEASURE_TIME
-                       drawingMeasure.StopCycle();
+                       #if DBG_EVENTS
+                       DbgEndSubEvt ();
                        #endif
                }
                #endregion
index cf72aeb9b5daacce96cf37b42c05bf2b51612f09..ab9fe3793826029abce763534c98d125d51e5f9d 100644 (file)
@@ -57,26 +57,6 @@ namespace Crow
                /// <summary> Unsuccessfull UpdateLayout and requeueing count </summary>
                public int LayoutingTries, DiscardCount;
 
-               #if DEBUG_LAYOUTING
-               public Stopwatch LQITime;
-               public GraphicObject graphicObject {
-                       get { return Layoutable as GraphicObject; }
-               }
-               public string Name {
-                       get { return graphicObject.Name; }
-               }
-               public string FullName {
-                       get { return graphicObject.ToString(); }
-               }
-               public Measure Width {
-                       get { return graphicObject.Width; }
-               }
-               public Measure Height {
-                       get { return graphicObject.Height; }
-               }
-               public Rectangle Slot, NewSlot;
-               #endif
-
                #region CTOR
                public LayoutingQueueItem (LayoutingType _layoutType, ILayoutable _graphicObject)
                {                       
@@ -85,16 +65,9 @@ namespace Crow
                        Layoutable.RegisteredLayoutings |= LayoutType;
                        LayoutingTries = 0;
                        DiscardCount = 0;
-                       #if DEBUG_LAYOUTING
-                       LQITime = new Stopwatch();
-                       Slot = Rectangle.Empty;
-                       NewSlot = Rectangle.Empty;
-                       Debug.WriteLine ("\tRegister => " + this.ToString ());
-                       #endif
                }
                #endregion
 
-
                public void ProcessLayouting()
                {
                        GraphicObject go = Layoutable as GraphicObject;
@@ -104,30 +77,27 @@ namespace Crow
                        if (go.Parent == null) {//TODO:improve this
                                go.registeredLayoutings &= (~LayoutType);
                                go.requestedLayoutings |= LayoutType;
-                               //cancel layouting for object without parent, maybe some were in queue when
-                               //removed from a listbox
-                               #if DEBUG_UPDATE || DEBUG_LAYOUTING
-                               Debug.WriteLine ("ERROR: processLayouting, no parent for: " + this.ToString ());
-                               #endif
                                go.parentRWLock.ExitReadLock ();
+                               #if DBG_EVENTS
+                               (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Deleted;
+                               go.IFace.CurDbgEvt.Message = "Parent is null";
+                               #endif
                                return;
                        }
 
-                       #if DEBUG_LAYOUTING
-                       LQITime.Start();
-                       Debug.WriteLine ("=> " + this.ToString ());
-                       #endif
                        LayoutingTries++;
                        if (!Layoutable.UpdateLayout (LayoutType)) {
-                               #if DEBUG_LAYOUTING
-                               Debug.WriteLine ("\t\tRequeued");
-                               #endif
                                if (LayoutingTries < Interface.MaxLayoutingTries) {
                                        Layoutable.RegisteredLayoutings |= LayoutType;
+
+                                       #if DBG_EVENTS
+                                       (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Requeued;
+                                       #endif
+
                                        (Layoutable as GraphicObject).IFace.LayoutingQueue.Enqueue (this);
                                } else if (DiscardCount < Interface.MaxDiscardCount) {
-                                       #if DEBUG_LAYOUTING
-                                       Debug.WriteLine ("\t\tDiscarded");
+                                       #if DBG_EVENTS
+                                       (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Discarded;
                                        #endif
                                        go.LayoutingDiscardCheck (LayoutType);
                                        LayoutingTries = 0;
@@ -135,19 +105,16 @@ namespace Crow
                                        Layoutable.RegisteredLayoutings |= LayoutType;
                                        (Layoutable as GraphicObject).IFace.DiscardQueue.Enqueue (this);
                                }
-                               //#if DEBUG_LAYOUTING
+                               #if DBG_EVENTS
                                else
-                                       Debug.WriteLine ("\tDELETED    => " + this.ToString ());
-                               //#endif
-                       }
-
-                       else{
-                               if (LayoutingTries > 2 || DiscardCount > 0)
-                                       Debug.WriteLine (this.ToString ());
+                               (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Deleted;
+                               #endif
                        }
-                       #if DEBUG_LAYOUTING
-                       LQITime.Stop();
+                       #if DBG_EVENTS
+                       else
+                               (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Ok;
                        #endif
+
                        go.parentRWLock.ExitReadLock ();
                }