Game.Triggers.RadioTagSystem
Assembly: Game
Namespace: Game.Triggers
Type: class
Base: GameSystemBase
Summary:
RadioTagSystem collects, buffers and deduplicates radio event tags produced by game code (usually from jobs). It maintains separate queues for normal and emergency radio tags, a buffer of recent events per radio segment type, and a RecentTags map to prevent the same event from being replaying too frequently. The system integrates with Unity job dependencies (JobHandle) so producers running in jobs can safely enqueue radio tags and report dependencies back to the system. It is enabled only in game mode and clears/disposes its native containers when stopped or destroyed.
Fields
-
private static readonly int kFrameDelay = 50000
Default minimum frame delay between repeated non-emergency events for the same event tag (used with m_RecentTags). -
private static readonly int kMaxBufferSize = 10
Maximum number of buffered RadioTag entries kept per Radio.SegmentType. Older entries are removed when the buffer exceeds this size. -
private NativeParallelHashMap<Entity, uint> m_RecentTags
Map of recent event Entity -> frameIndex when the event was last accepted. Used to deduplicate/reject rapid repeats. -
private NativeQueue<RadioTag> m_InputQueue
Native queue for regular (non-emergency) radio tags written by producers (jobs or main thread). Producers should use GetInputQueue to obtain this queue and report their JobHandle via AddInputQueueWriter. -
private NativeQueue<RadioTag> m_EmergencyInputQueue
Native queue for emergency radio tags written by producers. Emergency tags are subject to their own EmergencyFrameDelay per tag. -
private NativeQueue<RadioTag> m_EmergencyQueue
Native queue of emergency tags that have passed deduplication and are ready for immediate consumption by consumers. -
private Dictionary<Radio.SegmentType, List<RadioTag>> m_Events
Managed dictionary that stores buffered lists of radio events organized by Radio.SegmentType. -
private JobHandle m_InputDependencies
Combined JobHandle representing dependencies of all producers that write to m_InputQueue. Completed at the beginning of OnUpdate to ensure producers finished. -
private JobHandle m_EmergencyInputDependencies
Combined JobHandle for producers that write m_EmergencyInputQueue. -
private JobHandle m_EmergencyDependencies
Combined JobHandle for producers that write m_EmergencyQueue. -
private SimulationSystem m_SimulationSystem
Reference to the simulation system, used to get the current frameIndex for deduplication logic.
Properties
- (none public)
This system exposes no public get/set properties. Interaction is done via the provided GetQueue and AddWriter methods. Internally it stores JobHandle dependency fields (m_InputDependencies, m_EmergencyInputDependencies, m_EmergencyDependencies).
Constructors
public RadioTagSystem()
Default constructor. The system performs the bulk of initialization in OnCreate.
Methods
-
protected virtual OnCreate() : System.Void
Initializes native queues and the recent-tags map, retrieves the SimulationSystem, creates the events dictionary, and disables the system by default (base.Enabled = false). Allocates NativeQueue and NativeParallelHashMap with Allocator.Persistent. -
protected override void OnGamePreload(Purpose purpose, GameMode mode)
Enables or disables the system based on the provided GameMode. The system is enabled when mode.IsGame() is true. -
protected override void OnUpdate()
Main update that: - Completes input and emergency input dependency JobHandles so it can safely read and dequeue from native queues.
- Drains m_InputQueue and, per RadioTag, checks m_RecentTags to enforce kFrameDelay deduplication. If accepted, the tag is inserted into the buffer list for its Radio.SegmentType and trimmed to kMaxBufferSize.
-
Drains m_EmergencyInputQueue and enqueues (to m_EmergencyQueue) only those emergency tags that pass their EmergencyFrameDelay check against m_RecentTags. This method is where native queue data is transferred into managed buffers for consumption by other systems.
-
private List<RadioTag> EnsureList(Radio.SegmentType segmentType)
Helper that ensures a Listexists for the given segment type in m_Events and returns it. -
protected override void OnStopRunning()
Called when the system stops running; clears all buffers and dependencies via Clear(). -
protected override void OnDestroy()
Disposes NativeQueue and NativeParallelHashMap containers (m_InputQueue, m_EmergencyInputQueue, m_EmergencyQueue, m_RecentTags) and calls base.OnDestroy(). -
public bool TryPopEvent(Radio.SegmentType segmentType, bool newestFirst, out RadioTag radioTag)
Attempts to pop a buffered radio event for the given segment type. If newestFirst is true, the most recent buffered entry is returned; otherwise the oldest is returned. Returns true if an event was available. On false, out param is default(RadioTag). -
public void FlushEvents(Radio.SegmentType segmentType)
Clears the buffered events list for the given segment type. -
public NativeQueue<RadioTag> GetInputQueue(out JobHandle deps)
Returns the input queue that producers should write to and outputs the current combined dependency (deps). Asserts that the system is Enabled (writing not allowed when disabled). Producers should combine their job handles via AddInputQueueWriter after scheduling any job that writes to this queue. -
public NativeQueue<RadioTag> GetEmergencyInputQueue(out JobHandle deps)
Returns the emergency input queue and its current dependency JobHandle. Same enabled assertion applies. -
public NativeQueue<RadioTag> GetEmergencyQueue(out JobHandle deps)
Returns the emergency (ready) queue and its dependency JobHandle. -
public void AddInputQueueWriter(JobHandle handle)
Combine the provided JobHandle with internal m_InputDependencies. Call this from code that schedules jobs which write to the queue so the system can wait for them before dequeuing. -
public void AddEmergencyInputQueueWriter(JobHandle handle)
Combines a job handle into m_EmergencyInputDependencies. -
protected override void OnGameLoaded(Context serializationContext)
Called after game load; clears queues and buffers to ensure a clean state. -
private void Clear()
Completes dependency JobHandles and clears all native queues, the recent tags map and the managed events dictionary. Used on stop, on reload, and on load to reset system state.
Usage Example
// Example: Enqueue a RadioTag from a non-job (main thread) producer
// Ensure the RadioTagSystem is running (enabled) before calling GetInputQueue.
var radioSystem = World.GetExistingSystemManaged<Game.Triggers.RadioTagSystem>();
JobHandle deps;
var inputQueue = radioSystem.GetInputQueue(out deps);
// If called from main thread, you can write directly:
inputQueue.Enqueue(new RadioTag {
m_Event = someEntity,
m_SegmentType = Radio.SegmentType.SomeSegment,
m_EmergencyFrameDelay = 0u,
// ...other RadioTag fields...
});
// If you scheduled a job that writes to the queue, after scheduling it:
// radioSystem.AddInputQueueWriter(yourJobHandle);
// Consumers can pop buffered events:
RadioTag tag;
if (radioSystem.TryPopEvent(Radio.SegmentType.SomeSegment, newestFirst: true, out tag))
{
// process tag
}
Additional notes: - RadioTag and Radio.SegmentType are defined in Game.Audio.Radio. RadioTag contains m_Event (Entity), m_SegmentType and m_EmergencyFrameDelay among other fields. - Thread-safety: producers running in jobs must use the NativeQueue returned by GetInputQueue/GetEmergencyInputQueue and must report job dependencies via AddInputQueueWriter/AddEmergencyInputQueueWriter. The system completes those JobHandles in OnUpdate to safely drain the queues on the main thread. - Deduplication: m_RecentTags maps the event Entity to a frame index so repeated events are suppressed until the configured frame delay (kFrameDelay for normal tags or the tag's m_EmergencyFrameDelay for emergency tags) has passed. The system uses SimulationSystem.frameIndex for timing. - The system disables itself outside of game mode; writing to queues while disabled will assert.