com.wallstop-studios.dxmessaging 2.1.8 → 2.2.0

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/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.2.0]
11
+
12
+ ### Fixed
13
+
14
+ - Fixed a bug where no messages would get received by any listeners due to specifics in Unity play mode timings
15
+
10
16
  ## [2.1.8]
11
17
 
12
18
  ### Fixed
@@ -26,7 +26,7 @@ namespace DxMessaging.Editor
26
26
  {
27
27
  if (
28
28
  stateChange == PlayModeStateChange.EnteredEditMode
29
- || stateChange == PlayModeStateChange.EnteredPlayMode
29
+ || stateChange == PlayModeStateChange.ExitingEditMode
30
30
  )
31
31
  {
32
32
  ApplyEditorSettings();
@@ -1,12 +1,25 @@
1
1
  namespace DxMessaging.Core
2
2
  {
3
3
  using System;
4
- using Helper;
5
4
  using MessageBus;
6
5
 
7
6
  /// <summary>
8
7
  /// Centralised utility for resetting DxMessaging static state when Domain Reload is disabled.
9
8
  /// </summary>
9
+ /// <remarks>
10
+ /// <para>
11
+ /// This class is designed for Unity's Enter Play Mode Settings with Domain Reload disabled.
12
+ /// When Domain Reload is disabled, static fields persist between play mode sessions, which
13
+ /// can cause issues if stale state is not cleared.
14
+ /// </para>
15
+ /// <para>
16
+ /// <strong>Important:</strong> Message type sequential IDs (managed by MessageHelperIndexer)
17
+ /// are intentionally NOT reset. Once a message type is assigned an ID, it retains that ID
18
+ /// for the lifetime of the application domain. This prevents ID collisions that would occur
19
+ /// if a new message type were assigned an ID that was previously used by a different type.
20
+ /// Resetting IDs could cause messages to be routed to the wrong handlers.
21
+ /// </para>
22
+ /// </remarks>
10
23
  public static class DxMessagingStaticState
11
24
  {
12
25
  private static readonly object ResetLock = new object();
@@ -20,6 +33,9 @@ namespace DxMessaging.Core
20
33
  /// <summary>
21
34
  /// Resets all static variables in DxMessaging to their default values.
22
35
  /// </summary>
36
+ /// <remarks>
37
+ /// Message type IDs are NOT reset by this method. See the class remarks for details.
38
+ /// </remarks>
23
39
  public static void Reset()
24
40
  {
25
41
  lock (ResetLock)
@@ -31,13 +47,10 @@ namespace DxMessaging.Core
31
47
  IMessageBus.GlobalMessageBufferSize = Baseline.GlobalMessageBufferSize;
32
48
  IMessageBus.GlobalSequentialIndex = Baseline.GlobalSequentialIndex;
33
49
 
34
- MessageHelperIndexer.RestoreState(Baseline.HelperState);
35
-
36
50
  MessageRegistrationHandle.SetIdSeed(Baseline.MessageRegistrationHandleSeed);
37
51
  MessageRegistrationBuilder.SetSyntheticOwnerCounter(Baseline.SyntheticOwnerCounter);
38
52
 
39
53
  MessageHandler.ResetStatics();
40
- IMessageBus.GlobalSequentialIndex = Baseline.GlobalSequentialIndex;
41
54
  }
42
55
  }
43
56
 
@@ -50,8 +63,6 @@ namespace DxMessaging.Core
50
63
  int globalSequentialIndex = IMessageBus.GlobalSequentialIndex;
51
64
  long messageRegistrationHandleSeed = MessageRegistrationHandle.GetCurrentIdSeed();
52
65
  int syntheticOwnerCounter = MessageRegistrationBuilder.GetSyntheticOwnerCounter();
53
- MessageHelperIndexer.MessageHelperIndexerState helperState =
54
- MessageHelperIndexer.CaptureState();
55
66
 
56
67
  return new BaselineState(
57
68
  messagingDebugEnabled,
@@ -60,8 +71,7 @@ namespace DxMessaging.Core
60
71
  globalMessageBufferSize,
61
72
  globalSequentialIndex,
62
73
  messageRegistrationHandleSeed,
63
- syntheticOwnerCounter,
64
- helperState
74
+ syntheticOwnerCounter
65
75
  );
66
76
  }
67
77
 
@@ -74,8 +84,7 @@ namespace DxMessaging.Core
74
84
  int globalMessageBufferSize,
75
85
  int globalSequentialIndex,
76
86
  long messageRegistrationHandleSeed,
77
- int syntheticOwnerCounter,
78
- MessageHelperIndexer.MessageHelperIndexerState helperState
87
+ int syntheticOwnerCounter
79
88
  )
80
89
  {
81
90
  MessagingDebugEnabled = messagingDebugEnabled;
@@ -85,7 +94,6 @@ namespace DxMessaging.Core
85
94
  GlobalSequentialIndex = globalSequentialIndex;
86
95
  MessageRegistrationHandleSeed = messageRegistrationHandleSeed;
87
96
  SyntheticOwnerCounter = syntheticOwnerCounter;
88
- HelperState = helperState;
89
97
  }
90
98
 
91
99
  internal bool MessagingDebugEnabled { get; }
@@ -101,8 +109,6 @@ namespace DxMessaging.Core
101
109
  internal long MessageRegistrationHandleSeed { get; }
102
110
 
103
111
  internal int SyntheticOwnerCounter { get; }
104
-
105
- internal MessageHelperIndexer.MessageHelperIndexerState HelperState { get; }
106
112
  }
