com.wallstop-studios.dxmessaging 1.0.0-rc10
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/.gitattributes +63 -0
- package/CHANGELOG.md +0 -0
- package/CHANGELOG.md.meta +7 -0
- package/Editor.meta +8 -0
- package/LICENSE.md +7 -0
- package/LICENSE.md.meta +7 -0
- package/README.md +76 -0
- package/README.md.meta +7 -0
- package/Runtime/Core/Extensions/MessageExtensions.cs +275 -0
- package/Runtime/Core/Extensions/MessageExtensions.cs.meta +11 -0
- package/Runtime/Core/Extensions.meta +8 -0
- package/Runtime/Core/IMessage.cs +12 -0
- package/Runtime/Core/IMessage.cs.meta +11 -0
- package/Runtime/Core/InstanceId.cs +117 -0
- package/Runtime/Core/InstanceId.cs.meta +11 -0
- package/Runtime/Core/MessageBus/IMessageBus.cs +249 -0
- package/Runtime/Core/MessageBus/IMessageBus.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageBus.cs +961 -0
- package/Runtime/Core/MessageBus/MessageBus.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessagingRegistration.cs +100 -0
- package/Runtime/Core/MessageBus/MessagingRegistration.cs.meta +11 -0
- package/Runtime/Core/MessageBus/RegistrationLog.cs +111 -0
- package/Runtime/Core/MessageBus/RegistrationLog.cs.meta +11 -0
- package/Runtime/Core/MessageBus.meta +8 -0
- package/Runtime/Core/MessageHandler.cs +1589 -0
- package/Runtime/Core/MessageHandler.cs.meta +11 -0
- package/Runtime/Core/MessageRegistrationHandle.cs +55 -0
- package/Runtime/Core/MessageRegistrationHandle.cs.meta +11 -0
- package/Runtime/Core/MessageRegistrationToken.cs +885 -0
- package/Runtime/Core/MessageRegistrationToken.cs.meta +11 -0
- package/Runtime/Core/Messages/IBroadcastMessage.cs +27 -0
- package/Runtime/Core/Messages/IBroadcastMessage.cs.meta +11 -0
- package/Runtime/Core/Messages/ITargetedMessage.cs +26 -0
- package/Runtime/Core/Messages/ITargetedMessage.cs.meta +11 -0
- package/Runtime/Core/Messages/IUntargetedMessage.cs +26 -0
- package/Runtime/Core/Messages/IUntargetedMessage.cs.meta +11 -0
- package/Runtime/Core/Messages.meta +8 -0
- package/Runtime/Core/MessagingDebug.cs +71 -0
- package/Runtime/Core/MessagingDebug.cs.meta +11 -0
- package/Runtime/Core.meta +8 -0
- package/Runtime/Unity/MessageAwareComponent.cs +77 -0
- package/Runtime/Unity/MessageAwareComponent.cs.meta +11 -0
- package/Runtime/Unity/MessagingComponent.cs +73 -0
- package/Runtime/Unity/MessagingComponent.cs.meta +11 -0
- package/Runtime/Unity.meta +8 -0
- package/Runtime/WallstopStudios.DxMessaging.asmdef +18 -0
- package/Runtime/WallstopStudios.DxMessaging.asmdef.meta +7 -0
- package/Runtime.meta +8 -0
- package/Tests/Editor/WallstopStudios.DxMessaging.Tests.Editor.asmdef +23 -0
- package/Tests/Editor/WallstopStudios.DxMessaging.Tests.Editor.asmdef.meta +7 -0
- package/Tests/Editor.meta +8 -0
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs +196 -0
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks.meta +8 -0
- package/Tests/Runtime/Core/BroadcastTests.cs +600 -0
- package/Tests/Runtime/Core/BroadcastTests.cs.meta +11 -0
- package/Tests/Runtime/Core/GlobalAcceptAllTests.cs +169 -0
- package/Tests/Runtime/Core/GlobalAcceptAllTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessagingTestBase.cs +164 -0
- package/Tests/Runtime/Core/MessagingTestBase.cs.meta +11 -0
- package/Tests/Runtime/Core/NominalTests.cs +1468 -0
- package/Tests/Runtime/Core/NominalTests.cs.meta +11 -0
- package/Tests/Runtime/Core/PostProcessorTests.cs +849 -0
- package/Tests/Runtime/Core/PostProcessorTests.cs.meta +11 -0
- package/Tests/Runtime/Core/RegistrationTests.cs +1045 -0
- package/Tests/Runtime/Core/RegistrationTests.cs.meta +11 -0
- package/Tests/Runtime/Core/TargetedTests.cs +596 -0
- package/Tests/Runtime/Core/TargetedTests.cs.meta +11 -0
- package/Tests/Runtime/Core/UntargetedTests.cs +149 -0
- package/Tests/Runtime/Core/UntargetedTests.cs.meta +11 -0
- package/Tests/Runtime/Core.meta +8 -0
- package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs +9 -0
- package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs.meta +11 -0
- package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +140 -0
- package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs.meta +11 -0
- package/Tests/Runtime/Scripts/Components.meta +8 -0
- package/Tests/Runtime/Scripts/Messages/ComplexTargetedMessage.cs +28 -0
- package/Tests/Runtime/Scripts/Messages/ComplexTargetedMessage.cs.meta +11 -0
- package/Tests/Runtime/Scripts/Messages/SimpleBroadcastMessage.cs +8 -0
- package/Tests/Runtime/Scripts/Messages/SimpleBroadcastMessage.cs.meta +11 -0
- package/Tests/Runtime/Scripts/Messages/SimpleTargetedMessage.cs +8 -0
- package/Tests/Runtime/Scripts/Messages/SimpleTargetedMessage.cs.meta +11 -0
- package/Tests/Runtime/Scripts/Messages/SimpleUntargetedMessage.cs +8 -0
- package/Tests/Runtime/Scripts/Messages/SimpleUntargetedMessage.cs.meta +11 -0
- package/Tests/Runtime/Scripts/Messages.meta +8 -0
- package/Tests/Runtime/Scripts.meta +8 -0
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +22 -0
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef.meta +7 -0
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj +1 -0
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj.meta +7 -0
- package/Tests/Runtime.meta +8 -0
- package/Tests.meta +8 -0
- package/Third Party Notices.md +1 -0
- package/Third Party Notices.md.meta +7 -0
- package/package.json +36 -0
- package/package.json.meta +7 -0
package/.gitattributes
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
# Set default behavior to automatically normalize line endings.
|
|
3
|
+
###############################################################################
|
|
4
|
+
* text=auto
|
|
5
|
+
|
|
6
|
+
###############################################################################
|
|
7
|
+
# Set default behavior for command prompt diff.
|
|
8
|
+
#
|
|
9
|
+
# This is need for earlier builds of msysgit that does not have it on by
|
|
10
|
+
# default for csharp files.
|
|
11
|
+
# Note: This is only used by command line
|
|
12
|
+
###############################################################################
|
|
13
|
+
#*.cs diff=csharp
|
|
14
|
+
|
|
15
|
+
###############################################################################
|
|
16
|
+
# Set the merge driver for project and solution files
|
|
17
|
+
#
|
|
18
|
+
# Merging from the command prompt will add diff markers to the files if there
|
|
19
|
+
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
|
20
|
+
# the diff markers are never inserted). Diff markers may cause the following
|
|
21
|
+
# file extensions to fail to load in VS. An alternative would be to treat
|
|
22
|
+
# these files as binary and thus will always conflict and require user
|
|
23
|
+
# intervention with every merge. To do so, just uncomment the entries below
|
|
24
|
+
###############################################################################
|
|
25
|
+
#*.sln merge=binary
|
|
26
|
+
#*.csproj merge=binary
|
|
27
|
+
#*.vbproj merge=binary
|
|
28
|
+
#*.vcxproj merge=binary
|
|
29
|
+
#*.vcproj merge=binary
|
|
30
|
+
#*.dbproj merge=binary
|
|
31
|
+
#*.fsproj merge=binary
|
|
32
|
+
#*.lsproj merge=binary
|
|
33
|
+
#*.wixproj merge=binary
|
|
34
|
+
#*.modelproj merge=binary
|
|
35
|
+
#*.sqlproj merge=binary
|
|
36
|
+
#*.wwaproj merge=binary
|
|
37
|
+
|
|
38
|
+
###############################################################################
|
|
39
|
+
# behavior for image files
|
|
40
|
+
#
|
|
41
|
+
# image files are treated as binary by default.
|
|
42
|
+
###############################################################################
|
|
43
|
+
#*.jpg binary
|
|
44
|
+
#*.png binary
|
|
45
|
+
#*.gif binary
|
|
46
|
+
|
|
47
|
+
###############################################################################
|
|
48
|
+
# diff behavior for common document formats
|
|
49
|
+
#
|
|
50
|
+
# Convert binary document formats to text before diffing them. This feature
|
|
51
|
+
# is only available from the command line. Turn it on by uncommenting the
|
|
52
|
+
# entries below.
|
|
53
|
+
###############################################################################
|
|
54
|
+
#*.doc diff=astextplain
|
|
55
|
+
#*.DOC diff=astextplain
|
|
56
|
+
#*.docx diff=astextplain
|
|
57
|
+
#*.DOCX diff=astextplain
|
|
58
|
+
#*.dot diff=astextplain
|
|
59
|
+
#*.DOT diff=astextplain
|
|
60
|
+
#*.pdf diff=astextplain
|
|
61
|
+
#*.PDF diff=astextplain
|
|
62
|
+
#*.rtf diff=astextplain
|
|
63
|
+
#*.RTF diff=astextplain
|
package/CHANGELOG.md
ADDED
|
File without changes
|
package/Editor.meta
ADDED
package/LICENSE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2023 Eli Pinkerton
|
|
2
|
+
|
|
3
|
+
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:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
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.
|
package/LICENSE.md.meta
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# DxMessaging
|
|
2
|
+
Game engine agnostic robust, synchronous pub/sub C# messaging solution, mostly geared towards Unity and XNA/Monogame. See [this recorded talk](https://fathom.video/share/qjs8pn1MAwGb-yTAaW5WpZWdjzxcdwFR).
|
|
3
|
+
|
|
4
|
+
# Benchmarks
|
|
5
|
+
DxMessaging is currently a bit slower (2-3x) than Unity's built in messaging solution (when running in Unity). [Source](./Tests/Runtime/Core/PerformanceTests.cs).
|
|
6
|
+
| Message Tech | Operations / Second |
|
|
7
|
+
| ------------ | ------------------- |
|
|
8
|
+
| Unity | 1,955,744 |
|
|
9
|
+
| DxMessaging (GameObject) - Normal | 596,409 |
|
|
10
|
+
| DxMessaging (Component) - Normal | 602,120 |
|
|
11
|
+
| DxMessaging (GameObject) - No-Copy | 583,824 |
|
|
12
|
+
| DxMessaging (Component) - No-Copy | 611,504 |
|
|
13
|
+
| DxMessaging (Untargeted) - No-Copy | 1,044,795 |
|
|
14
|
+
|
|
15
|
+
# Functionality
|
|
16
|
+
While not as fast, DxMessaging offers *additional functionality* as compared to Unity's messaging solution.
|
|
17
|
+
| Feature | Unity | DxMessaging |
|
|
18
|
+
| ------- | ----- | ----------- |
|
|
19
|
+
| Require knowledge of receiver's implementation | ✓ | _ |
|
|
20
|
+
| Send a message to a GameObject | ✓ | ✓ |
|
|
21
|
+
| Send a message to a Component | _ | ✓ |
|
|
22
|
+
| Ignore messages dynamically at runtime | _ | ✓ (multiple ways) |
|
|
23
|
+
| Send messages to all receivers | _ | ✓ |
|
|
24
|
+
| Listen to messages for another GameObject | _ | ✓ (multiple ways)|
|
|
25
|
+
| Listen to messages for another Component | _ | ✓ (multiple ways)|
|
|
26
|
+
| Listen to messages *from* another GameObject | _ | ✓ (multiple ways)|
|
|
27
|
+
| Listen to messages *from* another Component | _ | ✓ (multiple ways)|
|
|
28
|
+
| Send a message without boxing its parameters | _ | ✓ |
|
|
29
|
+
| Listen to all messages | _ | ✓ |
|
|
30
|
+
| View a filter-able history of message registrations | N/A | ✓ |
|
|
31
|
+
| "LateUpdate" style handlers | _ | ✓ |
|
|
32
|
+
|
|
33
|
+
# Concepts
|
|
34
|
+
There are a few important concepts that DxMessaging provides.
|
|
35
|
+
* **MessageBus**: An implementation of the `IMessageBus` interface, configured to relay messages. There is no limit to these. By default there is only one, the global message bus.
|
|
36
|
+
* **Emitter**: Any piece of code, anywhere can emit messages to any MessageBus. By default messages are emitted to the global message bus.
|
|
37
|
+
* **Receiver**: A piece of code that has registered with a message bus to receive messages of certain types from it.
|
|
38
|
+
* **UntargetedMessage**: Messages that are global, and will be sent to every receiver that is registered for this type.
|
|
39
|
+
* **TargetedMessage**: Messages that are intended *for* a receiver, like a piece of mail or a command.
|
|
40
|
+
* **BroadcastMessage**: Messages that are *from* an emitter, indicating events that happened to the emitter.
|
|
41
|
+
|
|
42
|
+
## Receivers
|
|
43
|
+
Receivers can subscribe to any number of message types.
|
|
44
|
+
* For targeted messages, generally receivers listen to their own object as the target, but the receiver can opt to listen to any target, or even all targets.
|
|
45
|
+
* For broadcast messages, receivers can listen to any source, including themselves, or even all sources.
|
|
46
|
+
|
|
47
|
+
For Unity, we have an easy-to-integrate [MessageAwareComponent](./Runtime/Unity/MessageAwareComponent.cs) - simply extend any component you want off of this base class. This will handle message registration lifetimes automatically for you.
|
|
48
|
+
If you have your own base classes or aren't using Unity, then you'll need to add lifetimes yourself. Please use the MessageAwareComponent as reference.
|
|
49
|
+
### Integration
|
|
50
|
+
See the [tests](./Tests/Runtime/Scripts/) directory for examples about how to integrate with the MessageAwareComponent. But, for some starters:
|
|
51
|
+
```csharp
|
|
52
|
+
public readonly struct SimpleTargetedMessage : ITargetedMessage<SimpleTargetedMessage>
|
|
53
|
+
{
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public sealed class SimpleMessageAwareComponent : MessageAwareComponent
|
|
57
|
+
{
|
|
58
|
+
protected override void RegisterMessageHandlers()
|
|
59
|
+
{
|
|
60
|
+
_ = _messageRegistrationToken.RegisterGameObjectTargeted<SimpleTargetedMessage>(gameObject, HandleSimpleTargetedMessage);
|
|
61
|
+
}
|
|
62
|
+
-
|
|
63
|
+
private void HandleSimpleTargetedMessage(ref SimpleTargetedMessage message)
|
|
64
|
+
{
|
|
65
|
+
Debug.Log("Received SimpleTargetedMessage.");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// In some other bit of code
|
|
70
|
+
// Select a target
|
|
71
|
+
SimpleMessageAwareComponent target = Object.FindObjectOfType<SimpleMessageAwareComponent>();
|
|
72
|
+
// Create your message
|
|
73
|
+
SimpleTargetedMessage message = new();
|
|
74
|
+
// Send it - this will synchrously invoke all relevant handlers and return execution once complete
|
|
75
|
+
message.EmitGameObjectTargeted(target.gameObject);
|
|
76
|
+
```
|
package/README.md.meta
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
namespace DxMessaging.Core.Extensions
|
|
2
|
+
{
|
|
3
|
+
using Core;
|
|
4
|
+
using MessageBus;
|
|
5
|
+
using Messages;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Extensions to smartly go about emitting messages :^)
|
|
9
|
+
/// </summary>
|
|
10
|
+
public static class MessageExtensions
|
|
11
|
+
{
|
|
12
|
+
|
|
13
|
+
#if UNITY_2017_1_OR_NEWER
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// Emits a TargetedMessage of the given type.
|
|
16
|
+
/// </summary>
|
|
17
|
+
/// <param name="message">TargetedMessage to emit.</param>
|
|
18
|
+
/// <param name="target">Target that this message is intended for.</param>
|
|
19
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
20
|
+
public static void EmitGameObjectTargeted<TMessage>(this TMessage message, UnityEngine.GameObject target, IMessageBus messageBus = null) where TMessage : class, ITargetedMessage
|
|
21
|
+
{
|
|
22
|
+
InstanceId targetId = target;
|
|
23
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
24
|
+
if (typeof(TMessage) != message.MessageType)
|
|
25
|
+
{
|
|
26
|
+
messageBus.UntypedTargetedBroadcast(targetId, message);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
messageBus.TargetedBroadcast(ref targetId, ref message);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// <summary>
|
|
34
|
+
/// Emits a TargetedMessage of the given type.
|
|
35
|
+
/// </summary>
|
|
36
|
+
/// <param name="message">TargetedMessage to emit.</param>
|
|
37
|
+
/// <param name="target">Target that this message is intended for.</param>
|
|
38
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
39
|
+
public static void EmitGameObjectTargeted<TMessage>(this ref TMessage message, UnityEngine.GameObject target, IMessageBus messageBus = null) where TMessage : struct, ITargetedMessage
|
|
40
|
+
{
|
|
41
|
+
InstanceId targetId = target;
|
|
42
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
43
|
+
if (typeof(TMessage) != message.MessageType)
|
|
44
|
+
{
|
|
45
|
+
messageBus.UntypedTargetedBroadcast(targetId, message);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
messageBus.TargetedBroadcast(ref targetId, ref message);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// <summary>
|
|
53
|
+
/// Emits a TargetedMessage of the given type.
|
|
54
|
+
/// </summary>
|
|
55
|
+
/// <param name="message">TargetedMessage to emit.</param>
|
|
56
|
+
/// <param name="target">Target that this message is intended for.</param>
|
|
57
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
58
|
+
public static void EmitComponentTargeted<TMessage>(this TMessage message, UnityEngine.Component target, IMessageBus messageBus = null) where TMessage : class, ITargetedMessage
|
|
59
|
+
{
|
|
60
|
+
InstanceId targetId = target;
|
|
61
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
62
|
+
if (typeof(TMessage) != message.MessageType)
|
|
63
|
+
{
|
|
64
|
+
messageBus.UntypedTargetedBroadcast(targetId, message);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
messageBus.TargetedBroadcast(ref targetId, ref message);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// <summary>
|
|
72
|
+
/// Emits a TargetedMessage of the given type.
|
|
73
|
+
/// </summary>
|
|
74
|
+
/// <param name="message">TargetedMessage to emit.</param>
|
|
75
|
+
/// <param name="target">Target that this message is intended for.</param>
|
|
76
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
77
|
+
public static void EmitComponentTargeted<TMessage>(this ref TMessage message, UnityEngine.Component target, IMessageBus messageBus = null) where TMessage : struct, ITargetedMessage
|
|
78
|
+
{
|
|
79
|
+
InstanceId targetId = target;
|
|
80
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
81
|
+
if (typeof(TMessage) != message.MessageType)
|
|
82
|
+
{
|
|
83
|
+
messageBus.UntypedTargetedBroadcast(targetId, message);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
messageBus.TargetedBroadcast(ref targetId, ref message);
|
|
88
|
+
}
|
|
89
|
+
#endif
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/// <summary>
|
|
93
|
+
/// Emits a TargetedMessage of the given type.
|
|
94
|
+
/// </summary>
|
|
95
|
+
/// <param name="message">TargetedMessage to emit.</param>
|
|
96
|
+
/// <param name="target">Target that this message is intended for.</param>
|
|
97
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
98
|
+
public static void EmitTargeted<TMessage>(this TMessage message, InstanceId target, IMessageBus messageBus = null) where TMessage : class, ITargetedMessage
|
|
99
|
+
{
|
|
100
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
101
|
+
if (typeof(TMessage) != message.MessageType)
|
|
102
|
+
{
|
|
103
|
+
messageBus.UntypedTargetedBroadcast(target, message);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
messageBus.TargetedBroadcast(ref target, ref message);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/// <summary>
|
|
111
|
+
/// Emits a TargetedMessage of the given type.
|
|
112
|
+
/// </summary>
|
|
113
|
+
/// <param name="message">TargetedMessage to emit.</param>
|
|
114
|
+
/// <param name="target">Target that this message is intended for.</param>
|
|
115
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
116
|
+
public static void EmitTargeted<TMessage>(this ref TMessage message, InstanceId target, IMessageBus messageBus = null) where TMessage : struct, ITargetedMessage
|
|
117
|
+
{
|
|
118
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
119
|
+
if (typeof(TMessage) != message.MessageType)
|
|
120
|
+
{
|
|
121
|
+
messageBus.UntypedTargetedBroadcast(target, message);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
messageBus.TargetedBroadcast(ref target, ref message);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/// <summary>
|
|
129
|
+
/// Emits an UntargetedMessage of the given type.
|
|
130
|
+
/// </summary>
|
|
131
|
+
/// <param name="message">UntargetedMessage to emit.</param>
|
|
132
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
133
|
+
public static void EmitUntargeted<TMessage>(this TMessage message, IMessageBus messageBus = null) where TMessage : class, IUntargetedMessage
|
|
134
|
+
{
|
|
135
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
136
|
+
if (typeof(TMessage) != message.MessageType)
|
|
137
|
+
{
|
|
138
|
+
messageBus.UntypedUntargetedBroadcast(message);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
messageBus.UntargetedBroadcast(ref message);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// <summary>
|
|
146
|
+
/// Emits an UntargetedMessage of the given type.
|
|
147
|
+
/// </summary>
|
|
148
|
+
/// <param name="message">UntargetedMessage to emit.</param>
|
|
149
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
150
|
+
public static void EmitUntargeted<TMessage>(this ref TMessage message, IMessageBus messageBus = null) where TMessage : struct, IUntargetedMessage
|
|
151
|
+
{
|
|
152
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
153
|
+
if (typeof(TMessage) != message.MessageType)
|
|
154
|
+
{
|
|
155
|
+
messageBus.UntypedUntargetedBroadcast(message);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
messageBus.UntargetedBroadcast(ref message);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
#if UNITY_2017_1_OR_NEWER
|
|
163
|
+
/// <summary>
|
|
164
|
+
/// Emits a BroadcastMessage of the given type.
|
|
165
|
+
/// </summary>
|
|
166
|
+
/// <param name="message">BroadcastMessage to emit.</param>
|
|
167
|
+
/// <param name="source">Source of this message.</param>
|
|
168
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
169
|
+
public static void EmitGameObjectBroadcast<TMessage>(this TMessage message, UnityEngine.GameObject source, IMessageBus messageBus = null) where TMessage : class, IBroadcastMessage
|
|
170
|
+
{
|
|
171
|
+
InstanceId sourceId = source;
|
|
172
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
173
|
+
if (typeof(TMessage) != message.MessageType)
|
|
174
|
+
{
|
|
175
|
+
messageBus.UntypedSourcedBroadcast(sourceId, message);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
messageBus.SourcedBroadcast(ref sourceId, ref message);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/// <summary>
|
|
183
|
+
/// Emits a BroadcastMessage of the given type.
|
|
184
|
+
/// </summary>
|
|
185
|
+
/// <param name="message">BroadcastMessage to emit.</param>
|
|
186
|
+
/// <param name="source">Source of this message.</param>
|
|
187
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
188
|
+
public static void EmitGameObjectBroadcast<TMessage>(this ref TMessage message, UnityEngine.GameObject source, IMessageBus messageBus = null) where TMessage : struct, IBroadcastMessage
|
|
189
|
+
{
|
|
190
|
+
InstanceId sourceId = source;
|
|
191
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
192
|
+
if (typeof(TMessage) != message.MessageType)
|
|
193
|
+
{
|
|
194
|
+
messageBus.UntypedSourcedBroadcast(sourceId, message);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
messageBus.SourcedBroadcast(ref sourceId, ref message);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// <summary>
|
|
202
|
+
/// Emits a BroadcastMessage of the given type from the specified component.
|
|
203
|
+
/// </summary>
|
|
204
|
+
/// <param name="message">BroadcastMessage to emit.</param>
|
|
205
|
+
/// <param name="source">Source of this message.</param>
|
|
206
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
207
|
+
public static void EmitComponentBroadcast<TMessage>(this TMessage message, UnityEngine.Component source, IMessageBus messageBus = null) where TMessage : class, IBroadcastMessage
|
|
208
|
+
{
|
|
209
|
+
InstanceId sourceId = source;
|
|
210
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
211
|
+
if (typeof(TMessage) != message.MessageType)
|
|
212
|
+
{
|
|
213
|
+
messageBus.UntypedSourcedBroadcast(sourceId, message);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
messageBus.SourcedBroadcast(ref sourceId, ref message);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/// <summary>
|
|
221
|
+
/// Emits a BroadcastMessage of the given type from the specified component.
|
|
222
|
+
/// </summary>
|
|
223
|
+
/// <param name="message">BroadcastMessage to emit.</param>
|
|
224
|
+
/// <param name="source">Source of this message.</param>
|
|
225
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
226
|
+
public static void EmitComponentBroadcast<TMessage>(this ref TMessage message, UnityEngine.Component source, IMessageBus messageBus = null) where TMessage : struct, IBroadcastMessage
|
|
227
|
+
{
|
|
228
|
+
InstanceId sourceId = source;
|
|
229
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
230
|
+
if (typeof(TMessage) != message.MessageType)
|
|
231
|
+
{
|
|
232
|
+
messageBus.UntypedSourcedBroadcast(sourceId, message);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
messageBus.SourcedBroadcast(ref sourceId, ref message);
|
|
237
|
+
}
|
|
238
|
+
#endif
|
|
239
|
+
/// <summary>
|
|
240
|
+
/// Emits a BroadcastMessage of the given type from the specified component.
|
|
241
|
+
/// </summary>
|
|
242
|
+
/// <param name="message">BroadcastMessage to emit.</param>
|
|
243
|
+
/// <param name="source">Source of this message.</param>
|
|
244
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
245
|
+
public static void EmitBroadcast<TMessage>(this TMessage message, InstanceId source, IMessageBus messageBus = null) where TMessage : class, IBroadcastMessage
|
|
246
|
+
{
|
|
247
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
248
|
+
if (typeof(TMessage) != message.MessageType)
|
|
249
|
+
{
|
|
250
|
+
messageBus.UntypedSourcedBroadcast(source, message);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
messageBus.SourcedBroadcast(ref source, ref message);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/// <summary>
|
|
258
|
+
/// Emits a BroadcastMessage of the given type from the specified component.
|
|
259
|
+
/// </summary>
|
|
260
|
+
/// <param name="message">BroadcastMessage to emit.</param>
|
|
261
|
+
/// <param name="source">Source of this message.</param>
|
|
262
|
+
/// <param name="messageBus">MessageBus to emit to. If null, uses the GlobalMessageBus.</param>
|
|
263
|
+
public static void EmitBroadcast<TMessage>(this ref TMessage message, InstanceId source, IMessageBus messageBus = null) where TMessage : struct, IBroadcastMessage
|
|
264
|
+
{
|
|
265
|
+
messageBus ??= MessageHandler.MessageBus;
|
|
266
|
+
if (typeof(TMessage) != message.MessageType)
|
|
267
|
+
{
|
|
268
|
+
messageBus.UntypedSourcedBroadcast(source, message);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
messageBus.SourcedBroadcast(ref source, ref message);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
namespace DxMessaging.Core
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
|
|
5
|
+
/// <summary>
|
|
6
|
+
/// Common base for all Messaging needs. A common base lets us share some implementation details with type safety.
|
|
7
|
+
/// </summary>
|
|
8
|
+
public interface IMessage
|
|
9
|
+
{
|
|
10
|
+
Type MessageType => GetType();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
namespace DxMessaging.Core
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Runtime.CompilerServices;
|
|
5
|
+
using System.Runtime.Serialization;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// A light abstraction layer over Unity's InstanceId. Meant to uniquely identify a game object.
|
|
9
|
+
/// </summary>
|
|
10
|
+
[Serializable]
|
|
11
|
+
[DataContract]
|
|
12
|
+
public readonly struct InstanceId : IComparable, IComparable<InstanceId>, IEquatable<InstanceId>
|
|
13
|
+
{
|
|
14
|
+
public static readonly InstanceId EmptyId = new(0);
|
|
15
|
+
|
|
16
|
+
[DataMember(Name = "id")]
|
|
17
|
+
private readonly int _id;
|
|
18
|
+
|
|
19
|
+
#if UNITY_2017_1_OR_NEWER
|
|
20
|
+
public UnityEngine.Object Object { get; }
|
|
21
|
+
#endif
|
|
22
|
+
public InstanceId(int id) : this()
|
|
23
|
+
{
|
|
24
|
+
_id = id;
|
|
25
|
+
#if UNITY_2017_1_OR_NEWER
|
|
26
|
+
Object = null;
|
|
27
|
+
#endif
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#if UNITY_2017_1_OR_NEWER
|
|
31
|
+
private InstanceId(UnityEngine.Object @object) : this()
|
|
32
|
+
{
|
|
33
|
+
_id = @object.GetInstanceID();
|
|
34
|
+
Object = @object;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
38
|
+
public static implicit operator InstanceId(UnityEngine.GameObject gameObject)
|
|
39
|
+
{
|
|
40
|
+
if (gameObject == null)
|
|
41
|
+
{
|
|
42
|
+
throw new ArgumentNullException(nameof(gameObject));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return new InstanceId(gameObject);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
49
|
+
public static implicit operator InstanceId(UnityEngine.Component component)
|
|
50
|
+
{
|
|
51
|
+
if (component == null)
|
|
52
|
+
{
|
|
53
|
+
throw new ArgumentNullException(nameof(component));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return new InstanceId(component);
|
|
57
|
+
}
|
|
58
|
+
#endif
|
|
59
|
+
|
|
60
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
61
|
+
public int CompareTo(object rhs)
|
|
62
|
+
{
|
|
63
|
+
if (rhs is InstanceId other)
|
|
64
|
+
{
|
|
65
|
+
return CompareTo(other);
|
|
66
|
+
}
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
71
|
+
public bool Equals(InstanceId other)
|
|
72
|
+
{
|
|
73
|
+
return _id == other._id;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
77
|
+
public override bool Equals(object other)
|
|
78
|
+
{
|
|
79
|
+
return other is InstanceId id && Equals(id);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
83
|
+
public override int GetHashCode()
|
|
84
|
+
{
|
|
85
|
+
return _id;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public override string ToString()
|
|
89
|
+
{
|
|
90
|
+
#if UNITY_2017_1_OR_NEWER
|
|
91
|
+
UnityEngine.Object instance = Object;
|
|
92
|
+
string objectName = instance == null ? string.Empty : instance.name;
|
|
93
|
+
return $"{{\"Id\": {_id}, \"Name\": \"{objectName}\"}}";
|
|
94
|
+
#else
|
|
95
|
+
return $"{{\"Id\": {_id}}}";
|
|
96
|
+
#endif
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
100
|
+
public static bool operator ==(InstanceId lhs, InstanceId rhs)
|
|
101
|
+
{
|
|
102
|
+
return lhs.Equals(rhs);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
106
|
+
public static bool operator !=(InstanceId lhs, InstanceId rhs)
|
|
107
|
+
{
|
|
108
|
+
return !(lhs == rhs);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
112
|
+
public int CompareTo(InstanceId other)
|
|
113
|
+
{
|
|
114
|
+
return _id.CompareTo(other._id);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|