aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/debug
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-11-24 10:48:34 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-11-24 10:48:34 +0100
commit98eada369aa50115e677a1b337662fee9f0ca011 (patch)
tree6855bc602c4da5f6a13c90276452b438172c1d3d /src/debug
parent4db409fdff013e3e4249d567e4d6fdb0ee877256 (diff)
debug log viewer, X backends
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/DbgLogViewer.cs327
-rw-r--r--src/debug/DebugLogger.cs113
2 files changed, 387 insertions, 53 deletions
diff --git a/src/debug/DbgLogViewer.cs b/src/debug/DbgLogViewer.cs
new file mode 100644
index 00000000..b020df4b
--- /dev/null
+++ b/src/debug/DbgLogViewer.cs
@@ -0,0 +1,327 @@
+//
+// DbgLogViewer.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.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+#if DEBUG_LOG
+namespace Crow
+{
+ public class DbgLogViewer : ScrollingObject
+ {
+ #region CTOR
+ protected DbgLogViewer () : base(){}
+ public DbgLogViewer (Interface iface) : base(iface){}
+ #endregion
+
+ bool loaded = false;
+ double xScale = 0.125, yScale = 1.0, lineHeight = 0.0, leftMargin;
+ string logFile;
+ long currentTick = 0, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0;
+
+ public string LogFile {
+ get { return logFile; }
+ set {
+ if (logFile == value)
+ return;
+ logFile = value;
+ NotifyValueChanged ("LogFile", logFile);
+ loaded = false;
+ RegisterForGraphicUpdate ();
+ }
+ }
+ public double XScale {
+ get { return xScale; }
+ set {
+ if (xScale == value)
+ return;
+ xScale = value;
+ NotifyValueChanged ("XScale", xScale);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ public double YScale {
+ get { return yScale; }
+ set {
+ if (yScale == value)
+ return;
+ yScale = value;
+ NotifyValueChanged ("YScale", yScale);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ List<DbgEvent> events;
+ List<DbgGo> objs;
+
+ protected override void onDraw (Cairo.Context gr)
+ {
+ base.onDraw (gr);
+
+ if (!loaded) {
+ if (!File.Exists (logFile))
+ return;
+ events = new List<DbgEvent>();
+ objs = new List<DbgGo> ();
+
+ using (StreamReader s = new StreamReader (logFile)) {
+ if (s.ReadLine () != "[GraphicObjects]") {
+ loaded = false;
+ return;
+ }
+ while (!s.EndOfStream) {
+ string l = s.ReadLine ();
+ if (l == "[Events]")
+ break;
+ objs.Add (DbgGo.Parse (l));
+ }
+ while (!s.EndOfStream)
+ events.Add (DbgEvent.Parse (s.ReadLine ()));
+ }
+ loaded = true;
+ lineHeight = gr.FontExtents.Height;
+ if (events.Count > 0) {
+ minTicks = events [0].begin;
+ maxTicks = events [events.Count - 1].begin;
+ } else
+ minTicks = maxTicks = 0;
+ MaxScrollY = Math.Max(0, objs.Count - (int)Math.Ceiling((double)ClientRectangle.Height / lineHeight));
+ }
+
+ Rectangle r = ClientRectangle;
+
+ Foreground.SetAsSource (gr);
+
+ leftMargin = 0.0;
+
+ foreach (DbgGo g in objs) {
+ if (g.yIndex == 0)
+ continue;
+ double penX = r.X + g.xLevel * 5.0, penY = (g.yIndex - ScrollY) * lineHeight - gr.FontExtents.Descent;
+ gr.MoveTo (penX, penY);
+ Cairo.TextExtents te = gr.TextExtents (g.name);
+ if (te.Width + penX > leftMargin)
+ leftMargin = te.Width + penX;
+ gr.ShowText (g.name);
+ }
+
+ leftMargin += 2.5;
+ r.Left += (int)leftMargin;
+ gr.LineWidth = 1.0;
+ gr.MoveTo (leftMargin, r.Top);
+ gr.LineTo (leftMargin, r.Bottom);
+ gr.Stroke ();
+
+ MaxScrollX = (int)(maxTicks - minTicks) - r.Width;
+
+ foreach (DbgEvent evt in events) {
+ double x = (int)((double)(evt.begin - minTicks - ScrollX) * xScale) ;
+ x += (double)r.Left + 0.5;
+ double w = Math.Max (Math.Max(4.0, 10.0 * xScale), (double)(evt.end - evt.begin) * xScale);
+
+ if (x < r.Left || x > r.Right)
+ continue;
+
+ if (evt.type.HasFlag (DbgEvtType.GraphicObject)) {
+ gr.SetSourceColor (Crow.Color.DarkSlateBlue);
+ DbgData data = (DbgData)evt.data;
+ double y = (objs.Where(o=>o.index == data.obj).FirstOrDefault().yIndex - ScrollY - 1) * lineHeight;
+ if (evt.type.HasFlag (DbgEvtType.GOLayouting)) {
+ if (evt.type == DbgEvtType.GOProcessLayouting) {
+ switch (data.result) {
+ case LayoutingQueueItem.Result.Success:
+ gr.SetSourceColor (Crow.Color.Green);
+ break;
+ case LayoutingQueueItem.Result.Deleted:
+ gr.SetSourceColor (Crow.Color.Red);
+ break;
+ case LayoutingQueueItem.Result.Discarded:
+ gr.SetSourceColor (Crow.Color.DarkOrange);
+ break;
+ case LayoutingQueueItem.Result.Requeued:
+ gr.SetSourceColor (Crow.Color.GreenYellow);
+ break;
+ case LayoutingQueueItem.Result.Register:
+ gr.SetSourceColor (Crow.Color.Blue);
+ break;
+ }
+ }else
+ gr.SetSourceColor (Crow.Color.Bisque);
+ }else if (evt.type == DbgEvtType.GOInitialization)
+ gr.SetSourceColor (Crow.Color.Cyan);
+
+ gr.Rectangle (x, y, w, lineHeight);
+ gr.Fill ();
+ } else {
+ gr.SetSourceColor (Crow.Color.Black);
+ gr.MoveTo (x, r.Top);
+ gr.LineTo (x, r.Bottom);
+ gr.Stroke ();
+ string s = evt.type.ToString () [10].ToString ();
+ Cairo.TextExtents te = gr.TextExtents (s);
+ gr.Rectangle (x, r.Top, te.Width, lineHeight);
+ gr.Fill ();
+ gr.MoveTo (x, r.Top + gr.FontExtents.Ascent);
+ gr.SetSourceColor (Crow.Color.White);
+ gr.ShowText (s);
+ }
+ }
+
+ }
+ public override void Paint (ref Cairo.Context ctx)
+ {
+ base.Paint (ref ctx);
+ Rectangle r = new Rectangle(mousePos.X, 0, 1, Slot.Height);
+ Rectangle cb = ContextCoordinates (r);
+
+ ctx.Rectangle (cb);
+ ctx.SetSourceColor (Color.CornflowerBlue);
+ ctx.Fill();
+
+ ctx.MoveTo (cb.X, cb.Y + lineHeight);
+ ctx.ShowText (currentTick.ToString ());
+
+ if (selStart < 0)
+ return;
+ double selStartX = (double)(selStart - ScrollX - minTicks) * xScale + leftMargin;
+ double selEndX = (selEnd >= 0) ? (double)(selEnd - ScrollX - minTicks) * xScale + leftMargin :
+ (double)(currentTick - ScrollX - minTicks) * xScale + leftMargin;
+
+ if (selStartX < selEndX) {
+ cb.X = (int)selStartX;
+ cb.Width = (int)(selEndX - selStartX);
+ } else {
+ cb.X = (int)selEndX;
+ cb.Width = (int)(selStartX - selEndX);
+ }
+ ctx.Operator = Cairo.Operator.Multiply;
+ cb.Width = Math.Max (1, cb.Width);
+ ctx.Rectangle (cb);
+ ctx.SetSourceColor (Color.LightYellow);
+ ctx.Fill();
+ ctx.Operator = Cairo.Operator.Over;
+
+ }
+ public override void OnLayoutChanges (LayoutingType layoutType)
+ {
+ base.OnLayoutChanges (layoutType);
+ switch (layoutType) {
+ case LayoutingType.Width:
+ RegisterForLayouting (LayoutingType.X);
+ break;
+ case LayoutingType.Height:
+ if (!loaded)
+ break;
+ MaxScrollY = objs.Count - (int)Math.Ceiling((double)ClientRectangle.Height / lineHeight);
+ break;
+ }
+ }
+ Point mousePos;
+ void updateMouseLocalPos(Point mPos){
+ Rectangle r = ScreenCoordinates (Slot);
+ Rectangle cb = ClientRectangle;
+ cb.Left += (int)leftMargin;
+ mousePos = mPos - r.Position;
+
+ mousePos.X = Math.Max(cb.X, mousePos.X);
+ mousePos.X = Math.Min(cb.Right, mousePos.X);
+ mousePos.Y = Math.Max(cb.Y, mousePos.Y);
+ mousePos.Y = Math.Min(cb.Bottom, mousePos.Y);
+
+ currentTick = (int)((double)Math.Max(0, mousePos.X - cb.X) / xScale) + minTicks + ScrollX;
+ }
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseMove (sender, e);
+ updateMouseLocalPos (e.Position);
+
+ if (selStart >= 0 && IFace.Mouse.IsButtonDown(MouseButton.Left))
+ selEnd = currentTick;
+
+ RegisterForRedraw ();
+ }
+ public override void onMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseDown (sender, e);
+
+ selStart = currentTick;
+ selEnd = -1;
+
+ RegisterForRedraw ();
+ }
+ public override void onMouseUp (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseUp (sender, e);
+ if (selStart == currentTick) {
+ selStart = -1;
+ selEnd = -1;
+ }else
+ selEnd = currentTick;
+ RegisterForRedraw ();
+ }
+
+ /// <summary> Process scrolling vertically, or if shift is down, vertically </summary>
+ public override void onMouseWheel (object sender, MouseWheelEventArgs e)
+ {
+ //base.onMouseWheel (sender, e);
+
+ if (IFace.Keyboard.Shift)
+ ScrollX -= (int)((double)(e.Delta * MouseWheelSpeed) / xScale);
+ else if (IFace.Keyboard.Ctrl) {
+ if (e.Delta > 0) {
+ XScale *= 2.0;
+ } else {
+ XScale *= 0.5;
+ }
+ int cbx = ClientRectangle.X + (int)leftMargin;
+ ScrollX = (int)(currentTick - (int)((double)Math.Max(0, mousePos.X - cbx) / xScale) - minTicks);
+ }else
+ ScrollY -= e.Delta * MouseWheelSpeed;
+ }
+
+ public override void onKeyDown (object sender, KeyEventArgs e)
+ {
+ base.onKeyDown (sender, e);
+
+ if (e.Key == Key.F3) {
+ if (selEnd < 0)
+ return;
+ if (selEnd < selStart)
+ zoom (selEnd, selStart);
+ else
+ zoom (selStart, selEnd);
+ selEnd = selStart = -1;
+ }
+ }
+
+ void zoom (long start, long end) {
+ ScrollX = (int)(start - minTicks);
+ XScale = (ClientRectangle.Width - leftMargin)/(end - start);
+ }
+ }
+}
+#endif
+
diff --git a/src/debug/DebugLogger.cs b/src/debug/DebugLogger.cs
index 0599a6a1..161d742c 100644
--- a/src/debug/DebugLogger.cs
+++ b/src/debug/DebugLogger.cs
@@ -27,7 +27,6 @@ using System;
using Cairo;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
#if DEBUG_LOG
@@ -47,28 +46,41 @@ namespace Crow
IFaceEndClipping = 0x0104,
IFaceStartDrawing = 0x0105,
IFaceEndDrawing = 0x0106,
+ IFaceUpdate = 0x0107,
//10 nth bit set for graphic obj
GraphicObject = 0x0200,
GOClassCreation = 0x0201,
- GOInitialized = 0x0202,
+ GOInitialization = 0x0202,
GOClippingRegistration = 0x0203,
GORegisterClip = 0x0204,
GORegisterForGraphicUpdate = 0x0205,
GOEnqueueForRepaint = 0x0206,
- GORegisterLayouting = 0x0207,
- GOProcessLayoutingWithNoParent = 0x0208,
- GOProcessLayouting = 0x0209,
+ GOLayouting = 0x0400,
+ GORegisterLayouting = 0x0607,
+ GOProcessLayoutingWithNoParent = 0x0608,
+ GOProcessLayouting = 0x0609,
GODraw = 0x020a,
GORecreateCache = 0x020b,
GOUpdateCacheAndPaintOnCTX = 0x020c,
GOPaint = 0x020d,
GONewDataSource = 0x020e,
}
+ public class DbgData {
+ public int obj;
+ public LayoutingType layout;
+ public LayoutingQueueItem.Result result;
+
+ public DbgData (int _obj) {
+ obj = _obj;
+ }
+ }
public class DbgEvent {
public long begin, end;
public DbgEvtType type;
public object data = null;
+ public DbgEvent() {}
+
public DbgEvent(long timeStamp, DbgEvtType evt, object _data = null) {
data = _data;
type = evt;
@@ -79,13 +91,13 @@ namespace Crow
{
GraphicObject go = data as GraphicObject;
if (go != null)
- return string.Format ("{0};{1};{2}", begin, type, GraphicObject.GraphicObjects.IndexOf(go).ToString());
+ return string.Format ("{0};{1};{2};{3}", begin, end, type, GraphicObject.GraphicObjects.IndexOf(go).ToString());
if (!(data is LayoutingQueueItem))
- return string.Format ("{0};{1}", begin, type);
+ return string.Format ("{0};{1};{2}", begin, end, type);
LayoutingQueueItem lqi = (LayoutingQueueItem)data;
if (type == DbgEvtType.GOProcessLayouting)
- return string.Format ("{0};{1};{2};{3};{4};{5}", begin, type, GraphicObject.GraphicObjects.IndexOf(lqi.graphicObject).ToString(), lqi.LayoutType.ToString(), lqi.result.ToString(), end);
- return string.Format ("{0};{1};{2};{3}", begin, type, GraphicObject.GraphicObjects.IndexOf(lqi.graphicObject).ToString(), lqi.LayoutType.ToString());
+ return string.Format ("{0};{1};{2};{3};{4};{5}", begin, end, type, GraphicObject.GraphicObjects.IndexOf(lqi.graphicObject).ToString(), lqi.LayoutType.ToString(), lqi.result.ToString());
+ return string.Format ("{0};{1};{2};{3};{4}", begin, end, type, GraphicObject.GraphicObjects.IndexOf(lqi.graphicObject).ToString(), lqi.LayoutType.ToString());
}
@@ -94,13 +106,42 @@ namespace Crow
return null;
string[] tmp = str.Trim().Split(';');
- long timeStamp = long.Parse (tmp [0]);
- DbgEvtType type = (DbgEvtType)Enum.Parse (typeof(DbgEvtType), tmp [1]);
- if (type.HasFlag (DbgEvtType.GraphicObject)) {
+ DbgEvent evt = new DbgEvent ();
+ evt.begin = long.Parse (tmp [0]);
+ evt.end = long.Parse (tmp [1]);
+ evt.type = (DbgEvtType)Enum.Parse (typeof(DbgEvtType), tmp [2]);
+
+ if (evt.type.HasFlag (DbgEvtType.GraphicObject)) {
+ DbgData data = new DbgData (int.Parse (tmp [3]));
+ if (evt.type.HasFlag (DbgEvtType.GOLayouting)) {
+ data.layout = (LayoutingType)Enum.Parse (typeof(LayoutingType), tmp [4]);
+ if (evt.type == DbgEvtType.GOProcessLayouting)
+ data.result = (LayoutingQueueItem.Result)Enum.Parse (typeof(LayoutingQueueItem.Result), tmp [5]);
+ }
+ evt.data = data;
}
- return null;
+ return evt;
+ }
+ }
+ public class DbgGo {
+ public int index;
+ public string name;
+ public int yIndex;
+ public int xLevel;
+
+ public static DbgGo Parse (string str) {
+ DbgGo g = new DbgGo ();
+ if (str == null)
+ return null;
+ string[] tmp = str.Trim().Split(';');
+ g.index = int.Parse (tmp [0]);
+ g.name = tmp [1];
+ g.yIndex = int.Parse (tmp [2]);
+ g.xLevel = int.Parse (tmp [3]);
+ return g;
}
+
}
public static class DebugLog
{
@@ -123,24 +164,6 @@ namespace Crow
return evt;
}
- static DebugLog ()
- {
- surf = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height);
- ctx = new Context (surf);
-
- ctx.Antialias = Antialias.Subpixel;
- ctx.FontOptions = Interface.FontRenderingOptions;
- ctx.Antialias = Interface.Antialias;
-
- ctx.Rectangle (bounds);
- ctx.SetSourceColor (Crow.Color.WhiteSmoke);
- ctx.Fill ();
-
- ctx.SelectFontFace ("mono", FontSlant.Normal, FontWeight.Normal);
- ctx.SetFontSize (8.0);
- ySpacing = ctx.FontExtents.Height;
- }
-
static int y, level;
static void parseTree (GraphicObject go) {
@@ -170,19 +193,18 @@ namespace Crow
foreach (GraphicObject go in iface.GraphicTree)
parseTree (go);
- using (StreamWriter s = new StreamWriter("debug.bin")){
+ using (StreamWriter s = new StreamWriter("debug.log")){
s.WriteLine ("[GraphicObjects]");
for (int i=0; i<GraphicObject.GraphicObjects.Count; i++) {
GraphicObject g = GraphicObject.GraphicObjects [i];
s.WriteLine ("{0};{1};{2};{3}", i, g.GetType().Name, g.yIndex, g.xLevel);
}
s.WriteLine ("[Events]");
- foreach (DbgEvent e in events) {
- s.WriteLine (e.ToString ());
- }
+ foreach (DbgEvent e in events)
+ s.WriteLine (e.ToString ());
}
-
+ /*
List<GraphicObject> drawn = new List<GraphicObject> ();
@@ -213,27 +235,12 @@ namespace Crow
//penX = xPenStart + xResolution * lqi.begin;
//ctx.Rectangle (penX, penY, Math.Max(1.0, (lqi.end - lqi.begin) * xResolution), ySpacing);
- switch (lqi.result) {
- case LayoutingQueueItem.Result.Success:
- ctx.SetSourceColor (Crow.Color.Green);
- break;
- case LayoutingQueueItem.Result.Deleted:
- ctx.SetSourceColor (Crow.Color.Red);
- break;
- case LayoutingQueueItem.Result.Discarded:
- ctx.SetSourceColor (Crow.Color.DarkOrange);
- break;
- case LayoutingQueueItem.Result.Requeued:
- ctx.SetSourceColor (Crow.Color.GreenYellow);
- break;
- case LayoutingQueueItem.Result.Register:
- ctx.SetSourceColor (Crow.Color.Blue);
- break;
- }
+
ctx.Fill ();
}
surf.WriteToPng ("debug.png");
+ */
}
}
}