107
113
  }
108
114
  }
@@ -1,80 +1,22 @@
1
1
  namespace DxMessaging.Core.Helper
2
2
  {
3
- using System;
4
- using System.Collections.Generic;
5
-
3
+ /// <summary>
4
+ /// Provides sequential ID assignment for message types.
5
+ /// </summary>
6
+ /// <remarks>
7
+ /// Message type IDs are intentionally NOT reset during static state reset operations.
8
+ /// Once a message type is assigned an ID, it retains that ID for the lifetime of the
9
+ /// application domain. This design prevents ID collisions and ensures message routing
10
+ /// stability across reset cycles (e.g., when using Enter Play Mode Settings with
11
+ /// Domain Reload disabled in Unity).
12
+ /// </remarks>
6
13
  public static class MessageHelperIndexer
7
14
  {
8
- internal readonly struct MessageHelperIndexerState
9
- {
10
- internal readonly int _totalMessages;
11
-
12
- internal readonly Dictionary<Type, int> _sequentialIds;
13
-
14
- internal MessageHelperIndexerState(
15
- int totalMessages,
16
- Dictionary<Type, int> sequentialIds
17
- )
18
- {
19
- _totalMessages = totalMessages;
20
- _sequentialIds = sequentialIds;
21
- }
22
- }
23
-
24
- private static readonly object ResetLock = new();
25
- private static readonly HashSet<Type> RegisteredTypes = new();
26
- private static readonly Dictionary<Type, Func<int, int>> StateManipulationByType = new();
27
-
15
+ /// <summary>
16
+ /// The total number of message types that have been assigned sequential IDs.
17
+ /// This counter only increases and is never reset.
18
+ /// </summary>
28
19
  internal static int TotalMessages = 0;
29
-
30
- internal static void RegisterType(Type messageType, Func<int, int> idProducer)
31
- {
32
- if (messageType == null)
33
- {
34
- return;
35
- }
36
-
37
- lock (ResetLock)
38
- {
39
- if (!RegisteredTypes.Add(messageType))
40
- {
41
- return;
42
- }
43
-
44
- StateManipulationByType[messageType] = idProducer;
45
- }
46
- }
47
-
48
- internal static MessageHelperIndexerState CaptureState()
49
- {
50
- lock (ResetLock)
51
- {
52
- Dictionary<Type, int> snapshot = new(RegisteredTypes.Count);
53
- return new MessageHelperIndexerState(TotalMessages, snapshot);
54
- }
55
- }
56
-
57
- internal static void RestoreState(MessageHelperIndexerState state)
58
- {
59
- lock (ResetLock)
60
- {
61
- TotalMessages = state._totalMessages;
62
- foreach (KeyValuePair<Type, Func<int, int>> entry in StateManipulationByType)
63
- {
64
- Type type = entry.Key;
65
- Func<int, int> manipulationAction = entry.Value;
66
- if (
67
- state._sequentialIds == null
68
- || !state._sequentialIds.TryGetValue(type, out int value)
69
- )
70
- {
71
- value = -1;
72
- }
73
-
74
- manipulationAction(value);
75
- }
76
- }
77
- }
78
20
  }
79
21
 
80
22
  public static class MessageHelperIndexer<TMessage>
@@ -82,10 +24,5 @@ namespace DxMessaging.Core.Helper
82
24
  {
83
25
  // ReSharper disable once StaticMemberInGenericType
84
26
  internal static int SequentialId = -1;
85
-
86
- static MessageHelperIndexer()
87
- {
88
- MessageHelperIndexer.RegisterType(typeof(TMessage), value => SequentialId = value);
89
- }
90
27
  }
91
28
  }
@@ -282,11 +282,6 @@ namespace DxMessaging.Core.MessageBus
282
282
  _ = Interlocked.Exchange(ref _syntheticOwnerCounter, value);
283
283
  }
284
284
 
285
- internal static void ResetSyntheticOwnerCounter()
286
- {
287
- SetSyntheticOwnerCounter(0);
288
- }
289
-
290
285
  /// <summary>
291
286
  /// Initializes a builder that resolves buses from global state.
292
287
  /// </summary>
@@ -29,11 +29,6 @@ namespace DxMessaging.Core
29
29
  _ = Interlocked.Exchange(ref StaticIdCount, value);
30
30
  }
31
31
 
32
- internal static void ResetIdSeed()
33
- {
34
- SetIdSeed(0);
35
- }
36
-
37
32
  /// <summary>
38
33
  /// Creates a new unique handle.
39
34
  /// </summary>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.dxmessaging",
3
- "version": "2.1.8",
3
+ "version": "2.2.0",
4
4
  "displayName": "DxMessaging",
5
5
  "description": "Synchronous Event Bus for Unity",
6
6
  "unity": "2021.3",