<Compile Include="src\Editors\Parsers2\Tokenizer.cs" />
<Compile Include="src\Editors\SourceEditor.cs" />
<Compile Include="src\ProjectTree\StyleProjectItem.cs" />
+ <Compile Include="src\DbgEventViewer.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="ui\" />
--- /dev/null
+//
+// DbgEventViewer.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 Cairo;
+using System.Linq;
+using System.Threading;
+using System.ComponentModel;
+
+namespace Crow.Coding
+{
+ public class DbgEventViewer : ScrollingObject
+ {
+ protected ReaderWriterLockSlim evtsMTX = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
+
+ int visibleLines = 1;
+ int visibleColumns = 1;
+ int hoverLine = -1;
+ List<int> selectedLines = new List<int>();
+ Point mouseLocalPos;
+ Color selBackground, selForeground, hoverBackground;
+
+ FontExtents fe;
+ List<DebugEvent> debugEvents;
+ List<DebugEvent> filteredEvts;
+
+ string threadFilter = "*";
+ string objFilter = "*";
+ bool objSibling, objParent, objDescendants;
+
+ public string ObjFilter {
+ get { return objFilter; }
+ set {
+ if (objFilter == value)
+ return;
+ objFilter = value;
+ NotifyValueChanged ("ObjFilter", objFilter);
+ updateFilteredEvents ();
+ }
+ }
+ public bool ObjSibling {
+ get { return objSibling; }
+ set {
+ if (objSibling == value)
+ return;
+ objSibling = value;
+ NotifyValueChanged ("ObjSibling", objSibling);
+ updateFilteredEvents ();
+ }
+ }
+ public bool ObjParent {
+ get { return objParent; }
+ set {
+ if (objParent == value)
+ return;
+ objParent = value;
+ NotifyValueChanged ("ObjParent", objParent);
+ updateFilteredEvents ();
+ }
+ }
+ public bool ObjDescendants {
+ get { return objDescendants; }
+ set {
+ if (objDescendants == value)
+ return;
+ objDescendants = value;
+ NotifyValueChanged ("ObjDescendants", objDescendants);
+ updateFilteredEvents ();
+ }
+ }
+ public string ThreadFilter {
+ get { return threadFilter; }
+ set {
+ if (threadFilter == value)
+ return;
+ threadFilter = value;
+ NotifyValueChanged ("ThreadFilter", threadFilter);
+ updateFilteredEvents ();
+ }
+ }
+ public List<DebugEvent> DebugEvents {
+ get { return debugEvents; }
+ set {
+ if (debugEvents == value)
+ return;
+ evtsMTX.EnterWriteLock ();
+ debugEvents = value;
+ evtsMTX.ExitWriteLock ();
+ NotifyValueChanged ("DebugEvent", debugEvents);
+
+ updateFilteredEvents ();
+ }
+ }
+ public int HoverLine {
+ get { return hoverLine; }
+ set {
+ if (hoverLine == value)
+ return;
+ hoverLine = value;
+ NotifyValueChanged ("HoverLine", hoverLine);
+ Tooltip = (filteredEvts [hoverLine] as WidgetDebugEvent)?.FullName;
+ evtsMTX.EnterReadLock ();
+ if (selectedLines.Count > 0) {
+ long elapsed = Math.Abs (filteredEvts [selectedLines.LastOrDefault ()].Ticks -
+ filteredEvts [hoverLine].Ticks);
+ NotifyValueChanged ("ElapsedTicks", elapsed);
+ NotifyValueChanged ("ElapsedMS",
+ ((double)(elapsed * Interface.nanosecPerTick) / 1000000.0).ToString("#0.000"));
+ }
+ evtsMTX.ExitReadLock ();
+ RegisterForGraphicUpdate ();
+ }
+ }
+ [DefaultValue("SlateGray")]
+ public virtual Color HoverBackground {
+ get { return hoverBackground; }
+ set {
+ if (value == hoverBackground)
+ return;
+ hoverBackground = value;
+ NotifyValueChanged ("HoverBackground", hoverBackground);
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue("RoyalBlue")]
+ public virtual Color SelectionBackground {
+ get { return selBackground; }
+ set {
+ if (value == selBackground)
+ return;
+ selBackground = value;
+ NotifyValueChanged ("SelectionBackground", selBackground);
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue("White")]
+ public virtual Color SelectionForeground {
+ get { return selForeground; }
+ set {
+ if (value == selForeground)
+ return;
+ selForeground = value;
+ NotifyValueChanged ("SelectionForeground", selForeground);
+ RegisterForRedraw ();
+ }
+ }
+ public override Font Font {
+ get { return base.Font; }
+ set {
+ base.Font = value;
+
+ using (ImageSurface img = new ImageSurface (Format.Argb32, 1, 1)) {
+ using (Context gr = new Context (img)) {
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+
+ fe = gr.FontExtents;
+ }
+ }
+ MaxScrollY = 0;
+ RegisterForGraphicUpdate ();
+ }
+ }
+
+
+ public override void OnLayoutChanges (LayoutingType layoutType)
+ {
+ base.OnLayoutChanges (layoutType);
+
+ if (layoutType == LayoutingType.Height)
+ updateVisibleLines ();
+ else if (layoutType == LayoutingType.Width)
+ updateVisibleColumns ();
+ }
+ protected override void onDraw (Cairo.Context gr)
+ {
+ base.onDraw (gr);
+
+ if (filteredEvts == null)
+ return;
+
+ evtsMTX.EnterReadLock ();
+
+ int filteredCount = filteredEvts.Count;
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+ gr.FontOptions = Interface.FontRenderingOptions;
+ gr.Antialias = Interface.Antialias;
+
+ Rectangle cb = ClientRectangle;
+
+ for (int i = 0; i < visibleLines; i++) {
+ int lineIndex = i + ScrollY;
+ if (lineIndex >= filteredCount)
+ break;
+ string str = filteredEvts [i + ScrollY].ToString ();
+ double y = cb.Y + (fe.Ascent+fe.Descent) * i, x = cb.X;
+
+ gr.Operator = Operator.Multiply;
+ if (selectedLines.Contains (lineIndex)) {
+ gr.SetSourceColor (selBackground);
+ gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
+ gr.Fill ();
+ gr.SetSourceColor (selForeground);
+ }
+ if (lineIndex == hoverLine) {
+ gr.SetSourceColor (hoverBackground);
+ gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
+ gr.Fill ();
+ gr.SetSourceColor (selForeground);
+ }else
+ Foreground.SetAsSource (gr);
+ gr.Operator = Operator.Over;
+ gr.MoveTo (x, y + fe.Ascent);
+ gr.ShowText (str);
+ gr.Stroke ();
+ }
+ evtsMTX.ExitReadLock ();
+ }
+
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseMove (sender, e);
+ mouseLocalPos = e.Position - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+ HoverLine = ScrollY + (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent)));
+ }
+ public override void onMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseDown (sender, e);
+
+ if (IFace.Keyboard [Key.ControlLeft]) {
+ if (hoverLine >= 0) {
+ if (selectedLines.Contains (hoverLine))
+ selectedLines.Remove (hoverLine);
+ else
+ selectedLines.Add (hoverLine);
+ }
+ }else if (IFace.Keyboard [Key.ShiftLeft]) {
+ int curL = selectedLines.LastOrDefault ();
+ int inc = 1;
+ if (curL > hoverLine)
+ inc = -1;
+ while (curL != hoverLine) {
+ curL += inc;
+ if (!selectedLines.Contains(curL))
+ selectedLines.Add (curL);
+ }
+ } else
+ selectedLines = new List<int> () { hoverLine };
+
+ RegisterForGraphicUpdate ();
+ }
+ void updateFilteredEvents () {
+ evtsMTX.EnterWriteLock();
+
+ try {
+
+ if (debugEvents == null)
+ filteredEvts = null;
+ else {
+ if (threadFilter == "*")
+ filteredEvts = debugEvents.ToList ();
+ else {
+ string[] tmp = threadFilter.Split (';');
+ filteredEvts = debugEvents.Where (de=>tmp.Contains(de.ThreadId.ToString())).ToList();
+ }
+
+ if (objFilter != "*"){
+ string[] tmp = objFilter.Split (';');
+ // if (objParent) {
+ // List<string> tmpObjs = new List<string> (tmp);
+ // for (int i = 0; i < tmp.Length; i++) {
+ // tmpObjs.Add(tmp[i].Substring(0, tmp[i].LastIndexOf('.')-1));
+ // }
+ // }
+ List<WidgetDebugEvent> tmpwde = filteredEvts.OfType<WidgetDebugEvent> ().ToList();
+
+ if (objDescendants)
+ filteredEvts = tmpwde.Where (
+ wde=>tmp.Count (t => wde.FullName.Split('.').Contains(t)) > 0)
+ .Cast<DebugEvent>().ToList();
+ else
+ filteredEvts = tmpwde.Where (wde=>tmp.Contains(wde.Name)).Cast<DebugEvent>().ToList();
+ }
+ }
+ } catch (Exception ex) {
+ System.Diagnostics.Debug.WriteLine (ex);
+ }
+
+ evtsMTX.ExitWriteLock ();
+
+ updateMaxScrollY ();
+ RegisterForGraphicUpdate ();
+ }
+ void updateVisibleLines(){
+ visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / (fe.Ascent+fe.Descent));
+ NotifyValueChanged ("VisibleLines", visibleLines);
+ updateMaxScrollY ();
+ RegisterForGraphicUpdate ();
+ }
+ void updateVisibleColumns(){
+ visibleColumns = (int)Math.Floor ((double)(ClientRectangle.Width)/ fe.MaxXAdvance);
+ NotifyValueChanged ("VisibleColumns", visibleColumns);
+ RegisterForGraphicUpdate ();
+ }
+ void updateMaxScrollX (int longestTabulatedLineLength) {
+// MaxScrollX = Math.Max (0, longestTabulatedLineLength - visibleColumns);
+// if (longestTabulatedLineLength > 0)
+// NotifyValueChanged ("ChildWidthRatio", Slot.Width * visibleColumns / longestTabulatedLineLength);
+ }
+ void updateMaxScrollY () {
+ if (filteredEvts == null){
+ MaxScrollY = 0;
+ return;
+ }
+ evtsMTX.EnterReadLock ();
+ int lc = filteredEvts.Count;
+ evtsMTX.ExitReadLock ();
+
+ MaxScrollY = Math.Max (0, lc - visibleLines);
+ if (lc > 0)
+ NotifyValueChanged ("ChildHeightRatio", Slot.Height * visibleLines / lc);
+
+
+ }
+
+ public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
+ {
+ base.onKeyDown (sender, e);
+
+ switch (e.Key) {
+ case Key.W:
+ if (hoverLine < 0 || filteredEvts == null)
+ break;
+ WidgetDebugEvent wde = filteredEvts [hoverLine] as WidgetDebugEvent;
+ if (wde == null)
+ break;
+ ObjFilter = wde.Name;
+ break;
+ }
+ }
+ }
+}
+
#if DBG_EVENTS
bool logLayouting = false;
if (LayoutingQueue.Count > 0){
- DbgStartSubEvt(DbgEvtType.IFaceLayouting);
+ DbgLog(DbgEvtType.IFaceLayouting, "ProcessLayouting");
logLayouting = true;
}
#endif
+
while (LayoutingQueue.Count > 0) {
lqi = LayoutingQueue.Dequeue ();
- #if DBG_EVENTS
- DbgStartSubEvt (new LayoutingDebugEvent(lqi.LayoutType,lqi.Layoutable as GraphicObject));
- #endif
lqi.ProcessLayouting ();
- #if DBG_EVENTS
- DbgEndSubEvt();
- #endif
}
#if DBG_EVENTS
if (logLayouting)
- DbgEndSubEvt();
+ DbgLog(DbgEvtType.IFaceLayouting, "End of ProcessLayouting");
#endif
LayoutingQueue = DiscardQueue;
Monitor.Exit (LayoutMutex);
}
public List<DebugEvent> DebugEvents {
- get { return instance?.IFace.PerThreadCurDbgEvt.ToList(); }
+ get { return Interface.DbgEvents; }
}
void GTView_SelectedItemChanged (object sender, SelectionChangeEventArgs e){
<?xml version="1.0"?>
<DockWindow Name="winLQIs" Caption="Layouting Queue Items Explorer" Width="90%" Height="80%">
- <VerticalStack DataSource="{CurrentSolution}">
- <TreeView DataSource="{SelectedItem}" Name="treeView" Data="{DebugEvents}">
- <ItemTemplate DataType="Crow.DebugEvent" Data="ChildEvents">
- <Expandable >
- <Template>
- <VerticalStack Spacing="1">
- <HorizontalStack Spacing="1" MouseDoubleClick="./onClickForExpand">
- <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
- Path="{./Image}"
- Visible="{./IsExpandable}"
- SvgSub="{./IsExpanded}"
- MouseEnter="{Background=LightGray}"
- MouseLeave="{Background=Transparent}"/>
- <Label Style="DbgGridCell" Text="{ThreadId}" Width="18" />
- <Label Style="DbgGridCell" Text="{EventType}" Width="90" />
- <Label Style="DbgGridCell" Text="{Ticks}" Width="60" TextAlignment="Right"/>
- <Label Text="{Message}" Width="Stretched" Background="White" Foreground="Black"/>
- </HorizontalStack>
- <Container Name="Content" Visible="false"/>
- </VerticalStack>
- </Template>
- <HorizontalStack Height="Fit">
- <GraphicObject Width="8" Height="10"/>
- <VerticalStack Height="Fit" Name="ItemsContainer"/>
- </HorizontalStack>
- </Expandable>
- </ItemTemplate>
- <ItemTemplate DataType="Crow.LayoutingDebugEvent">
- <Expandable >
- <Template>
- <VerticalStack Spacing="1">
- <HorizontalStack Spacing="1" MouseDoubleClick="./onClickForExpand">
- <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
- Path="{./Image}"
- Visible="{./IsExpandable}"
- SvgSub="{./IsExpanded}"
- MouseEnter="{Background=LightGray}"
- MouseLeave="{Background=Transparent}"/>
- <Label Style="DbgGridCell" Text="{LayoutingType}" Width="60"/>
- <Label Style="DbgGridCell" Text="{EndResult}" Width="60"/>
- <Label Style="DbgGridCell" Text="{Ticks}" Width="60" TextAlignment="Right"/>
- <Label Style="DbgGridCell" Text="{Target}" Width="30%" Tooltip="{Target}"/>
- <Label Style="DbgGridCell" Text="{PreviousSlot}" Width="100"/>
- <Label Style="DbgGridCell" Text="{Slot}" Width="100"/>
- </HorizontalStack>
- <Container Name="Content" Visible="false"/>
- </VerticalStack>
- </Template>
- <HorizontalStack Height="Fit">
- <GraphicObject Width="8" Height="10"/>
- <VerticalStack Height="Fit" Name="ItemsContainer"/>
- </HorizontalStack>
- </Expandable>
- </ItemTemplate>
- </TreeView>
+ <VerticalStack>
+<!-- <Expandable Height="Fit" Caption="Filters">-->
+ <VerticalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Thread filter"/>
+ <TextBox Text="{²../../../../viewer.ThreadFilter}" Width="30"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Obj filter"/>
+ <TextBox Text="{²../../../../viewer.ObjFilter}" />
+ <CheckBox Caption="Sibling" IsChecked="{²../../../../viewer.ObjSibling}"/>
+ <CheckBox Caption="Parent" IsChecked="{²../../../../viewer.ObjParent}"/>
+ <CheckBox Caption="Descendants" IsChecked="{²../../../../viewer.ObjDescendants}"/>
+ </HorizontalStack>
+ </VerticalStack>
+<!-- </Expandable>-->
+ <Expandable Height="Fit" Caption="Infos">
+ <HorizontalStack Height="Fit">
+ <Label Text="elapsed:"/>
+ <Label Text="{../../../viewer.ElapsedTicks}" Foreground="White" Width="50" TextAlignment="Right"/>
+ <Label Text="ticks"/>
+ <Label Text="{../../../viewer.ElapsedMS}" Foreground="White" Width="50" TextAlignment="Right"/>
+ <Label Text="ms"/>
+ </HorizontalStack>
+ </Expandable>
+ <HorizontalStack DataSource="{CurrentSolution}">
+ <DbgEventViewer Font="mono, 8" Focusable="true" Name="viewer" DataSource="{SelectedItem}" DebugEvents="{DebugEvents}"/>
+ <ScrollBar
+ Name="scrollbar1"
+ LargeIncrement="{../viewer.PageHeight}" SmallIncrement="30"
+ CursorSize="{../viewer.ChildHeightRatio}"
+ Value="{²../viewer.ScrollY}"
+ Maximum="{../viewer.MaxScrollY}"
+ Width="14" Orientation="Vertical"/>
+ </HorizontalStack>
</VerticalStack>
</DockWindow>
-
+ <!-- <TreeView DataSource="{SelectedItem}" Name="treeView" Data="{DebugEvents}">
+ <ItemTemplate DataType="Crow.DebugEvent" Data="ChildEvents">
+ <Expandable >
+ <Template>
+ <VerticalStack Spacing="1">
+ <HorizontalStack Spacing="1" MouseDoubleClick="./onClickForExpand">
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{./IsExpandable}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGray}"
+ MouseLeave="{Background=Transparent}"/>
+ <Label Style="DbgGridCell" Text="{ThreadId}" Width="18" />
+ <Label Style="DbgGridCell" Text="{EventType}" Width="90" />
+ <Label Style="DbgGridCell" Text="{Ticks}" Width="60" TextAlignment="Right"/>
+ <Label Text="{Message}" Width="Stretched" Background="White" Foreground="Black"/>
+ </HorizontalStack>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <GraphicObject Width="8" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+ </Expandable>
+ </ItemTemplate>
+ <ItemTemplate DataType="Crow.LayoutingDebugEvent">
+ <Expandable >
+ <Template>
+ <VerticalStack Spacing="1">
+ <HorizontalStack Spacing="1" MouseDoubleClick="./onClickForExpand">
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{./IsExpandable}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGray}"
+ MouseLeave="{Background=Transparent}"/>
+ <Label Style="DbgGridCell" Text="{LayoutingType}" Width="60"/>
+ <Label Style="DbgGridCell" Text="{EndResult}" Width="60"/>
+ <Label Style="DbgGridCell" Text="{Ticks}" Width="60" TextAlignment="Right"/>
+ <Label Style="DbgGridCell" Text="{Target}" Width="30%" Tooltip="{Target}"/>
+ <Label Style="DbgGridCell" Text="{PreviousSlot}" Width="100"/>
+ <Label Style="DbgGridCell" Text="{Slot}" Width="100"/>
+ </HorizontalStack>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <GraphicObject Width="8" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+ </Expandable>
+ </ItemTemplate>
+ </TreeView>-->
<!-- <ItemTemplate DataType="Crow.LayoutingQueueItem" Data="triggeredLQIs">
<Expandable>
<Template>
<Label TextAlignment="Left" Text="{./SelectedItemName}" Width="Stretched"/>
</Border>
<HorizontalStack>
- <Scroller Name="scroller1" Margin="1"
- Background="{./Background}"
- ScrollY="{../scrollbar1.Value}">
+ <Scroller Name="scroller1" Margin="1" Background="{./Background}">
<VerticalStack Spacing="1"
Height="Fit" Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/>
</Scroller>
Name="scrollbar1"
LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
CursorSize="{../scroller1.ChildHeightRatio}"
- Value="{../scroller1.ScrollY}"
- Maximum="{../scroller1.MaximumScroll}"
+ Value="{²../scroller1.ScrollY}"
+ Maximum="{../scroller1.MaxScrollY}"
Width="14" Orientation="Vertical"/>
</HorizontalStack>
</VerticalStack>
RecreateCache = 0x24,
IFaceLayouting = 0x80,
UpdateLayout = 0x81,
- RegisterLayouting= 0x82,
+ RequeueLQI = 0x82,
+ DiscardLQI = 0x83,
+ DeleteLQI = 0x84,
+ SucceedLQI = 0x85,
+ RegisterLayouting= 0x86,
}
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 long Ticks;
public string Message;
- public DebugEvent Parent;
- public List<DebugEvent> ChildEvents = new List<DebugEvent>();
-
- public long Ticks { get { return Time.ElapsedTicks; }}
-
-
- public virtual void Start () {
- Time = Stopwatch.StartNew();
- }
- public virtual void Finished () {
- Time.Stop();
+ public override string ToString ()
+ {
+ return string.Format ("{0,2}:{1,10}:{2} {3}", ThreadId, Ticks, EventType, Message);
}
}
- public class WidgetDebugEvent : DebugEvent {
- public GraphicObject Target;
+ public class WidgetDebugEvent : DebugEvent {
+ public string FullName;
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 GraphicObject Target {
+ set {
+ FullName = value.ToString ();
+ RegisteredLayoutings = value.registeredLayoutings;
+ RequestedLayoutings = value.requestedLayoutings;
+ Width = value.Width;
+ Height = value.Height;
+ Slot = value.Slot;
+ }
}
- }
- public class LayoutingDebugEvent : WidgetDebugEvent
- {
- public enum Result {
- Ok,
- Requeued,
- Discarded,
- Deleted,
+ public string Name {
+ get { return string.IsNullOrEmpty(FullName) ? "" : FullName.Substring(FullName.LastIndexOf('.')+1); }
}
- 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;
- }
-
public override string ToString ()
{
- return string.Format ("{0} {1} {2} {3} => {4}", Target, LayoutingType, EndResult, PreviousSlot, Slot);
+ return base.ToString() + ";" + string.Format ("{0};{1};{2};{3}", Name, RegisteredLayoutings, RequestedLayoutings, Slot);
}
}
#endif
public virtual bool ArrangeChildren { get { return false; } }
public virtual void RegisterForLayouting(LayoutingType layoutType = LayoutingType.None){
+ #if DBG_EVENTS
+ Interface.DbgLog(DbgEvtType.RegisterLayouting, layoutType.ToString(), this);
+ #endif
+
Interface iface = IFace;
if (iface == null || !Monitor.TryEnter(IFace.LayoutMutex)) {
requestedLayoutings |= layoutType;
/// met and LQI has to be re-queued</returns>
public virtual bool UpdateLayout (LayoutingType layoutType)
{
- #if DEBUG_UPDATE
- Debug.WriteLine (string.Format("UpdateLayout ({1})-> {0}", this.ToString (), layoutType));
+ #if DBG_EVENTS
+ Interface.DbgLog(DbgEvtType.UpdateLayout, layoutType.ToString(), this);
#endif
//unset bit, it would be reset if LQI is re-queued
registeredLayoutings &= (~layoutType);
public class Interface : ILayoutable
{
#if DBG_EVENTS
- const int MAX_THREAD = 20;
+ public static long nanosecPerTick = 0;
+ public static Stopwatch DbgTicks = Stopwatch.StartNew();
+ public static List<DebugEvent> DbgEvents = new List<DebugEvent>();
+
+ public static void DbgLog (DbgEvtType type, string message = "", GraphicObject go = null) {
+ DebugEvent de = null;
+ if (go == null)
+ de = new DebugEvent ();
+ else
+ de = new WidgetDebugEvent () { Target = go };
+
+ de.ThreadId = Thread.CurrentThread.ManagedThreadId;
+ de.Ticks = DbgTicks.ElapsedTicks;
+ de.EventType = type;
+ de.Message = message;
- 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;
+ DbgEvents.Add (de);
}
#endif
#region CTOR
- static Interface(){
+ static Interface(){
if (Type.GetType ("Mono.Runtime") == null) {
throw new Exception (@"C.R.O.W. run only on Mono, download latest version at: http://www.mono-project.com/download/stable/");
}
+ #if DBG_EVENTS
+ nanosecPerTick = (1000L * 1000L * 1000L) / Stopwatch.Frequency;
+ #endif
+
CrowConfigRoot =
System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
void interfaceThread()
{
#if DBG_EVENTS
- CurDbgEvt = new DebugEvent(DbgEvtType.IfaceStart);
+ DbgLog(DbgEvtType.IfaceStart, "IFace thread start");
#endif
while (ClientRectangle.Size.Width == 0)
loadCursors ();
loadStyling ();
findAvailableTemplates ();
-// initTooltip ();
-// initContextMenus ();
+ initTooltip ();
+ initContextMenus ();
}
#region Static and constants
/// 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 DBG_EVENTS
+ DbgLog(DbgEvtType.IFaceUpdate);
+ #endif
if (armedClickSender != null && clickTimer.ElapsedMilliseconds >= Interface.DoubleClick) {
armedClickSender.onMouseClick (armedClickSender, armedClickEvtArgs);
#if DBG_EVENTS
bool logLayouting = false;
if (LayoutingQueue.Count > 0){
- DbgStartSubEvt(DbgEvtType.IFaceLayouting);
+ DbgLog(DbgEvtType.IFaceLayouting, "ProcessLayouting");
logLayouting = true;
}
#endif
while (LayoutingQueue.Count > 0) {
lqi = LayoutingQueue.Dequeue ();
- #if DBG_EVENTS
- DbgStartSubEvt (new LayoutingDebugEvent(lqi.LayoutType,lqi.Layoutable as GraphicObject));
- #endif
lqi.ProcessLayouting ();
- #if DBG_EVENTS
- DbgEndSubEvt();
- #endif
}
-
#if DBG_EVENTS
if (logLayouting)
- DbgEndSubEvt();
+ DbgLog(DbgEvtType.IFaceLayouting, "End of ProcessLayouting");
#endif
LayoutingQueue = DiscardQueue;
if (ClippingQueue.Count == 0)
return;
#if DBG_EVENTS
- DbgStartSubEvt(DbgEvtType.IFaceClipping);
+ DbgLog(DbgEvtType.IFaceClipping, "ClippingRegistration");
#endif
GraphicObject g = null;
while (ClippingQueue.Count > 0) {
}
#if DBG_EVENTS
- DbgEndSubEvt();
+ DbgLog(DbgEvtType.IFaceClipping, "End of Clipping Registration");
#endif
}
/// <summary>Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be
using (ctx = new Context (surf)){
if (!clipping.IsEmpty) {
#if DBG_EVENTS
- DbgStartSubEvt(DbgEvtType.IFaceDrawing);
+ DbgLog(DbgEvtType.IFaceDrawing);
#endif
for (int i = 0; i < clipping.NumRectangles; i++)
}
}
#if DBG_EVENTS
- DbgEndSubEvt ();
+ DbgLog(DbgEvtType.IFaceDrawing, "End of drawing");
#endif
#if DEBUG_CLIP_RECTANGLE
go.requestedLayoutings |= LayoutType;
go.parentRWLock.ExitReadLock ();
#if DBG_EVENTS
- (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Deleted;
- go.IFace.CurDbgEvt.Message = "Parent is null";
+ Interface.DbgLog(DbgEvtType.DeleteLQI, "Parent is null", go);
#endif
return;
}
Layoutable.RegisteredLayoutings |= LayoutType;
#if DBG_EVENTS
- (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Requeued;
+ Interface.DbgLog(DbgEvtType.RequeueLQI, LayoutType.ToString(), go);
#endif
(Layoutable as GraphicObject).IFace.LayoutingQueue.Enqueue (this);
} else if (DiscardCount < Interface.MaxDiscardCount) {
#if DBG_EVENTS
- (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Discarded;
+ Interface.DbgLog(DbgEvtType.DiscardLQI, LayoutType.ToString(), go);
#endif
go.LayoutingDiscardCheck (LayoutType);
LayoutingTries = 0;
}
#if DBG_EVENTS
else
- (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Deleted;
+ Interface.DbgLog(DbgEvtType.DeleteLQI, LayoutType.ToString(), go);
#endif
}
#if DBG_EVENTS
else
- (go.IFace.CurDbgEvt as LayoutingDebugEvent).EndResult = LayoutingDebugEvent.Result.Ok;
+ Interface.DbgLog(DbgEvtType.SucceedLQI, LayoutType.ToString(), go);
#endif
go.parentRWLock.ExitReadLock ();
Xor,
Add,
Saturate,
+
+ Multiply,
+ Screen,
+ Overlay,
+ Darken,
+ Lighten,
+ Dodge,
+ Burn,
+ Light,
+ SoftLight,
+ Difference,
+ Exclusion,
+ HslHue,
+ HslSaturation,
+ HslColor,
+ HslLuminosity
}
}