void FixValueList(List <CounterValueInfo> list, DateTime endTime) { if (list.Count == 0) { return; } list.Sort(delegate(CounterValueInfo v1, CounterValueInfo v2) { return(v1.Time.CompareTo(v2.Time)); }); for (int n = 0; n < list.Count - 1; n++) { CounterValueInfo val = list [n]; if (val.TimerTraces != null) { int i = n + 1; DateTime localEndTime = val.Time + val.Duration; while (i < list.Count && list [i].Time < localEndTime) { i++; } list.RemoveRange(n + 1, i - n - 1); val.CanExpand = (i > n + 1) || (val.TimerTraces.Any()); } else { val.Duration = list [n + 1].Time - val.Time; } } list [list.Count - 1].Duration = endTime - list [list.Count - 1].Time; }
void ToggleExpand(CounterValueInfo val) { val.Expanded = !val.Expanded; if (!val.Expanded || val.ExpandedTimerTraces != null) { QueueDraw(); return; } ExpandValue(val); QueueDraw(); }
void ExpandValue(CounterValueInfo val) { List <CounterValueInfo> list = new List <CounterValueInfo> (); if (val.TimerTraces != null) { FillTimerTraces(val.TimerTraces, list, val.Time, val.Time + val.Duration); } else { GetValues(list, val.Time, val.Time + val.Duration, false, false); } if (list.Count == 0) { val.CanExpand = false; } FixValueList(list, val.Time + val.Duration); val.ExpandedTimerTraces = list; }
void FillTimerTraces(IEnumerable <TimerTrace> traces, List <CounterValueInfo> list, DateTime startTime, DateTime endTime) { if (!traces.Any()) { GetValues(list, startTime, endTime, false, false); } else { GetValues(list, startTime, traces.First().Timestamp, false, false); } foreach (TimerTrace tt in traces) { CounterValueInfo v = new CounterValueInfo(); v.Time = tt.Timestamp; v.Trace = tt.Message; v.Counter = mainCounter; v.CanExpand = true; list.Add(v); } }
void GetValues(List <CounterValueInfo> list, DateTime startTime, DateTime endTime, bool includeStart, bool includeEnd) { foreach (Counter c in App.Service.GetCounters()) { foreach (CounterValue cval in c.GetValuesBetween(startTime, endTime)) { if (singleThread && cval.ThreadId != mainValue.ThreadId) { continue; } if (!includeStart && cval.TimeStamp == startTime) { continue; } if (!includeEnd && cval.TimeStamp == endTime) { continue; } CounterValueInfo v = new CounterValueInfo(); v.Time = cval.TimeStamp; v.Counter = c; v.Trace = "[" + c.Name + ": " + cval.Value + "]"; if (!string.IsNullOrEmpty(cval.Message)) { v.Trace = cval.Message + " " + v.Trace; } if (cval.HasTimerTraces) { v.TimerTraces = cval.GetTimerTraces(); v.Duration = cval.Duration; v.CanExpand = true; } list.Add(v); } } }
void DrawValue (Cairo.Context ctx, Gdk.GC gc, DateTime initialTime, int ytop, int lx, int tx, ref int ty, ref int maxx, ref int maxy, int indent, CounterValueInfo val) { Gdk.Color color; if (val.Counter != null) color = val.Counter.GetColor (); else color = Style.Black; // Draw text gc.RgbFgColor = color; double ms = (val.Time - initialTime).TotalMilliseconds; string txt = (ms / 1000).ToString ("0.00000") + ": " + (val.Duration.TotalMilliseconds / 1000).ToString ("0.00000") + " " + val.Trace; layout.SetText (txt); GdkWindow.DrawLayout (gc, tx + indent, ty, layout); int tw, th; layout.GetPixelSize (out tw, out th); if (tx + tw + indent > maxx) maxx = tx + tw + indent; HotSpot hp = AddHotSpot (tx + indent, ty, tw, th); int tempTy = ty; hp.Action = delegate { int ytm = ytop + (int) ((ms * scale) / 1000); SetBaseTime ((int) (tempTy + (th / 2) + 0.5) - ytm); }; hp.OnMouseOver += delegate { overValue = val; QueueDraw (); }; hp.Action += delegate { focusedValue = val; QueueDraw (); }; // Draw time marker int ytime = ytop + (int) ((ms * scale) / 1000) + baseTime; if (val == focusedValue || val == overValue) { ctx.NewPath (); double dx = val == focusedValue ? 0 : 2; ctx.Rectangle (lx + 0.5 + dx - SelectedValuePadding, ytime + 0.5, LineEndWidth - dx*2 + SelectedValuePadding, ((val.Duration.TotalMilliseconds * scale) / 1000)); Mono.TextEditor.HslColor hsl = color; hsl.L = val == focusedValue ? 0.9 : 0.8; ctx.SetSourceColor (hsl); ctx.Fill (); } ctx.NewPath (); ctx.LineWidth = 1; ctx.MoveTo (lx + 0.5, ytime + 0.5); ctx.LineTo (lx + LineEndWidth + 0.5, ytime + 0.5); ctx.LineTo (tx - 3 - LineEndWidth + 0.5, ty + (th / 2) + 0.5); ctx.LineTo (tx + indent - 3 + 0.5, ty + (th / 2) + 0.5); ctx.SetSourceColor (color.ToCairoColor ()); ctx.Stroke (); // Expander bool incLine = true; if (val.CanExpand) { double ex = tx + indent - 3 - ExpanderSize - 2 + 0.5; double ey = ty + (th / 2) - (ExpanderSize/2) + 0.5; hp = AddHotSpot (ex, ey, ExpanderSize, ExpanderSize); DrawExpander (ctx, ex, ey, val.Expanded, false); hp.OnMouseOver = delegate { using (Cairo.Context c = CairoHelper.Create (GdkWindow)) { DrawExpander (c, ex, ey, val.Expanded, true); } }; hp.OnMouseLeave = delegate { using (Cairo.Context c = CairoHelper.Create (GdkWindow)) { DrawExpander (c, ex, ey, val.Expanded, false); } }; hp.Action = delegate { ToggleExpand (val); }; if (val.Expanded && val.ExpandedTimerTraces.Count > 0) { ty += th + LineSpacing; foreach (CounterValueInfo cv in val.ExpandedTimerTraces) DrawValue (ctx, gc, initialTime, ytop, lx, tx, ref ty, ref maxx, ref maxy, indent + ChildIndent, cv); incLine = false; } } if (incLine) ty += th + LineSpacing; if (ytime > maxy) maxy = ytime; }
void ToggleExpand (CounterValueInfo val) { val.Expanded = !val.Expanded; if (!val.Expanded || val.ExpandedTimerTraces != null) { QueueDraw (); return; } ExpandValue (val); QueueDraw (); }
void GetValues (List<CounterValueInfo> list, DateTime startTime, DateTime endTime, bool includeStart, bool includeEnd) { foreach (Counter c in App.Service.GetCounters ()) { foreach (CounterValue cval in c.GetValuesBetween (startTime, endTime)) { if (singleThread && cval.ThreadId != mainValue.ThreadId) continue; if (!includeStart && cval.TimeStamp == startTime) continue; if (!includeEnd && cval.TimeStamp == endTime) continue; CounterValueInfo v = new CounterValueInfo (); v.Time = cval.TimeStamp; v.Counter = c; v.Trace = "[" + c.Name + ": " + cval.Value + "]"; if (!string.IsNullOrEmpty (cval.Message)) v.Trace = cval.Message + " " + v.Trace; if (cval.HasTimerTraces) { v.TimerTraces = cval.GetTimerTraces (); v.Duration = cval.Duration; v.CanExpand = true; } list.Add (v); } } }
void ExpandValue (CounterValueInfo val) { List<CounterValueInfo> list = new List<CounterValueInfo> (); if (val.TimerTraces != null) { FillTimerTraces (val.TimerTraces, list, val.Time, val.Time + val.Duration); } else { GetValues (list, val.Time, val.Time + val.Duration, false, false); } if (list.Count == 0) val.CanExpand = false; FixValueList (list, val.Time + val.Duration); val.ExpandedTimerTraces = list; }
void FillTimerTraces (IEnumerable<TimerTrace> traces, List<CounterValueInfo> list, DateTime startTime, DateTime endTime) { if (traces.Count () == 0) { GetValues (list, startTime, endTime, false, false); } else { GetValues (list, startTime, traces.First ().Timestamp, false, false); } foreach (TimerTrace tt in traces) { CounterValueInfo v = new CounterValueInfo (); v.Time = tt.Timestamp; v.Trace = tt.Message; v.Counter = mainCounter; v.CanExpand = true; list.Add (v); } }
void DrawValue(Cairo.Context ctx, Gdk.GC gc, DateTime initialTime, int ytop, int lx, int tx, ref int ty, ref int maxx, ref int maxy, int indent, CounterValueInfo val) { Gdk.Color color; if (val.Counter != null) { color = val.Counter.GetColor(); } else { color = Style.Black; } // Draw text gc.RgbFgColor = color; double ms = (val.Time - initialTime).TotalMilliseconds; string txt = (ms / 1000).ToString("0.00000") + ": " + (val.Duration.TotalMilliseconds / 1000).ToString("0.00000") + " " + val.Trace; layout.SetText(txt); GdkWindow.DrawLayout(gc, tx + indent, ty, layout); int tw, th; layout.GetPixelSize(out tw, out th); if (tx + tw + indent > maxx) { maxx = tx + tw + indent; } HotSpot hp = AddHotSpot(tx + indent, ty, tw, th); int tempTy = ty; hp.Action = delegate { int ytm = ytop + (int)((ms * scale) / 1000); SetBaseTime((int)(tempTy + (th / 2) + 0.5) - ytm); }; hp.OnMouseOver += delegate { overValue = val; QueueDraw(); }; hp.Action += delegate { focusedValue = val; QueueDraw(); }; // Draw time marker int ytime = ytop + (int)((ms * scale) / 1000) + baseTime; if (val == focusedValue || val == overValue) { ctx.NewPath(); double dx = val == focusedValue ? 0 : 2; ctx.Rectangle(lx + 0.5 + dx - SelectedValuePadding, ytime + 0.5, LineEndWidth - dx * 2 + SelectedValuePadding, ((val.Duration.TotalMilliseconds * scale) / 1000)); HslColor hsl = color; hsl.L = val == focusedValue ? 0.9 : 0.8; ctx.SetSourceColor(hsl); ctx.Fill(); } ctx.NewPath(); ctx.LineWidth = 1; ctx.MoveTo(lx + 0.5, ytime + 0.5); ctx.LineTo(lx + LineEndWidth + 0.5, ytime + 0.5); ctx.LineTo(tx - 3 - LineEndWidth + 0.5, ty + (th / 2) + 0.5); ctx.LineTo(tx + indent - 3 + 0.5, ty + (th / 2) + 0.5); ctx.SetSourceColor(color.ToCairoColor()); ctx.Stroke(); // Expander bool incLine = true; if (val.CanExpand) { double ex = tx + indent - 3 - ExpanderSize - 2 + 0.5; double ey = ty + (th / 2) - (ExpanderSize / 2) + 0.5; hp = AddHotSpot(ex, ey, ExpanderSize, ExpanderSize); DrawExpander(ctx, ex, ey, val.Expanded, false); hp.OnMouseOver = delegate { using (Cairo.Context c = CairoHelper.Create(GdkWindow)) { DrawExpander(c, ex, ey, val.Expanded, true); } }; hp.OnMouseLeave = delegate { using (Cairo.Context c = CairoHelper.Create(GdkWindow)) { DrawExpander(c, ex, ey, val.Expanded, false); } }; hp.Action = delegate { ToggleExpand(val); }; if (val.Expanded && val.ExpandedTimerTraces.Count > 0) { ty += th + LineSpacing; foreach (CounterValueInfo cv in val.ExpandedTimerTraces) { DrawValue(ctx, gc, initialTime, ytop, lx, tx, ref ty, ref maxx, ref maxy, indent + ChildIndent, cv); } incLine = false; } } if (incLine) { ty += th + LineSpacing; } if (ytime > maxy) { maxy = ytime; } }