Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
EventManager.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 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Reflection;
7 
8 namespace SiliconStudio.Paradox.UI.Events
9 {
10  /// <summary>
11  /// Provides event-related utility methods that register routed events for class owners and add class handlers.
12  /// </summary>
13  public static class EventManager
14  {
15  /// <summary>
16  /// Finds the routed event identified by its name and owner.
17  /// </summary>
18  /// <param name="ownerType">The type to start the search with. Base classes are included in the search.</param>
19  /// <param name="eventName">The event name.</param>
20  /// <returns>The matching routed event identifier if any match is found; otherwise, null.</returns>
21  public static RoutedEvent GetRoutedEvent(Type ownerType, string eventName)
22  {
23  var currentType = ownerType;
24  while (currentType != null)
25  {
26  if (ownerToEvents.ContainsKey(currentType) && ownerToEvents[currentType].ContainsKey(eventName))
27  return ownerToEvents[currentType][eventName];
28 
29  currentType = currentType.GetTypeInfo().BaseType;
30  }
31 
32  return null;
33  }
34 
35  /// <summary>
36  /// Returns identifiers for routed events that have been registered to the event system.
37  /// </summary>
38  /// <returns>An array of type <see cref="RoutedEvent"/> that contains the registered objects.</returns>
39  public static RoutedEvent[] GetRoutedEvents()
40  {
41  return routedEvents.ToArray();
42  }
43 
44  /// <summary>
45  /// Finds all routed event identifiers for events that are registered with the provided owner type.
46  /// </summary>
47  /// <param name="ownerType">The type to start the search with. Base classes are included in the search.</param>
48  /// <returns>An array of matching routed event identifiers if any match is found; otherwise, null.</returns>
49  public static RoutedEvent[] GetRoutedEventsForOwner(Type ownerType)
50  {
51  var types = new List<Type>();
52 
53  var currentType = ownerType;
54  while (currentType != null)
55  {
56  types.Add(currentType);
57  currentType = currentType.GetTypeInfo().BaseType;
58  }
59 
60  return types.Where(t => ownerToEvents.ContainsKey(t)).SelectMany(t => ownerToEvents[t].Values).ToArray();
61  }
62 
63  /// <summary>
64  /// Registers a class handler for a particular routed event, with the option to handle events where event data is already marked handled.
65  /// </summary>
66  /// <param name="classType">The type of the class that is declaring class handling.</param>
67  /// <param name="routedEvent">The routed event identifier of the event to handle.</param>
68  /// <param name="handler">A reference to the class handler implementation.</param>
69  /// <param name="handledEventsToo">true to invoke this class handler even if arguments of the routed event have been marked as handled;
70  /// false to retain the default behavior of not invoking the handler on any marked-handled event.</param>
71  /// <exception cref="ArgumentNullException"><paramref name="classType"/>, <paramref name="routedEvent"/>, or <paramref name="handler"/> is null.</exception>
72  public static void RegisterClassHandler<T>(Type classType, RoutedEvent<T> routedEvent, EventHandler<T> handler, bool handledEventsToo = false) where T : RoutedEventArgs
73  {
74  if (classType == null) throw new ArgumentNullException("classType");
75  if (routedEvent == null) throw new ArgumentNullException("routedEvent");
76  if (handler == null) throw new ArgumentNullException("handler");
77 
78  if(!classesToClassHandlers.ContainsKey(classType))
79  classesToClassHandlers[classType] = new Dictionary<RoutedEvent, RoutedEventHandlerInfo>();
80 
81  classesToClassHandlers[classType][routedEvent] = new RoutedEventHandlerInfo<T>(handler, handledEventsToo);
82  }
83 
84  /// <summary>
85  /// Get the class handler for the class <paramref name="classType"/> and routed event <paramref name="routedEvent"/>.
86  /// </summary>
87  /// <param name="classType">The type of the class that is handling the event.</param>
88  /// <param name="routedEvent">The routed event to handle</param>
89  /// <returns>The class handler</returns>
90  /// <exception cref="ArgumentNullException"><paramref name="classType"/>, or <paramref name="routedEvent"/> is null.</exception>
91  internal static RoutedEventHandlerInfo GetClassHandler(Type classType, RoutedEvent routedEvent)
92  {
93  if (classType == null) throw new ArgumentNullException("classType");
94  if (routedEvent == null) throw new ArgumentNullException("routedEvent");
95 
96  var currentType = classType;
97  while (currentType != null)
98  {
99  if (classesToClassHandlers.ContainsKey(currentType) && classesToClassHandlers[currentType].ContainsKey(routedEvent))
100  return classesToClassHandlers[currentType][routedEvent];
101 
102  currentType = currentType.GetTypeInfo().BaseType;
103  }
104 
105  return null;
106  }
107 
108  private readonly static Dictionary<Type, Dictionary<RoutedEvent, RoutedEventHandlerInfo>> classesToClassHandlers = new Dictionary<Type, Dictionary<RoutedEvent, RoutedEventHandlerInfo>>();
109 
110  /// <summary>
111  /// Registers a new routed event.
112  /// </summary>
113  /// <param name="name">The name of the routed event. The name must be unique within the owner type (base class included) and cannot be null or an empty string.</param>
114  /// <param name="routingStrategy">The routing strategy of the event as a value of the enumeration.</param>
115  /// <param name="ownerType">The owner class type of the routed event. This cannot be null.</param>
116  /// <returns>The identifier for the newly registered routed event.
117  /// This identifier object can now be stored as a static field in a class and then used as a parameter for methods that attach handlers to the event.
118  /// The routed event identifier is also used for other event system APIs.</returns>
119  /// <exception cref="ArgumentNullException"><paramref name="name"/> or <paramref name="ownerType"/> is null.</exception>
120  /// <exception cref="InvalidOperationException">This exception is thrown if a routed event of name <paramref name="name"/> already exists for type <paramref name="ownerType"/> and parents.
121  /// </exception>
122  public static RoutedEvent<T> RegisterRoutedEvent<T>(string name, RoutingStrategy routingStrategy, Type ownerType) where T: RoutedEventArgs
123  {
124  if (name == null) throw new ArgumentNullException("name");
125  if (ownerType == null) throw new ArgumentNullException("ownerType");
126 
127  if (GetRoutedEvent(ownerType, name) != null)
128  throw new InvalidOperationException("A routed event named '" + name + "' already exists in provided owner type '" + ownerType + "' or base classes.");
129 
130  var newRoutedEvent = new RoutedEvent<T> { Name = name, OwnerType = ownerType, RoutingStrategy = routingStrategy, };
131  routedEvents.Add(newRoutedEvent);
132 
133  if(!ownerToEvents.ContainsKey(ownerType))
134  ownerToEvents[ownerType] = new Dictionary<string, RoutedEvent>();
135 
136  ownerToEvents[ownerType][name] = newRoutedEvent;
137 
138  return newRoutedEvent;
139  }
140 
141  private readonly static List<RoutedEvent> routedEvents = new List<RoutedEvent>();
142  private readonly static Dictionary<Type, Dictionary<string, RoutedEvent>> ownerToEvents = new Dictionary<Type, Dictionary<string, RoutedEvent>>();
143 
144  /// <summary>
145  /// This functions reset all the registers and invalidate all the created routed events.
146  /// It is mostly used for tests purposes.
147  /// </summary>
148  internal static void ResetRegisters()
149  {
150  routedEvents.Clear();
151  ownerToEvents.Clear();
152  classesToClassHandlers.Clear();
153  }
154  }
155 }
static RoutedEvent GetRoutedEvent(Type ownerType, string eventName)
Finds the routed event identified by its name and owner.
Definition: EventManager.cs:21
Contains state information and event data associated with a routed event.
Provides event-related utility methods that register routed events for class owners and add class han...
Definition: EventManager.cs:13
static RoutedEvent[] GetRoutedEventsForOwner(Type ownerType)
Finds all routed event identifiers for events that are registered with the provided owner type...
Definition: EventManager.cs:49
Represents and identifies a routed event and declares its characteristics.
Definition: RoutedEvent.cs:10
static RoutedEvent[] GetRoutedEvents()
Returns identifiers for routed events that have been registered to the event system.
Definition: EventManager.cs:39
A routed event typed with the RoutedEventArgs it triggers.
Definition: RoutedEvent.cs:38
RoutingStrategy
Indicates the routing strategy of a routed event.