Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
TriggerTracing.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if DEBUG
4 
5 using System.Windows;
6 using System.Windows.Media.Animation;
7 using System.Diagnostics;
8 using System.Windows.Markup;
9 
10 // Code from http://www.wpfmentor.com/2009/01/how-to-debug-triggers-using-trigger.html
11 // No license specified - this code is trimmed out from Release build anyway so it should be ok using it this way
12 
13 // HOWTO: add the following attached property to any trigger and you will see when it is activated/deactivated in the output window
14 // TriggerTracing.TriggerName="your debug name"
15 // TriggerTracing.TraceEnabled="True"
16 
17 namespace SiliconStudio.Presentation.Diagnostics
18 {
19  /// <summary>
20  /// Contains attached properties to activate Trigger Tracing on the specified Triggers.
21  /// This file alone should be dropped into your app.
22  /// </summary>
23  public static class TriggerTracing
24  {
25  static TriggerTracing()
26  {
27  // Initialise WPF Animation tracing and add a TriggerTraceListener
28  PresentationTraceSources.Refresh();
29  PresentationTraceSources.AnimationSource.Listeners.Clear();
30  PresentationTraceSources.AnimationSource.Listeners.Add(new TriggerTraceListener());
31  PresentationTraceSources.AnimationSource.Switch.Level = SourceLevels.All;
32  }
33 
34  #region TriggerName attached property
35 
36  /// <summary>
37  /// Gets the trigger name for the specified trigger. This will be used
38  /// to identify the trigger in the debug output.
39  /// </summary>
40  /// <param name="trigger">The trigger.</param>
41  /// <returns></returns>
42  public static string GetTriggerName(TriggerBase trigger)
43  {
44  return (string)trigger.GetValue(TriggerNameProperty);
45  }
46 
47  /// <summary>
48  /// Sets the trigger name for the specified trigger. This will be used
49  /// to identify the trigger in the debug output.
50  /// </summary>
51  /// <param name="trigger">The trigger.</param>
52  /// <returns></returns>
53  public static void SetTriggerName(TriggerBase trigger, string value)
54  {
55  trigger.SetValue(TriggerNameProperty, value);
56  }
57 
58  public static readonly DependencyProperty TriggerNameProperty =
59  DependencyProperty.RegisterAttached(
60  "TriggerName",
61  typeof(string),
62  typeof(TriggerTracing),
63  new UIPropertyMetadata(string.Empty));
64 
65  #endregion
66 
67  #region TraceEnabled attached property
68 
69  /// <summary>
70  /// Gets a value indication whether trace is enabled for the specified trigger.
71  /// </summary>
72  /// <param name="trigger">The trigger.</param>
73  /// <returns></returns>
74  public static bool GetTraceEnabled(TriggerBase trigger)
75  {
76  return (bool)trigger.GetValue(TraceEnabledProperty);
77  }
78 
79  /// <summary>
80  /// Sets a value specifying whether trace is enabled for the specified trigger
81  /// </summary>
82  /// <param name="trigger"></param>
83  /// <param name="value"></param>
84  public static void SetTraceEnabled(TriggerBase trigger, bool value)
85  {
86  trigger.SetValue(TraceEnabledProperty, value);
87  }
88 
89  public static readonly DependencyProperty TraceEnabledProperty =
90  DependencyProperty.RegisterAttached(
91  "TraceEnabled",
92  typeof(bool),
93  typeof(TriggerTracing),
94  new UIPropertyMetadata(false, OnTraceEnabledChanged));
95 
96  private static void OnTraceEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
97  {
98  var triggerBase = d as TriggerBase;
99 
100  if (triggerBase == null)
101  return;
102 
103  if (!(e.NewValue is bool))
104  return;
105 
106  if ((bool)e.NewValue)
107  {
108  // insert dummy story-boards which can later be traced using WPF animation tracing
109 
110  var storyboard = new TriggerTraceStoryboard(triggerBase, TriggerTraceStoryboardType.Enter);
111  triggerBase.EnterActions.Insert(0, new BeginStoryboard() { Storyboard = storyboard });
112 
113  storyboard = new TriggerTraceStoryboard(triggerBase, TriggerTraceStoryboardType.Exit);
114  triggerBase.ExitActions.Insert(0, new BeginStoryboard() { Storyboard = storyboard });
115  }
116  else
117  {
118  // remove the dummy storyboards
119 
120  foreach (TriggerActionCollection actionCollection in new[] { triggerBase.EnterActions, triggerBase.ExitActions })
121  {
122  foreach (TriggerAction triggerAction in actionCollection)
123  {
124  BeginStoryboard bsb = triggerAction as BeginStoryboard;
125 
126  if (bsb != null && bsb.Storyboard != null && bsb.Storyboard is TriggerTraceStoryboard)
127  {
128  actionCollection.Remove(bsb);
129  break;
130  }
131  }
132  }
133  }
134  }
135 
136  #endregion
137 
138  private enum TriggerTraceStoryboardType
139  {
140  Enter, Exit
141  }
142 
143  /// <summary>
144  /// A dummy storyboard for tracing purposes
145  /// </summary>
146  private class TriggerTraceStoryboard : Storyboard
147  {
148  public TriggerTraceStoryboardType StoryboardType { get; private set; }
149  public TriggerBase TriggerBase { get; private set; }
150 
151  public TriggerTraceStoryboard(TriggerBase triggerBase, TriggerTraceStoryboardType storyboardType)
152  {
153  TriggerBase = triggerBase;
154  StoryboardType = storyboardType;
155  }
156  }
157 
158  /// <summary>
159  /// A custom tracelistener.
160  /// </summary>
161  private class TriggerTraceListener : TraceListener
162  {
163  public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
164  {
165  base.TraceEvent(eventCache, source, eventType, id, format, args);
166 
167  if (format.StartsWith("Storyboard has begun;"))
168  {
169  TriggerTraceStoryboard storyboard = args[1] as TriggerTraceStoryboard;
170  if (storyboard != null)
171  {
172  // add a breakpoint here to see when your trigger has been
173  // entered or exited
174 
175  // the element being acted upon
176  object targetElement = args[5];
177 
178  // the namescope of the element being acted upon
179  INameScope namescope = (INameScope)args[7];
180 
181  TriggerBase triggerBase = storyboard.TriggerBase;
182  string triggerName = GetTriggerName(storyboard.TriggerBase);
183 
184  Debug.WriteLine(string.Format("Element: {0}, {1}: {2}: {3}",
185  targetElement,
186  triggerBase.GetType().Name,
187  triggerName,
188  storyboard.StoryboardType));
189  }
190  }
191  }
192 
193  public override void Write(string message)
194  {
195  }
196 
197  public override void WriteLine(string message)
198  {
199  }
200  }
201  }
202 
203 }
204 
205 #endif
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175