From: Jean-Philippe Bruyère Date: Mon, 22 Jun 2020 12:49:45 +0000 (+0200) Subject: DbgLogger X-Git-Tag: v0.9.5-beta~113^2~6 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=5f689a331911b6115f298cc56c89b9e188095f46;p=jp%2Fcrow.git DbgLogger --- diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index 2cfa12fd..38082c37 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -32,7 +32,7 @@ full - $(DefineConstants);DEBUG;TRACE;MEASURE_TIME;_DEBUG_DISPOSE;_DEBUG_BINDING;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;DEBUG_DRAGNDROP;_DEBUG_LOG + $(DefineConstants);DEBUG_LOG;DEBUG;TRACE;DEBUG_LAYOUTING;DEBUG_DISPOSE;_DEBUG_BINDING;_DEBUG_CLIP_RECTANGLE true diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs index ca41eec1..2f9aa94a 100644 --- a/Crow/src/IML/Instantiator.cs +++ b/Crow/src/IML/Instantiator.cs @@ -78,9 +78,9 @@ namespace Crow.IML { #endif iface = _iface; sourcePath = srcPath; - #if DEBUG_LOAD - Stopwatch loadingTime = Stopwatch.StartNew (); - #endif +#if DEBUG_LOG + DbgEvent de = DbgLogger.StartEvent (DbgEvtType.CreateITor, sourcePath); +#endif try { using (XmlReader itr = XmlReader.Create (stream)) { parseIML (itr); @@ -89,11 +89,8 @@ namespace Crow.IML { throw new InstantiatorException(sourcePath, ex); } finally { stream?.Dispose (); -#if DEBUG_LOAD - loadingTime.Stop (); - using (StreamWriter sw = new StreamWriter ("loading.log", true)) { - sw.WriteLine ($"ITOR;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}"); - } +#if DEBUG_LOG + DbgLogger.EndEvent (DbgEvtType.CreateITor, de); #endif } } @@ -136,17 +133,7 @@ namespace Crow.IML { /// /// The new graphic object instance public Widget CreateInstance(){ -#if DEBUG_LOAD - Stopwatch loadingTime = Stopwatch.StartNew (); - GraphicObject o = loader (iface) as GraphicObject; - loadingTime.Stop (); - using (StreamWriter sw = new StreamWriter ("loading.log", true)) { - sw.WriteLine ($"NEW ;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}"); - } - return o; -#else return loader (iface) as Widget; -#endif } /// /// Creates a new instance of T compiled in the instantiator @@ -154,17 +141,7 @@ namespace Crow.IML { /// /// The new T instance public T CreateInstance(){ -#if DEBUG_LOAD - Stopwatch loadingTime = Stopwatch.StartNew (); - T i = (T)loader (iface); - loadingTime.Stop (); - using (StreamWriter sw = new StreamWriter ("loading.log", true)) { - sw.WriteLine ($"NEW ;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}"); - } - return i; -#else return (T)loader (iface); -#endif } List dsValueChangedDynMeths = new List(); List cachedDelegates = new List(); diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index 8d4766ff..87e8a1f1 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -685,11 +685,14 @@ namespace Crow lock (ClippingMutex) { if (g.IsQueueForClipping) return; - #if DEBUG_LOG - DbgLogger.AddEvent(DbgEvtType.GOEnqueueForRepaint, g); - #endif +#if DEBUG_LOG + DbgLogger.StartEvent (DbgEvtType.GOEnqueueForRepaint, g); +#endif ClippingQueue.Enqueue (g); g.IsQueueForClipping = true; +#if DEBUG_LOG + DbgLogger.EndEvent (DbgEvtType.GOEnqueueForRepaint); +#endif } } /// Main Update loop, executed in this interface thread, protected by the UpdateMutex @@ -723,7 +726,7 @@ namespace Crow return; #if DEBUG_LOG - DbgLogger.StartEvent (DbgEvtType.IFaceUpdate); + DbgLogger.StartEvent (DbgEvtType.Update); #endif processLayouting (); @@ -737,7 +740,7 @@ namespace Crow processDrawing (ctx); #if DEBUG_LOG - DbgLogger.EndEvent (DbgEvtType.IFaceUpdate, true); + DbgLogger.EndEvent (DbgEvtType.Update, true); #endif Monitor.Exit (UpdateMutex); @@ -748,7 +751,7 @@ namespace Crow protected virtual void processLayouting(){ if (Monitor.TryEnter (LayoutMutex)) { #if DEBUG_LOG - DbgLogger.StartEvent (DbgEvtType.IFaceLayouting); + DbgLogger.StartEvent (DbgEvtType.Layouting); #endif DiscardQueue = new Queue (); //Debug.WriteLine ("======= Layouting queue start ======="); @@ -759,7 +762,7 @@ namespace Crow } LayoutingQueue = DiscardQueue; #if DEBUG_LOG - DbgLogger.EndEvent (DbgEvtType.IFaceLayouting, true); + DbgLogger.EndEvent (DbgEvtType.Layouting, true); #endif Monitor.Exit (LayoutMutex); DiscardQueue = null; @@ -770,7 +773,7 @@ namespace Crow /// operation to known if it should go down in the tree for further graphic updates and repaints void clippingRegistration(){ #if DEBUG_LOG - DbgLogger.StartEvent (DbgEvtType.IFaceClipping); + DbgLogger.StartEvent (DbgEvtType.Clipping); #endif Widget g = null; while (ClippingQueue.Count > 0) { @@ -781,14 +784,14 @@ namespace Crow g.ClippingRegistration (); } #if DEBUG_LOG - DbgLogger.EndEvent (DbgEvtType.IFaceClipping, true); + DbgLogger.EndEvent (DbgEvtType.Clipping, true); #endif } /// 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 void processDrawing(Context ctx){ #if DEBUG_LOG - DbgLogger.StartEvent (DbgEvtType.IFaceDrawing); + DbgLogger.StartEvent (DbgEvtType.Drawing); #endif if (DragImage != null) clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight)); @@ -852,7 +855,7 @@ namespace Crow } #if DEBUG_LOG - DbgLogger.EndEvent (DbgEvtType.IFaceDrawing, true); + DbgLogger.EndEvent (DbgEvtType.Drawing, true); #endif } #endregion @@ -922,12 +925,6 @@ namespace Crow g.Dispose (); } } - #if DEBUG_LAYOUTING - LQIsTries = new List(); - curLQIsTries = new LQIList(); - LQIs = new List(); - curLQIs = new LQIList(); - #endif } /// Put widget on top of other root widgets public void PutOnTop(Widget g, bool isOverlay = false) @@ -1436,20 +1433,6 @@ namespace Crow } public Rectangle getSlot () { return ClientRectangle; } #endregion - - -#if DEBUG_LAYOUTING - public List LQIsTries = new List(); - public LQIList curLQIsTries = new LQIList(); - public List LQIs = new List(); - public LQIList curLQIs = new LQIList(); - // public static LayoutingQueueItem[] MultipleRunsLQIs { - // get { return curUpdateLQIs.Where(l=>l.LayoutingTries>2 || l.DiscardCount > 0).ToArray(); } - // } - public LayoutingQueueItem currentLQI; -#else - public List LQIs = null;//still create the var for CrowIDE -#endif } } diff --git a/Crow/src/LayoutingQueueItem.cs b/Crow/src/LayoutingQueueItem.cs index f1568db3..4fc22d1a 100644 --- a/Crow/src/LayoutingQueueItem.cs +++ b/Crow/src/LayoutingQueueItem.cs @@ -35,7 +35,7 @@ namespace Crow /// Unsuccessfull UpdateLayout and requeueing count public int LayoutingTries, DiscardCount; - #if DEBUG_LOG + public enum Result : byte { Unknown, Register, @@ -44,6 +44,7 @@ namespace Crow Discarded, Deleted, } +#if DEBUG_LOG public Result result; public Widget graphicObject { get { return Layoutable as Widget; } @@ -101,7 +102,7 @@ namespace Crow return; } #if DEBUG_LOG - DbgLogger.DbgEvent dbgEvt = DbgLogger.StartEvent (DbgEvtType.GOProcessLayouting, this); + DbgLogger.StartEvent (DbgEvtType.GOProcessLayouting, this); #endif LayoutingTries++; if (!Layoutable.UpdateLayout (LayoutType)) { @@ -130,7 +131,9 @@ namespace Crow else{ result = Result.Success; } - DbgLogger.EndEvent (DbgEvtType.GOProcessLayouting).data = this; + Slot = graphicObject.LastSlots; + NewSlot = graphicObject.Slot; + (DbgLogger.EndEvent (DbgEvtType.GOProcessLayouting) as DbgLayoutEvent).SetLQI (this); #endif go.parentRWLock.ExitReadLock (); } @@ -144,22 +147,7 @@ namespace Crow return lqi.LayoutType; } public override string ToString () - { - #if DEBUG_LAYOUTING - return string.Format ("{2};{3} {1}->{0}", LayoutType,Layoutable.ToString(), - LayoutingTries,DiscardCount); - #else - return string.Format ("{2};{3} {1}->{0}", LayoutType,Layoutable.ToString(), - LayoutingTries, DiscardCount); - #endif - } - } - public class LQIList : List{ -// #if DEBUG_LAYOUTING -// public List GetRootLQIs(){ -// return this.Where (lqi => lqi.wasTriggeredBy == null).ToList (); -// } -// #endif + => $"{LayoutType};{Layoutable.ToString ()};{LayoutingTries};{DiscardCount}"; } } diff --git a/Crow/src/Widgets/GenericStack.cs b/Crow/src/Widgets/GenericStack.cs index 2fd86466..de33aa2a 100644 --- a/Crow/src/Widgets/GenericStack.cs +++ b/Crow/src/Widgets/GenericStack.cs @@ -117,9 +117,6 @@ namespace Crow { if (newW != stretchedGO.Slot.Width) { stretchedGO.Slot.Width = newW; stretchedGO.IsDirty = true; -#if DEBUG_LAYOUTING - LOG ($"width: {stretchedGO.ToString()}"); -#endif stretchedGO.LayoutChanged -= OnChildLayoutChanges; stretchedGO.OnLayoutChanges (LayoutingType.Width); stretchedGO.LayoutChanged += OnChildLayoutChanges; @@ -134,9 +131,6 @@ namespace Crow { if (newH != stretchedGO.Slot.Height) { stretchedGO.Slot.Height = newH; stretchedGO.IsDirty = true; -#if DEBUG_LAYOUTING - LOG ($"height: {stretchedGO.ToString ()}"); -#endif stretchedGO.LayoutChanged -= OnChildLayoutChanges; stretchedGO.OnLayoutChanges (LayoutingType.Height); stretchedGO.LayoutChanged += OnChildLayoutChanges; diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs index 6731d7be..419479b5 100644 --- a/Crow/src/Widgets/Group.cs +++ b/Crow/src/Widgets/Group.cs @@ -67,9 +67,9 @@ namespace Crow set { _multiSelect = value; } } public virtual void AddChild(Widget g){ -#if DEBUG +#if DEBUG_LOG if (disposed) { - System.Diagnostics.Debug.WriteLine ($"AddChild ({g}) in disposed Widget: {this}\n{System.Environment.StackTrace}"); + DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed | DbgEvtType.GOAddChild); return; } #endif @@ -116,9 +116,9 @@ namespace Crow child.Dispose (); } public virtual void InsertChild (int idx, Widget g) { -#if DEBUG +#if DEBUG_LOG if (disposed) { - System.Diagnostics.Debug.WriteLine ($"InsertChild ({idx},{g}) in disposed Widget: {this}\n{System.Environment.StackTrace}"); + DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed | DbgEvtType.GOAddChild); return; } #endif @@ -344,10 +344,6 @@ namespace Crow { Widget g = sender as Widget; -#if DEBUG_LAYOUTING - LOG ($"{arg.LayoutType}:{g}->{g.Slot}"); -#endif - switch (arg.LayoutType) { case LayoutingType.Width: if (Width != Measure.Fit) @@ -381,9 +377,9 @@ namespace Crow } void searchLargestChild (bool forceMeasure = false) { - #if DEBUG_LAYOUTING - LOG (this.ToString()); - #endif +#if DEBUG_LOG + DbgLogger.StartEvent (DbgEvtType.GOSearchLargestChild, this); +#endif largestChild = null; contentSize.Width = 0; for (int i = 0; i < Children.Count; i++) { @@ -401,12 +397,15 @@ namespace Crow largestChild = Children [i]; } } +#if DEBUG_LOG + DbgLogger.EndEvent (DbgEvtType.GOSearchLargestChild); +#endif } void searchTallestChild (bool forceMeasure = false) { - #if DEBUG_LAYOUTING - LOG (this.ToString()); - #endif +#if DEBUG_LOG + DbgLogger.StartEvent (DbgEvtType.GOSearchTallestChild, this); +#endif tallestChild = null; contentSize.Height = 0; for (int i = 0; i < Children.Count; i++) { @@ -424,6 +423,9 @@ namespace Crow tallestChild = Children [i]; } } +#if DEBUG_LOG + DbgLogger.EndEvent (DbgEvtType.GOSearchTallestChild); +#endif } diff --git a/Crow/src/Widgets/MenuItem.cs b/Crow/src/Widgets/MenuItem.cs index be7d4b33..eb49147e 100644 --- a/Crow/src/Widgets/MenuItem.cs +++ b/Crow/src/Widgets/MenuItem.cs @@ -146,9 +146,6 @@ namespace Crow } public override void onMouseClick (object sender, MouseButtonEventArgs e) { -#if DEBUG_FOCUS - System.Diagnostics.Debug.WriteLine ("MENU CLICK => " + this.ToString ()); -#endif if (command != null) { command.Execute (); closeMenu (); diff --git a/Crow/src/Widgets/PrivateContainer.cs b/Crow/src/Widgets/PrivateContainer.cs index bd49c1b4..4972ab96 100644 --- a/Crow/src/Widgets/PrivateContainer.cs +++ b/Crow/src/Widgets/PrivateContainer.cs @@ -159,9 +159,6 @@ namespace Crow public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { Widget g = sender as Widget; -#if DEBUG_LAYOUTING - LOG ($"{arg.LayoutType}:{g}->{child.Slot}"); -#endif if (arg.LayoutType == LayoutingType.Width) { contentSize.Width = g.Slot.Width; if (Width != Measure.Fit) diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index ca693cde..0ca6e92a 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -32,6 +32,7 @@ namespace Crow //0 is the main graphic tree, for other obj tree not added to main tree, it range from 1->n //useful to track events for obj shown later, not on start, or never added to main tree public int treeIndex; + public int instanceIndex;//index in the GraphicObjects list public int yIndex;//absolute index in the graphic tree for debug draw public int xLevel;//x increment for debug draw #endif @@ -146,18 +147,16 @@ namespace Crow } protected virtual void Dispose(bool disposing){ if (disposed){ - #if DEBUG_DISPOSE - Debug.WriteLine ("Trying to dispose already disposed obj: {0}", this.ToString()); - #endif +#if DEBUG_LOG + DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed, this); +#endif return; } +#if DEBUG_LOG + DbgLogger.StartEvent (DbgEvtType.Disposing, this); +#endif if (disposing) { - #if DEBUG_DISPOSE - System.Diagnostics.Debug.WriteLine ("Disposing: {0}", this.ToString()); - //if () - //throw new Exception("Trying to dispose an object queued for Redraw: " + this.ToString()); - #endif unshownPostActions (); @@ -167,15 +166,21 @@ namespace Crow parentRWLock.EnterWriteLock(); parent = null; parentRWLock.ExitWriteLock(); - } else - Debug.WriteLine ("!!! Finalized by GC: {0}", this.ToString ()); + } +#if DEBUG_LOG + else + DbgLogger.AddEvent (DbgEvtType.DisposedByGC, this); +#endif Clipping?.Dispose (); bmp?.Dispose (); disposed = true; - } +#if DEBUG_LOG + DbgLogger.EndEvent (DbgEvtType.Disposing); +#endif + } #endregion - #if DEBUG_LOG +#if DEBUG_LOG internal static List GraphicObjects = new List(); #endif @@ -226,10 +231,11 @@ namespace Crow /// protected Widget () { Clipping = new Region (); - #if DEBUG_LOG +#if DEBUG_LOG + instanceIndex = GraphicObjects.Count; GraphicObjects.Add (this); DbgLogger.AddEvent(DbgEvtType.GOClassCreation, this); - #endif +#endif } /// /// This constructor **must** be used when creating widget from code. @@ -1420,9 +1426,9 @@ namespace Crow [MethodImpl(MethodImplOptions.AggressiveInlining)] public void RegisterForGraphicUpdate () { -#if DEBUG +#if DEBUG_LOG if (disposed) { -// System.Diagnostics.Debug.WriteLine ($"RegisterForGraphicUpdate for disposed Widget: {this}\n{System.Environment.StackTrace}"); + DbgLogger.AddEvent (DbgEvtType.GORegisterForGraphicUpdate | DbgEvtType.AlreadyDisposed, this); return; } #endif @@ -1438,7 +1444,7 @@ namespace Crow { #if DEBUG if (disposed) { - System.Diagnostics.Debug.WriteLine ($"RegisterForRedraw for disposed Widget: {this}\n{System.Environment.StackTrace}"); + DbgLogger.AddEvent (DbgEvtType.GORegisterForRedraw | DbgEvtType.AlreadyDisposed, this); return; } #endif @@ -1913,9 +1919,6 @@ namespace Crow } public virtual void onMouseDown(object sender, MouseButtonEventArgs e){ -#if DEBUG_FOCUS - Debug.WriteLine("MOUSE DOWN => " + this.ToString()); -#endif if (Focusable) { IFace.FocusedWidget = this; e.Handled = true; @@ -1932,9 +1935,6 @@ namespace Crow FocusParent?.onMouseDown (sender, e); } public virtual void onMouseUp(object sender, MouseButtonEventArgs e){ -#if DEBUG_FOCUS - Debug.WriteLine("MOUSE UP => " + this.ToString()); -#endif if (IFace.DragAndDropOperation != null){ if (IFace.DragAndDropOperation.DragSource == this) { @@ -1951,18 +1951,12 @@ namespace Crow FocusParent?.onMouseUp (sender, e); } public virtual void onMouseClick(object sender, MouseButtonEventArgs e){ -#if DEBUG_FOCUS - Debug.WriteLine("CLICK => " + this.ToString()); -#endif if (MouseClick != null) MouseClick.Invoke (this, e); else if (!e.Handled) FocusParent?.onMouseClick (sender, e); } public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){ -#if DEBUG_FOCUS - Debug.WriteLine("DOUBLE CLICK => " + this.ToString()); -#endif if (MouseDoubleClick != null) MouseDoubleClick.Invoke (this, e); else if (!e.Handled) @@ -1976,10 +1970,6 @@ namespace Crow } public virtual void onMouseEnter(object sender, MouseMoveEventArgs e) { - #if DEBUG_FOCUS - Debug.WriteLine("MouseEnter => " + this.ToString()); - #endif - IFace.MouseCursor = MouseCursor; if (IFace.DragAndDropOperation != null) { @@ -2001,10 +1991,6 @@ namespace Crow } public virtual void onMouseLeave(object sender, MouseMoveEventArgs e) { - #if DEBUG_FOCUS - Debug.WriteLine("MouseLeave => " + this.ToString()); - #endif - MouseLeave.Raise (this, e); } @@ -2030,17 +2016,23 @@ namespace Crow Disabled.Raise (this, e); } protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) { +#if DEBUG_LOG + DbgLogger.AddEvent (DbgEvtType.GONewParent, this, e); +#endif ParentChanged.Raise (this, e); if (logicalParent == null) LogicalParentChanged.Raise (this, e); } protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) { +#if DEBUG_LOG + DbgLogger.AddEvent (DbgEvtType.GONewLogicalParent, this, e); +#endif LogicalParentChanged.Raise (this, e); } internal void ClearTemplateBinding(){ - #if DEBUG_UPDATE +#if DEBUG_UPDATE Debug.WriteLine (string.Format("ClearTemplateBinding: {0}", this.ToString())); - #endif +#endif if (ValueChanged == null) return; EventInfo eiEvt = this.GetType().GetEvent ("ValueChanged"); diff --git a/Crow/src/Widgets/Wrapper.cs b/Crow/src/Widgets/Wrapper.cs index 13443fae..6d792d25 100644 --- a/Crow/src/Widgets/Wrapper.cs +++ b/Crow/src/Widgets/Wrapper.cs @@ -192,9 +192,6 @@ namespace Crow } public override void OnLayoutChanges (LayoutingType layoutType) { -#if DEBUG_LAYOUTING - LOG ($"{layoutType}: {LastSlots}->{Slot}"); -#endif switch (layoutType) { case LayoutingType.Width: foreach (Widget c in Children) { diff --git a/Crow/src/debug/DbgEventTypeColors.cs b/Crow/src/debug/DbgEventTypeColors.cs index c05ffbbc..3be2c209 100644 --- a/Crow/src/debug/DbgEventTypeColors.cs +++ b/Crow/src/debug/DbgEventTypeColors.cs @@ -1,35 +1,13 @@ -// -// DbgEventTypeColors.cs +// Copyright (c) 2013-2020 Jean-Philippe Bruyère // -// Author: -// Jean-Philippe Bruyère -// -// 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. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + using System; using Crow.Cairo; using System.Linq; namespace Crow { - #if DEBUG_LOG public class DbgEventTypeColors : Widget { protected override void onDraw (Context gr) @@ -72,6 +50,5 @@ namespace Crow } } } - #endif } diff --git a/Crow/src/debug/DbgLogViewer.cs b/Crow/src/debug/DbgLogViewer.cs index 1a0d5db2..57bd8e30 100644 --- a/Crow/src/debug/DbgLogViewer.cs +++ b/Crow/src/debug/DbgLogViewer.cs @@ -9,7 +9,6 @@ using System.Linq; using System.Threading.Tasks; using Crow.Cairo; -#if DEBUG_LOG namespace Crow { public class DbgLogViewer : ScrollingObject @@ -18,182 +17,6 @@ namespace Crow public static Configuration colorsConf = new Configuration ("dbgcolor.conf");//, Interface.GetStreamFromPath("#Crow.dbgcolor.conf")); - #region debug viewer private classes - public class DbgLayoutEvent : DbgWidgetEvent - { - public LayoutingType layouting; - public LayoutingQueueItem.Result result; - public override Color Color { - get { - if (type == DbgEvtType.GORegisterLayouting) - return Colors.GreenYellow; - if (type == DbgEvtType.GOProcessLayoutingWithNoParent) - return Colors.DarkRed; - switch (result) { - case LayoutingQueueItem.Result.Success: - return Colors.Green; - case LayoutingQueueItem.Result.Deleted: - return Colors.Red; - case LayoutingQueueItem.Result.Discarded: - return Colors.OrangeRed; - default: - return Colors.Orange; - } - } - } - } - public class DbgWidgetEvent : DbgEvent - { - public int widgetInstanceId; - public override Color Color { - get { - switch (type) { - case DbgEvtType.GOClassCreation: - return Colors.DarkSlateGrey; - case DbgEvtType.GOInitialization: - return Colors.DarkOliveGreen; - case DbgEvtType.GOClippingRegistration: - return Colors.MediumTurquoise; - case DbgEvtType.GORegisterClip: - return Colors.Turquoise; - case DbgEvtType.GORegisterForGraphicUpdate: - return Colors.LightPink; - case DbgEvtType.GOEnqueueForRepaint: - return Colors.LightSalmon; - case DbgEvtType.GONewDataSource: - return Colors.MediumVioletRed; - case DbgEvtType.GODraw: - return Colors.SteelBlue; - case DbgEvtType.GORecreateCache: - return Colors.CornflowerBlue; - case DbgEvtType.GOUpdateCache: - return Colors.SteelBlue; - case DbgEvtType.GOPaint: - return Colors.RoyalBlue; - case DbgEvtType.GOLockUpdate: - return Colors.SaddleBrown; - case DbgEvtType.GOLockClipping: - return Colors.Sienna; - case DbgEvtType.GOLockRender: - return Colors.BurlyWood; - case DbgEvtType.GOLockLayouting: - return Colors.GoldenRod; - case DbgEvtType.TGCancelLoadingThread: - return Colors.Maroon; - default: - return Colors.Crimson; - } - if (type.HasFlag (DbgEvtType.GOLock)) - return Colors.DarkMagenta; - return Colors.White; - } - } - } - public class DbgEvent { - public long begin, end; - public int threadId; - public DbgEvtType type; - public DbgEvent parentEvent; - public List events; - public bool HasChildEvents => events != null && events.Count > 0; - public long Duration => end - begin; - - public virtual Color Color { - get { - switch (type) { - case DbgEvtType.IFaceLayouting: - return Colors.Yellow; - case DbgEvtType.IFaceClipping: - return Colors.DarkTurquoise; - case DbgEvtType.IFaceDrawing: - return Colors.MidnightBlue; - case DbgEvtType.IFaceUpdate: - return Colors.Grey; - case DbgEvtType.IFaceLoad: - return Colors.Teal; - default: - return Colors.White; - } - - } - } - - public void AddEvent (DbgEvent evt) - { - if (events == null) - events = new List () { evt }; - else - events.Add (evt); - evt.parentEvent = this; - } - - public DbgEvent() {} - - public static DbgEvent Parse (string str) { - if (str == null) - return null; - string[] tmp = str.Trim().Split(';'); - - DbgEvtType evtType = (DbgEvtType)Enum.Parse (typeof (DbgEvtType), tmp [3]); - - if (evtType.HasFlag (DbgEvtType.GraphicObject)) { - if (evtType.HasFlag (DbgEvtType.GOLayouting)) - return new DbgLayoutEvent () { - begin = long.Parse (tmp [0]), - end = long.Parse (tmp [1]), - threadId = int.Parse (tmp [2]), - type = evtType, - widgetInstanceId = int.Parse (tmp [4]), - layouting = (LayoutingType)Enum.Parse (typeof (LayoutingType), tmp [5]), - result = evtType == DbgEvtType.GOProcessLayouting ? - (LayoutingQueueItem.Result)Enum.Parse (typeof (LayoutingQueueItem.Result), tmp [6]) - : LayoutingQueueItem.Result.Unknown - }; - return new DbgWidgetEvent () { - begin = long.Parse (tmp [0]), - end = long.Parse (tmp [1]), - threadId = int.Parse (tmp [2]), - type = evtType, - widgetInstanceId = int.Parse (tmp [4]), - }; - } - return new DbgEvent () { - begin = long.Parse (tmp [0]), - end = long.Parse (tmp [1]), - threadId = int.Parse (tmp [2]), - type = evtType, - }; - } - public override string ToString () - => $"{begin}:{end}:{type}"; - } - public class DbgGo { - public int listIndex;//prevent doing an IndexOf on list for each event to know y pos on screen - public int instanceNum;//class instantiation order, used to bind events to objs - public string name; - //0 is the main graphic tree, for other obj tree not added to main tree, it range from 1->n - //useful to track events for obj shown later, not on start - public int treeIndex; - public int yIndex;//index in parenting, the whole main graphic tree is one continuous suite - public int xLevel;//depth - - public List events = new List();//flattened event list of this widget - - public static DbgGo Parse (string str) { - DbgGo g = new DbgGo (); - if (str == null) - return null; - string[] tmp = str.Trim().Split(';'); - g.instanceNum = int.Parse (tmp [0]); - g.name = tmp [1]; - g.yIndex = int.Parse (tmp [2]); - g.xLevel = int.Parse (tmp [3]); - return g; - } - - } - #endregion - public static void reloadColors () { colors = new Dictionary(); foreach (string n in colorsConf.Names) { @@ -215,14 +38,14 @@ namespace Crow double xScale = 1.0/512.0, yScale = 1.0, leftMargin, topMargin = 0.0; string logFile; - DbgGo curWidget; + DbgWidgetRecord curWidget; DbgEvent curEvent; List events; - List objs; + List objs; public List Events => events; - public List Widgets => objs; + public List Widgets => objs; long currentTick = 0, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0, visibleTicks = 0; @@ -302,7 +125,7 @@ namespace Crow } } - public DbgGo CurrentWidget { + public DbgWidgetRecord CurrentWidget { get => curWidget; internal set { if (curWidget == value) @@ -316,7 +139,15 @@ namespace Crow internal set { if (curEvent == value) return; + + if (curEvent != null) + curEvent.IsSelected = false; curEvent = value; + if (curEvent != null) { + curEvent.IsSelected = true; + curEvent.IsExpanded = true; + } + NotifyValueChanged (nameof (CurrentEvent), curEvent); } } @@ -334,9 +165,9 @@ namespace Crow if (evt.begin - minTicks > ScrollX + visibleTicks) break; double penY = topMargin + ClientRectangle.Top; - if (evt.type.HasFlag (DbgEvtType.GraphicObject)) { + if (evt.type.HasFlag (DbgEvtType.Widget)) { DbgWidgetEvent eW = evt as DbgWidgetEvent; - int lIdx = eW.widgetInstanceId - ScrollY; + int lIdx = eW.InstanceIndex - ScrollY; if (lIdx < 0 || lIdx > visibleLines) continue; penY += (lIdx) * fe.Height; @@ -380,7 +211,7 @@ namespace Crow ctx.ShowText (s); } - drawEvents (ctx, evt.events); + drawEvents (ctx, evt.Events); } } @@ -405,7 +236,8 @@ namespace Crow for (int i = 0; i < visibleLines; i++) { if (i + ScrollY >= objs.Count) break; - DbgGo g = objs [i + ScrollY]; + int gIdx = i + ScrollY; + DbgWidgetRecord g = objs [gIdx]; penY += fe.Height; @@ -422,7 +254,7 @@ namespace Crow Foreground.SetAsSource (gr); gr.MoveTo (penX, penY - gr.FontExtents.Descent); - gr.ShowText (g.name + g.instanceNum); + gr.ShowText (g.name + gIdx); gr.SetSource (Crow.Colors.White); gr.MoveTo (cb.X, penY - gr.FontExtents.Descent); @@ -589,6 +421,8 @@ namespace Crow base.onMouseDown (sender, e); if (e.Button == Glfw.MouseButton.Left) { + CurrentWidget = (currentLine < 0 || currentLine >= objs.Count) ? null : objs [currentLine]; + CurrentEvent = curWidget?.Events.FirstOrDefault (ev => ev.begin <= currentTick && ev.end >= currentTick); selStart = currentTick; selEnd = -1; } @@ -651,7 +485,7 @@ namespace Crow return; events = new List (); - objs = new List (); + objs = new List (); minTicks = maxTicks = 0; leftMargin = topMargin = 0.0; @@ -668,7 +502,7 @@ namespace Crow string l = s.ReadLine (); if (l == "[Events]") break; - DbgGo o = DbgGo.Parse (l); + DbgWidgetRecord o = DbgWidgetRecord.Parse (l); objs.Add (o); double nameWidth = gr.TextExtents (o.name).Width + 5.0 * o.xLevel; if (nameWidth > maxNameWidth) @@ -706,8 +540,8 @@ namespace Crow } } startedEvents.Push (evt); - if (evt.type.HasFlag(DbgEvtType.GraphicObject)) - objs [(evt as DbgWidgetEvent).widgetInstanceId].events.Add (evt); + if (evt.type.HasFlag(DbgEvtType.Widget)) + objs [(evt as DbgWidgetEvent).InstanceIndex].Events.Add (evt); } if (events.Count > 0) minTicks = events [0].begin; @@ -777,8 +611,6 @@ namespace Crow mousePos.Y = Math.Min (cb.Bottom, mousePos.Y); currentTick = (int)((double)(mousePos.X - cb.X) / xScale) + minTicks + ScrollX; - CurrentWidget = (currentLine < 0 || currentLine >= objs.Count) ? null : objs [currentLine]; - CurrentEvent = curWidget?.events.FirstOrDefault (e => e.begin <= currentTick && e.end >= currentTick); } void zoom (long start, long end) { //Rectangle cb = ClientRectangle; @@ -788,5 +620,5 @@ namespace Crow } } } -#endif + diff --git a/Crow/src/debug/DebugLogger.cs b/Crow/src/debug/DebugLogger.cs index 61ca14af..1c188737 100644 --- a/Crow/src/debug/DebugLogger.cs +++ b/Crow/src/debug/DebugLogger.cs @@ -10,133 +10,110 @@ using System.IO; using System.Linq; using System.Threading; -#if DEBUG_LOG + namespace Crow { - /*public class LayoutingEvent : DbgEvent { - public List lqis = new List(); - - }*/ [Flags] public enum DbgEvtType { ////9 nth bit set for iface event IFace = 0x10000, - IFaceFocus = 0x20000, - GraphicObject = 0x00100, - GOLayouting = 0x00200, - Drawing = 0x00400, - GOLock = 0x00800, - IFaceLayouting = IFace | 0x01, - IFaceClipping = IFace | 0x02, - IFaceDrawing = IFace | 0x03, - IFaceUpdate = IFace | 0x04, + Focus = 0x20000, + Override = 0x40000, + Widget = 0x00100, + //GOLayouting = 0x00200, + //Drawing = 0x00400, + Lock = 0x00800, + Layouting = IFace | 0x01000, + Clipping = IFace | 0x02000, + Drawing = IFace | 0x04000, + Update = IFace | 0x08000, IFaceLoad = IFace | 0x05, IFaceInit = IFace | 0x06, + CreateITor = IFace | 0x07, - HoverWidget = IFaceFocus | 0x01, - FocusedWidget = IFaceFocus | 0x02, - ActiveWidget = IFaceFocus | 0x03, + HoverWidget = Focus | 0x01, + FocusedWidget = Focus | 0x02, + ActiveWidget = Focus | 0x03, //10 nth bit set for graphic obj - Warning = 0x4000, - Error = 0x8000, - GOClassCreation = GraphicObject | 0x01, - GOInitialization = GraphicObject | 0x02, - GOClippingRegistration = GraphicObject | 0x03, - GORegisterClip = GraphicObject | 0x04, - GORegisterForGraphicUpdate = GraphicObject | 0x05, - GOEnqueueForRepaint = GraphicObject | 0x06, - GONewDataSource = GraphicObject | 0x07, TemplatedGroup = 0x1000, - GORegisterLayouting = GraphicObject | GOLayouting | 0x01, - GOProcessLayouting = GraphicObject | GOLayouting | 0x02, - GOProcessLayoutingWithNoParent = Warning | GraphicObject | GOLayouting | 0x01, - GODraw = GraphicObject | Drawing | 0x01, - GORecreateCache = GraphicObject | Drawing | 0x02, - GOUpdateCache = GraphicObject | Drawing | 0x03, - GOPaint = GraphicObject | Drawing | 0x04, - - GOLockUpdate = GraphicObject | GOLock | 0x01, - GOLockClipping = GraphicObject | GOLock | 0x02, - GOLockRender = GraphicObject | GOLock | 0x03, - GOLockLayouting = GraphicObject | GOLock | 0x04, - - TGLoadingThread = GraphicObject | TemplatedGroup | 0x01, - TGCancelLoadingThread = GraphicObject | TemplatedGroup | 0x02, + Dispose = 0x2000, + Warning = 0x4000, + Error = 0x8000, + GOClassCreation = Widget | 0x01, + GOInitialization = Widget | 0x02, + GORegisterForGraphicUpdate = Widget | 0x03, + GOEnqueueForRepaint = Widget | 0x04, + GONewDataSource = Widget | 0x05, + GONewParent = Widget | 0x06, + GONewLogicalParent = Widget | 0x07, + GOAddChild = Widget | 0x08, + + GOSearchLargestChild = Widget | 0x09, + GOSearchTallestChild = Widget | 0x10, + GORegisterForRedraw = Widget | 0x11, + + AlreadyDisposed = Dispose | Widget | Error | 0x01, + DisposedByGC = Dispose | Widget | Error | 0x02, + Disposing = Dispose | Widget | 0x01, + + GOClippingRegistration = Clipping | Widget | 0x01, + GORegisterClip = Clipping | Widget | 0x02, + GORegisterLayouting = Layouting | Widget | 0x01, + GOProcessLayouting = Layouting | Widget | 0x02, + GOProcessLayoutingWithNoParent = Layouting | Widget | Warning | 0x01, + GODraw = Drawing | Widget | 0x01, + GORecreateCache = Drawing | Widget | 0x02, + GOUpdateCache = Drawing | Widget | 0x03, + GOPaint = Drawing | Widget | 0x04, + + GOLockUpdate = Widget | Lock | 0x01, + GOLockClipping = Widget | Lock | 0x02, + GOLockRender = Widget | Lock | 0x03, + GOLockLayouting = Widget | Lock | 0x04, + + TGLoadingThread = Widget | TemplatedGroup | 0x01, + TGCancelLoadingThread = Widget | TemplatedGroup | 0x02, All = 0x0FFFFFFF } - - - +#if DEBUG_LOG public static class DbgLogger { public static DbgEvtType IncludeEvents = DbgEvtType.All; - public static DbgEvtType DiscardEvents = DbgEvtType.IFaceFocus; + public static DbgEvtType DiscardEvents = DbgEvtType.Focus; static bool logevt (DbgEvtType evtType) - { - return (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) != 0; - } + => (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) != 0; - /// - /// debug events as recorded, another class is used in the viewer - /// - public class DbgEvent - { - public long begin, end; - public DbgEvtType type; - public object data = null; - public int threadId; - public List Events = new List (); - - public DbgEvent () { } - - public DbgEvent (long timeStamp, DbgEvtType evt, object _data = null) - { - data = _data; - type = evt; - begin = timeStamp; - end = timeStamp; - threadId = Thread.CurrentThread.ManagedThreadId; - } - public override string ToString () - { - string tmp = $"{begin};{end};{threadId};{type}"; - if (type.HasFlag (DbgEvtType.GraphicObject)) { - if (type.HasFlag (DbgEvtType.GOLayouting)) { - LayoutingQueueItem lqi = (LayoutingQueueItem)data; - tmp += $";{Widget.GraphicObjects.IndexOf (lqi.graphicObject).ToString ()};{lqi.LayoutType}"; - if (type == DbgEvtType.GOProcessLayouting) - tmp += $";{lqi.result}"; - } else - tmp += $";{Widget.GraphicObjects.IndexOf (data as Widget).ToString ()}"; + static object logMutex = new object (); + static Stopwatch chrono = Stopwatch.StartNew (); + static List events = new List (); + //started events per thread + static Dictionary> startedEvents = new Dictionary> (); + //helper for fetching current event list to add next event to while recording + static List curEventList { + get { + if (startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId)) { + if (startedEvents [Thread.CurrentThread.ManagedThreadId].Count == 0) + return events; + DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Peek (); + if (e.Events == null) + e.Events = new List (); + return e.Events; } - return tmp; + return events; } } - public static Stopwatch chrono = Stopwatch.StartNew(); - - static List events = new List(); - static Dictionary> startedEvents = new Dictionary> (); - - static object logMutex = new object (); - - - static List curEventList => - startedEvents.ContainsKey(Thread.CurrentThread.ManagedThreadId) ? - startedEvents[Thread.CurrentThread.ManagedThreadId].Count == 0 ? events : startedEvents[Thread.CurrentThread.ManagedThreadId].Peek ().Events : events; - - public static DbgEvent StartEvent (DbgEvtType evtType, object data = null) + public static DbgEvent StartEvent (DbgEvtType evtType, params object[] data) { if (!logevt (evtType)) return null; lock (logMutex) { chrono.Stop (); - DbgEvent evt = new DbgEvent (chrono.ElapsedTicks, evtType, data); - curEventList.Add (evt); + DbgEvent evt = addEventInternal (evtType, data); if (!startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId)) startedEvents [Thread.CurrentThread.ManagedThreadId] = new Stack (); startedEvents [Thread.CurrentThread.ManagedThreadId].Push (evt); @@ -156,7 +133,7 @@ namespace Crow DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Pop (); if (e.type != evtType) throw new Exception ($"Begin/end event logging mismatch: {e.type}/{evtType}"); - if (discardIfNoChildEvents && e.Events.Count == 0) + if (discardIfNoChildEvents && (e.Events == null || e.Events.Count == 0)) curEventList.Remove (e); else e.end = chrono.ElapsedTicks; @@ -164,40 +141,76 @@ namespace Crow return e; } } - public static DbgEvent AddEvent (DbgEvtType evtType, object data = null) { + /// + /// End event by reference to cancel unended events on failure + /// + public static DbgEvent EndEvent (DbgEvtType evtType, DbgEvent evt) + { if (!logevt (evtType)) return null; lock (logMutex) { chrono.Stop (); - DbgEvent evt = new DbgEvent (chrono.ElapsedTicks, evtType, data); - curEventList.Add (evt); + if (!startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId)) + throw new Exception ("Current thread has no event started"); + DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Pop (); + while (e != evt) + e = startedEvents [Thread.CurrentThread.ManagedThreadId].Pop (); + e.end = chrono.ElapsedTicks; + chrono.Start (); + return e; + } + } + + public static DbgEvent AddEvent (DbgEvtType evtType, params object [] data) { + if (!logevt (evtType)) + return null; + + lock (logMutex) { + chrono.Stop (); + DbgEvent evt = addEventInternal (evtType, data); chrono.Start (); return evt; } } - static int y, level; + static DbgEvent addEventInternal (DbgEvtType evtType, params object [] data) + { + DbgEvent evt = null; + if (data == null || data.Length == 0) + evt = new DbgEvent (chrono.ElapsedTicks, evtType); + else if (data [0] is Widget w) + evt = new DbgWidgetEvent (chrono.ElapsedTicks, evtType, w); + else if (data [0] is LayoutingQueueItem lqi) + evt = new DbgLayoutEvent (chrono.ElapsedTicks, evtType, lqi); + else + evt = new DbgEvent (chrono.ElapsedTicks, evtType); + + curEventList.Add (evt); + return evt; + } - static void parseTree (Widget go) { + static void parseTree (Widget go, int level = 0, int y = 1) { if (go == null) return; - go.yIndex = y++; - go.xLevel = level++; + go.yIndex = y; + go.xLevel = level; Group gr = go as Group; if (gr != null) { - foreach (Widget g in gr.Children) { - parseTree (g); - } + foreach (Widget g in gr.Children) + parseTree (g, level + 1, y + 1); + } else { PrivateContainer pc = go as PrivateContainer; if (pc != null) - parseTree (pc.getTemplateRoot); + parseTree (pc.getTemplateRoot, level + 1, y + 1); } - level--; } + /// + /// Clear all recorded events from logger. + /// public static void Reset () { lock (logMutex) { @@ -206,21 +219,23 @@ namespace Crow chrono.Restart (); } } - public static void save(Interface iface) { + /// + /// Save recorded events to disk + /// + /// Iface. + public static void save(Interface iface, string dbgLogFilePath = "debug.log") { lock (logMutex) { - y = 1; - level = 0; foreach (Widget go in iface.GraphicTree) parseTree (go); - using (StreamWriter s = new StreamWriter ("debug.log")) { + using (StreamWriter s = new StreamWriter (dbgLogFilePath)) { s.WriteLine ("[GraphicObjects]"); lock (Widget.GraphicObjects) { - Widget.GraphicObjects = Widget.GraphicObjects.OrderBy (o => o.yIndex).ToList (); + //Widget.GraphicObjects = Widget.GraphicObjects.OrderBy (o => o.yIndex).ToList (); for (int i = 0; i < Widget.GraphicObjects.Count; i++) { Widget g = Widget.GraphicObjects [i]; - s.WriteLine ("{0};{1};{2};{3}", i, g.GetType ().Name, g.yIndex, g.xLevel); + s.WriteLine ($"{g.GetType ().Name};{g.yIndex};{g.xLevel}"); } } s.WriteLine ("[Events]"); @@ -229,17 +244,19 @@ namespace Crow } } - static void saveEventList (StreamWriter s, List events, int level = 0) + static void saveEventList (StreamWriter s, List evts, int level = 0) { - foreach (DbgEvent e in events) { + foreach (DbgEvent e in evts) { if (e == null) continue; - s.WriteLine (new string ('\t', level) + e.ToString ()); - saveEventList (s, e.Events, level + 1); + s.WriteLine (new string ('\t', level) + e); + if (e.Events != null) + saveEventList (s, e.Events, level + 1); } } } -} #endif +} + diff --git a/Samples/common/ui/Interfaces/Divers/dbglog.crow b/Samples/common/ui/Interfaces/Divers/dbglog.crow index 02147b62..16f6c35e 100644 --- a/Samples/common/ui/Interfaces/Divers/dbglog.crow +++ b/Samples/common/ui/Interfaces/Divers/dbglog.crow @@ -1,8 +1,8 @@  - - - + + + + + + + + + + + +