com.wallstop-studios.dxmessaging 2.0.0-rc13 → 2.0.0-rc15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,9 @@ Game engine agnostic robust, synchronous pub/sub C# messaging solution, mostly g
16
16
 
17
17
  # Installation
18
18
 
19
+ ## From Releases
20
+ Check out the latest [Releases](https://github.com/wallstop/DxMessaging/releases) to grab the Unity Package and import to your project.
21
+
19
22
  ## To Install as Unity Package
20
23
  1. Open Unity Package Manager
21
24
  2. (Optional) Enable Pre-release packages to get the latest, cutting-edge builds
@@ -29,23 +32,20 @@ Game engine agnostic robust, synchronous pub/sub C# messaging solution, mostly g
29
32
  ## From Source
30
33
  Grab a copy of this repo (either `git clone` both [this repo](https://github.com/wallstop/DxMessaging) *and* [Unity Helpers](https://github.com/wallstop/unity-helpers) or [download a zip of the source](https://github.com/wallstop/DxMessaging/archive/refs/heads/master.zip) and [Unity Helper's source](https://github.com/wallstop/unity-helpers/archive/refs/heads/main.zip)) and copy the contents to your project's `Assets` folder.
31
34
 
32
- ## From Releases
33
- Check out the latest [Releases](https://github.com/wallstop/DxMessaging/releases) to grab the Unity Package and import to your project.
34
-
35
35
  # Dependencies
36
36
  This project has a dependency on my [`Unity Helpers`](https://github.com/wallstop/unity-helpers) project, which contains the `System.Runtime.CompilerServices.Unsafe.dll`, which is used for some speed hacks in DxMessaging directly. Unity Helpers bundles a few (small) dependencies, including protobuf. If you don't want these dependencies, or if they conflict in some way, you can either include a copy of the `System.Runtime.CompilerServices.Unsafe.dll` yourself without relying on UnityHelpers, or manually download and include the Unity Helpers project and delete anything that conflicts with your project. Or, manually download this project without UnityHelpers. The choice is yours.
37
37
 
38
38
  # Benchmarks
39
39
  DxMessaging is currently a bit slower (2-3x) than Unity's built in messaging solution (when running in Unity). [Source](./Tests/Runtime/Benchmarks/PerformanceTests.cs).
40
40
 
41
- | Message Tech | Operations / Second | Memory Allocated |
42
- | ------------ | ------------------- | --------------- |
43
- | Unity | 2,302,247 | 76.83 GB |
44
- | DxMessaging (GameObject) - Normal | 1,223,941 | 3.52 MB |
45
- | DxMessaging (Component) - Normal | 1,229,897 | 2.83 MB |
46
- | DxMessaging (GameObject) - No-Copy | 1,172,148 | 2.83 MB |
47
- | DxMessaging (Component) - No-Copy | 1,258,505 | 3.03 MB |
48
- | DxMessaging (Untargeted) - No-Copy | 1,737,476 | 4.2 MB |
41
+ | Message Tech | Operations / Second | Allocations? |
42
+ | ------------ | ------------------- | ------------ |
43
+ | Unity | 2,287,562 | Yes |
44
+ | DxMessaging (GameObject) - Normal | 1,198,797 | No |
45
+ | DxMessaging (Component) - Normal | 1,198,796 | No |
46
+ | DxMessaging (GameObject) - No-Copy | 1,137,634 | No |
47
+ | DxMessaging (Component) - No-Copy | 1,225,105 | No |
48
+ | DxMessaging (Untargeted) - No-Copy | 1,681,407 | No |
49
49
 
50
50
  # Functionality
51
51
  While not as fast, DxMessaging offers *additional functionality* as compared to Unity's messaging solution.
@@ -64,6 +64,7 @@ While not as fast, DxMessaging offers *additional functionality* as compared to
64
64
  | Send a message without boxing its parameters | _ | ✓ |
65
65
  | Listen to all messages | _ | ✓ |
66
66
  | View a filter-able history of message registrations | N/A | ✓ |
67
+ | "PreUpdate" style handlers | _ | ✓ |
67
68
  | "LateUpdate" style handlers | _ | ✓ |
68
69
 
69
70
  # Concepts
@@ -23,7 +23,8 @@
23
23
  private readonly int _id;
24
24
 
25
25
  #if UNITY_2017_1_OR_NEWER
26
- public UnityEngine.Object Object { get; }
26
+ // ReSharper disable once InconsistentNaming
27
+ public readonly UnityEngine.Object Object;
27
28
  #endif
28
29
 
29
30
  [JsonConstructor]
@@ -36,10 +37,10 @@
36
37
  }
37
38
 
38
39
  #if UNITY_2017_1_OR_NEWER
39
- private InstanceId(UnityEngine.Object @object)
40
+ private InstanceId(UnityEngine.Object unityObject)
40
41
  {
41
- _id = @object.GetInstanceID();
42
- Object = @object;
42
+ _id = unityObject.GetInstanceID();
43
+ Object = unityObject;
43
44
  }
44
45
 
45
46
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -88,9 +89,9 @@
88
89
  #if UNITY_2017_1_OR_NEWER
89
90
  UnityEngine.Object instance = Object;
90
91
  string objectName = instance == null ? string.Empty : instance.name;
91
- return $"{{\"Id\": {_id}, \"Name\": \"{objectName}\"}}";
92
+ return new { Id = _id, Name = objectName }.ToString();
92
93
  #else
93
- return $"{{\"Id\": {_id}}}";
94
+ return new { Id = _id }.ToString();
94
95
  #endif
95
96
  }
96
97
 
@@ -5,10 +5,16 @@
5
5
  using Messages;
6
6
 
7
7
  /// <summary>
8
- /// Description of a general purpose message bus that provides both registration, de-registration, and broadcast capabilities.
8
+ /// Description of a general purpose message bus that provides both registration, deregistration, and broadcast capabilities.
9
9
  /// </summary>
10
10
  public interface IMessageBus
11
11
  {
12
+ public int RegisteredBroadcast { get; }
13
+
14
+ public int RegisteredTargeted { get; }
15
+
16
+ public int RegisteredUntargeted { get; }
17
+
12
18
  /// <summary>
13
19
  /// Given an Untargeted message, determines whether or not it should be processed or skipped
14
20
  /// </summary>
@@ -54,7 +60,7 @@
54
60
  /// </summary>
55
61
  /// <typeparam name="T">Specific type of UntargetedMessages to register for.</typeparam>
56
62
  /// <param name="messageHandler">MessageHandler to register to accept UntargetedMessages of the specified type.</param>
57
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to receive messages.</returns>
63
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to receive messages.</returns>
58
64
  Action RegisterUntargeted<T>(MessageHandler messageHandler, int priority = 0)
59
65
  where T : IUntargetedMessage;
60
66
 
@@ -64,7 +70,7 @@
64
70
  /// <typeparam name="T">Specific type of TargetedMessages to register for.</typeparam>
65
71
  /// <param name="target">Target of messages to listen for.</param>
66
72
  /// <param name="messageHandler">MessageHandler to register the TargetedMessages of the specified type.</param>
67
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to receive the messages.</returns>
73
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to receive the messages.</returns>
68
74
  Action RegisterTargeted<T>(
69
75
  InstanceId target,
70
76
  MessageHandler messageHandler,
@@ -78,7 +84,7 @@
78
84
  /// </summary>
79
85
  /// <typeparam name="T">Specific type of TargetedMessages to register for.</typeparam>
80
86
  /// <param name="messageHandler">MessageHandler to register to accept all TargetedMessages of the specified type.</param>
81
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to receive messages.</returns>
87
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to receive messages.</returns>
82
88
  Action RegisterTargetedWithoutTargeting<T>(MessageHandler messageHandler, int priority = 0)
83
89
  where T : ITargetedMessage;
84
90
 
@@ -88,7 +94,7 @@
88
94
  /// <typeparam name="T">Type of the BroadcastMessage to register.</typeparam>
89
95
  /// <param name="source">InstanceId of the source for BroadcastMessages to listen to.</param>
90
96
  /// <param name="messageHandler">MessageHandler to register to accept BroadcastMessages.</param>
91
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to receive messages.</returns>
97
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to receive messages.</returns>
92
98
  Action RegisterSourcedBroadcast<T>(
93
99
  InstanceId source,
94
100
  MessageHandler messageHandler,
@@ -102,7 +108,7 @@
102
108
  /// </summary>
103
109
  /// <typeparam name="T">Type of the BroadcastMessage to register.</typeparam>
104
110
  /// <param name="messageHandler">MessageHandler to register to accept BroadcastMessages.</param>
105
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to receive messages.</returns>
111
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to receive messages.</returns>
106
112
  Action RegisterSourcedBroadcastWithoutSource<T>(
107
113
  MessageHandler messageHandler,
108
114
  int priority = 0
@@ -114,7 +120,7 @@
114
120
  /// It doesn't matter if the message is Targeted or Untargeted, this MessageHandler will be invoked for it.
115
121
  /// </summary>
116
122
  /// <param name="messageHandler">MessageHandler to register to accept all messages.</param>
117
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to receive messages.</returns>
123
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to receive messages.</returns>
118
124
  Action RegisterGlobalAcceptAll(MessageHandler messageHandler);
119
125
 
120
126
  /// <summary>
@@ -135,7 +141,7 @@
135
141
  /// param1: Current message instance by reference
136
142
  /// And returns: true if message handling should continue, false if message handling should be stopped.
137
143
  /// </note>
138
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to intercept messages.</returns>
144
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to intercept messages.</returns>
139
145
  Action RegisterUntargetedInterceptor<T>(
140
146
  UntargetedInterceptor<T> interceptor,
141
147
  int priority = 0
@@ -160,7 +166,7 @@
160
166
  /// param1: Current message instance by reference
161
167
  /// And returns: true if message handling should continue, false if message handling should be stopped.
162
168
  /// </note>
163
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to intercept messages.</returns>
169
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to intercept messages.</returns>
164
170
  Action RegisterTargetedInterceptor<T>(TargetedInterceptor<T> interceptor, int priority = 0)
165
171
  where T : ITargetedMessage;
166
172
 
@@ -182,7 +188,7 @@
182
188
  /// param1: Current message instance by reference
183
189
  /// And returns: true if message handling should continue, false if message handling should be stopped.
184
190
  /// </note>
185
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to intercept messages.</returns>
191
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to intercept messages.</returns>
186
192
  Action RegisterBroadcastInterceptor<T>(
187
193
  BroadcastInterceptor<T> interceptor,
188
194
  int priority = 0
@@ -190,25 +196,25 @@
190
196
  where T : IBroadcastMessage;
191
197
 
192
198
  /// <summary>
193
- /// Registers the provided MessageHandler to post process Untargeted messages of the given type.
199
+ /// Registers the provided MessageHandler to post-process Untargeted messages of the given type.
194
200
  /// (This will run after all handlers run for the provided message).
195
201
  /// </summary>
196
- /// <typeparam name="T">Type of UntargetedMessage to post process.</typeparam>
197
- /// <param name="messageHandler">MessageHandler to post process messages for.</param>
202
+ /// <typeparam name="T">Type of UntargetedMessage to post-process.</typeparam>
203
+ /// <param name="messageHandler">MessageHandler to post-process messages for.</param>
198
204
  /// <param name="priority">Priority of the interceptor to run at. Handlers run in order of priority from low -> high.</param>
199
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to post process messages.</returns>
205
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to post-process messages.</returns>
200
206
  Action RegisterUntargetedPostProcessor<T>(MessageHandler messageHandler, int priority = 0)
201
207
  where T : IUntargetedMessage;
202
208
 
203
209
  /// <summary>
204
- /// Registers the provided MessageHandler to post process Targeted messages of the given type.
210
+ /// Registers the provided MessageHandler to post-process Targeted messages of the given type.
205
211
  /// (This will run after all handlers run for the provided message).
206
212
  /// </summary>
207
- /// <typeparam name="T">Type of TargetedMessage to post process.</typeparam>
213
+ /// <typeparam name="T">Type of TargetedMessage to post-process.</typeparam>
208
214
  /// <param name="target">Target of messages to listen for.</param>
209
- /// <param name="messageHandler">MessageHandler to post process messages for.</param>
215
+ /// <param name="messageHandler">MessageHandler to post-process messages for.</param>
210
216
  /// <param name="priority">Priority of the interceptor to run at. Handlers run in order of priority from low -> high.</param>
211
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to post process messages.</returns>
217
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to post-process messages.</returns>
212
218
  Action RegisterTargetedPostProcessor<T>(
213
219
  InstanceId target,
214
220
  MessageHandler messageHandler,
@@ -217,13 +223,13 @@
217
223
  where T : ITargetedMessage;
218
224
 
219
225
  /// <summary>
220
- /// Registers the provided MessageHandler to post process Targeted messages of the given type for all targets.
226
+ /// Registers the provided MessageHandler to post-process Targeted messages of the given type for all targets.
221
227
  /// (This will run after all handlers run for the provided message).
222
228
  /// </summary>
223
- /// <typeparam name="T">Type of TargetedMessage to post process.</typeparam>
224
- /// <param name="messageHandler">MessageHandler to post process messages for.</param>
229
+ /// <typeparam name="T">Type of TargetedMessage to post-process.</typeparam>
230
+ /// <param name="messageHandler">MessageHandler to post-process messages for.</param>
225
231
  /// <param name="priority">Priority of the interceptor to run at. Handlers run in order of priority from low -> high.</param>
226
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to post process messages.</returns>
232
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to post-process messages.</returns>
227
233
  Action RegisterTargetedWithoutTargetingPostProcessor<T>(
228
234
  MessageHandler messageHandler,
229
235
  int priority = 0
@@ -231,14 +237,14 @@
231
237
  where T : ITargetedMessage;
232
238
 
233
239
  /// <summary>
234
- /// Registers the provided MessageHandler to post process Targeted messages of the given type.
240
+ /// Registers the provided MessageHandler to post-process Targeted messages of the given type.
235
241
  /// (This will run after all handlers run for the provided message).
236
242
  /// </summary>
237
- /// <typeparam name="T">Type of TargetedMessage to post process.</typeparam>
243
+ /// <typeparam name="T">Type of TargetedMessage to post-process.</typeparam>
238
244
  /// <param name="source">Source of messages to listen for.</param>
239
- /// <param name="messageHandler">MessageHandler to post process messages for.</param>
245
+ /// <param name="messageHandler">MessageHandler to post-process messages for.</param>
240
246
  /// <param name="priority">Priority of the interceptor to run at. Handlers run in order of priority from low -> high.</param>
241
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to post process messages.</returns>
247
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to post-process messages.</returns>
242
248
  Action RegisterBroadcastPostProcessor<T>(
243
249
  InstanceId source,
244
250
  MessageHandler messageHandler,
@@ -247,13 +253,13 @@
247
253
  where T : IBroadcastMessage;
248
254
 
249
255
  /// <summary>
250
- /// Registers the provided MessageHandler to post process Targeted messages of the given type for all sources.
256
+ /// Registers the provided MessageHandler to post-process Targeted messages of the given type for all sources.
251
257
  /// (This will run after all handlers run for the provided message).
252
258
  /// </summary>
253
- /// <typeparam name="T">Type of TargetedMessage to post process.</typeparam>
254
- /// <param name="messageHandler">MessageHandler to post process messages for.</param>
259
+ /// <typeparam name="T">Type of TargetedMessage to post-process.</typeparam>
260
+ /// <param name="messageHandler">MessageHandler to post-process messages for.</param>
255
261
  /// <param name="priority">Priority of the interceptor to run at. Handlers run in order of priority from low -> high.</param>
256
- /// <returns>The de-registration action. Should be invoked when the handler no longer wants to post process messages.</returns>
262
+ /// <returns>The deregistration action. Should be invoked when the handler no longer wants to post-process messages.</returns>
257
263
  Action RegisterBroadcastWithoutSourcePostProcessor<T>(
258
264
  MessageHandler messageHandler,
259
265
  int priority = 0
@@ -221,11 +221,15 @@
221
221
  );
222
222
  if (!_globalSinks.TryGetValue(messageHandler, out count))
223
223
  {
224
- MessagingDebug.Log(
225
- LogLevel.Error,
226
- "Received over-deregistration of GlobalAcceptAll for MessageHandler {0}. Check to make sure you're not calling (de)registration multiple times.",
227
- messageHandler
228
- );
224
+ if (MessagingDebug.enabled)
225
+ {
226
+ MessagingDebug.Log(
227
+ LogLevel.Error,
228
+ "Received over-deregistration of GlobalAcceptAll for MessageHandler {0}. Check to make sure you're not calling (de)registration multiple times.",
229
+ messageHandler
230
+ );
231
+ }
232
+
229
233
  return;
230
234
  }
231
235
 
@@ -421,7 +425,7 @@
421
425
  _uniqueInterceptorsAndPriorities.Remove(interceptor);
422
426
  }
423
427
  }
424
- else
428
+ else if (MessagingDebug.enabled)
425
429
  {
426
430
  MessagingDebug.Log(
427
431
  LogLevel.Error,
@@ -441,7 +445,7 @@
441
445
  complete = interceptors.Remove(interceptor);
442
446
  }
443
447
 
444
- if (!complete)
448
+ if (!complete && MessagingDebug.enabled)
445
449
  {
446
450
  MessagingDebug.Log(
447
451
  LogLevel.Error,
@@ -534,7 +538,7 @@
534
538
  }
535
539
  }
536
540
 
537
- if (!foundAnyHandlers)
541
+ if (!foundAnyHandlers && MessagingDebug.enabled)
538
542
  {
539
543
  MessagingDebug.Log(
540
544
  LogLevel.Info,
@@ -765,7 +769,7 @@
765
769
  }
766
770
  }
767
771
 
768
- if (!foundAnyHandlers)
772
+ if (!foundAnyHandlers && MessagingDebug.enabled)
769
773
  {
770
774
  MessagingDebug.Log(
771
775
  LogLevel.Info,
@@ -1096,7 +1100,7 @@
1096
1100
  }
1097
1101
  }
1098
1102
 
1099
- if (!foundAnyHandlers)
1103
+ if (!foundAnyHandlers && MessagingDebug.enabled)
1100
1104
  {
1101
1105
  MessagingDebug.Log(
1102
1106
  LogLevel.Info,
@@ -1914,12 +1918,16 @@
1914
1918
  || !handler.TryGetValue(messageHandler, out count)
1915
1919
  )
1916
1920
  {
1917
- MessagingDebug.Log(
1918
- LogLevel.Error,
1919
- "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
1920
- type,
1921
- messageHandler
1922
- );
1921
+ if (MessagingDebug.enabled)
1922
+ {
1923
+ MessagingDebug.Log(
1924
+ LogLevel.Error,
1925
+ "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
1926
+ type,
1927
+ messageHandler
1928
+ );
1929
+ }
1930
+
1923
1931
  return;
1924
1932
  }
1925
1933
 
@@ -1937,7 +1945,7 @@
1937
1945
  _ = sinks.Remove(type);
1938
1946
  }
1939
1947
 
1940
- if (!complete)
1948
+ if (!complete && MessagingDebug.enabled)
1941
1949
  {
1942
1950
  MessagingDebug.Log(
1943
1951
  LogLevel.Error,
@@ -2032,12 +2040,16 @@
2032
2040
  || !handler.TryGetValue(messageHandler, out count)
2033
2041
  )
2034
2042
  {
2035
- MessagingDebug.Log(
2036
- LogLevel.Error,
2037
- "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
2038
- type,
2039
- messageHandler
2040
- );
2043
+ if (MessagingDebug.enabled)
2044
+ {
2045
+ MessagingDebug.Log(
2046
+ LogLevel.Error,
2047
+ "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
2048
+ type,
2049
+ messageHandler
2050
+ );
2051
+ }
2052
+
2041
2053
  return;
2042
2054
  }
2043
2055
 
@@ -2059,7 +2071,7 @@
2059
2071
  _ = sinks.Remove(type);
2060
2072
  }
2061
2073
 
2062
- if (!complete)
2074
+ if (!complete && MessagingDebug.enabled)
2063
2075
  {
2064
2076
  MessagingDebug.Log(
2065
2077
  LogLevel.Error,
@@ -2106,7 +2118,10 @@
2106
2118
  }
2107
2119
  else
2108
2120
  {
2109
- messageHandlers.AddRange(handlers);
2121
+ foreach (KeyValuePair<int, SortedList<MessageHandler, int>> handler in handlers)
2122
+ {
2123
+ messageHandlers.Add(handler);
2124
+ }
2110
2125
  }
2111
2126
  return messageHandlers;
2112
2127
  }
@@ -2162,7 +2177,10 @@
2162
2177
  }
2163
2178
  default:
2164
2179
  {
2165
- messageHandlers.AddRange(handlers);
2180
+ foreach (MessageHandler handler in handlers)
2181
+ {
2182
+ messageHandlers.Add(handler);
2183
+ }
2166
2184
  break;
2167
2185
  }
2168
2186
  }