Game.UI.InGame.ChirperUISystem
Assembly:
Namespace: Game.UI.InGame
Type: class
Base: UISystemBase
Summary:
Manages the in-game "Chirper" UI feed. This system gathers Chirp entities, sorts them, exposes them to the UI via bindings/events, handles user-triggered actions (like/unlike, selecting links), and resolves sender/link metadata (names, avatars, links). It uses several other systems (PrefabSystem, NameSystem, ChirpLinkSystem, etc.), maintains EntityQueries to watch chirp creation/changes, and publishes JSON-compatible chirp objects to the UI layer. This system is intended for use in the main Entity World and is designed to be called from the UI binding infrastructure.
Fields
-
private struct ChirpComparer : IComparer<Entity>
Comparer used to sort chirps by creation frame (newest first) and then by Entity id to produce a stable order. -
private const string kGroup = "chirper"
Internal constant group name used for bindings (informational). -
private const int kBrandIconSize = 32
Icon size used when generating brand thumbnail URLs. -
private PrefabSystem m_PrefabSystem
Reference to PrefabSystem used to resolve Prefab and InfoView data (avatars, localization, etc.). -
private SelectedInfoUISystem m_SelectedInfoUISystem
Reference used to focus/select entities in the selected-info UI. -
private InfoviewsUISystem m_InfoviewsUISystem
Reference used to activate infoviews for Chirper account links. -
private ChirpLinkSystem m_ChirpLinkSystem
Reference used for cached chirp/link data when linked entities are deleted. -
private NameSystem m_NameSystem
Reference used to resolve/display names for entities and links. -
private EntityQuery m_ChirpQuery
EntityQuery selecting active Chirp entities with RandomLocalizationIndex and PrefabRef and excluding Deleted/Temp. Used for full chirp lists. -
private EntityQuery m_ModifiedChirpQuery
EntityQuery used to detect changed chirps (has Chirp + PrefabRef; change/version filters applied). Used to update UI when chirps change. -
private EntityQuery m_CreatedChirpQuery
EntityQuery selecting newly created Chirp entities (includes Created component) and excluding Deleted/Temp. Used to publish chirp-added events. -
private EntityQuery m_TimeDataQuery
EntityQuery used to access TimeData singleton for computing ticks/date. -
private EndFrameBarrier m_EndFrameBarrier
Used to create command buffers to apply component changes (e.g., toggling likes) at end of frame. -
private RawValueBinding m_ChirpsBinding
Value binding registered as ("chirper", "chirps") that writes the current chirp list to UI when requested. -
private RawEventBinding m_ChirpAddedBinding
Event binding registered as ("chirper", "chirpAdded") used to emit newly created chirps as events to the UI.
Properties
- None (this type exposes no public properties).
Constructors
public ChirperUISystem()
Default constructor. The system initializes references and bindings in OnCreate. There is no custom construction logic beyond that.
Methods
protected override void OnCreate()
Initializes the system: acquires references to required systems (PrefabSystem, SelectedInfoUISystem, InfoviewsUISystem, ChirpLinkSystem, NameSystem), sets up EntityQueries (chirp, modified chirp, created chirp, time data), creates reference to EndFrameBarrier, and registers UI bindings:- RawValueBinding("chirper", "chirps", UpdateChirps)
- RawEventBinding("chirper", "chirpAdded")
- TriggerBinding
("chirper", "addLike", AddLike) - TriggerBinding
("chirper", "removeLike", RemoveLike) -
TriggerBinding
("chirper", "selectLink", SelectLink) Notes: the modified query has an order/version filter and a changed-version filter for the Chirp component. -
protected override void OnUpdate()
Runs each frame (system update). Behavior: - If m_ModifiedChirpQuery is not empty: calls m_ChirpsBinding.Update() to refresh UI list.
-
If m_ChirpAddedBinding is active and m_CreatedChirpQuery is not empty (ignoring filters): calls PublishAddedChirps() to fire chirp-added events. This keeps UI synchronized with entity changes.
-
private void AddLike(Entity entity)
Marks the specified Chirp entity as Liked by setting the Chirp.m_Flags |= ChirpFlags.Liked, then schedules the component update and an Updated marker using an EntityCommandBuffer created from m_EndFrameBarrier. Use the system's bindings (trigger "addLike") to invoke from UI. Changes are applied at end of frame. -
private void RemoveLike(Entity entity)
Removes the Liked flag from the Chirp (m_Flags &= ~ChirpFlags.Liked) and schedules the updated component and Updated tag via an EndFrameBarrier command buffer. -
private void SelectLink(string target)
Parses a UI link string: - If it parses as an entity URI and the entity exists => selects and focuses it in SelectedInfoUISystem.
-
If it parses as an infoview URI and entity exists => sets that infoview active in InfoviewsUISystem. Used by the UI trigger "selectLink".
-
private void UpdateChirps(IJsonWriter binder)
Called by the "chirps" binding to write the current chirp list. It: - Gets sorted chirps via GetSortedChirps(m_ChirpQuery).
-
Writes an array and binds each chirp using BindChirp. Note: allocates a temporary NativeArray
which must be disposed by the caller of ToEntityArray; this method returns it in a local and relies on its allocator (it returns the array and iterates it before exiting). -
private void PublishAddedChirps()
Called to emit events for newly created chirps. It: - Gets sorted chirps via GetSortedChirps(m_CreatedChirpQuery).
-
For each entity calls m_ChirpAddedBinding.EventBegin(), BindChirp(..., newChirp: true), EventEnd(). Also triggers Telemetry.Chirp for new chirps whose sender is a ChirperAccount.
-
private NativeArray<Entity> GetSortedChirps(EntityQuery chirpQuery)
Retrieves entities matching chirpQuery into a temporary NativeArray(Allocator.Temp), sorts it using ChirpComparer (newest first), and returns it. The returned NativeArray is allocated with Allocator.Temp and must be used immediately (no long-term storage). -
public void BindChirp(IJsonWriter binder, Entity chirpEntity, bool newChirp = false)
Writes a chirp object to IJsonWriter with structure "chirper.Chirp", including: - entity (Entity)
- sender (chirp sender object via BindChirpSender)
- optionally emits telemetry for newChirp when sender has ChirperAccountData
- date (ticks computed from Chirp.m_CreationFrame)
- messageId (via GetMessageID)
- links (array of links resolved from ChirpEntity buffer via BindChirpLink)
- likes (like count)
-
liked (bool derived from Chirp.m_Flags) This is the main JSON representation used by the UI.
-
public string GetMessageID(Entity chirp)
Resolves a localization message id for the chirp: - Reads PrefabRef and RandomLocalizationIndex buffer on the chirp entity
- Resolves PrefabBase from PrefabSystem and tries to get RandomLocalization component
-
Returns LocalizationUtils.AppendIndex(localizationID, buffer[0]) if successful; otherwise returns empty string.
-
private void BindChirpSender(IJsonWriter binder, Entity entity)
Writes the chirp sender representation ("chirper.ChirpSender"): - If Chirp.m_Sender exists as an entity: writes the entity and a link produced by BindChirpLink (using NameSystem.GetName).
- Else if ChirpLinkSystem has cached data for the chirp entity: writes cached sender entity and link (name from cache).
-
Otherwise writes Entity.Null and an empty custom name. This handles cases where the sender entity has been deleted.
-
private void BindChirpLink(IJsonWriter binder, Entity entity, int linkIndex)
Helper that reads the ChirpEntity buffer from entity and chooses appropriate link: - If target entity in buffer exists => binds link with that entity and its name (omitting brand for name resolution).
- Else if ChirpLinkSystem cached data exists for the chirp and contains a link at linkIndex => binds using cached name.
-
Otherwise binds an empty custom name. Delegates final serialization to BindChirpLink(IJsonWriter, Entity, NameSystem.Name).
-
public void BindChirpLink(IJsonWriter binder, Entity entity, NameSystem.Name name)
Writes a "chirper.ChirpLink" with: - name (NameSystem.Name)
-
target (string URI). Target resolution rules:
- If entity has CompanyData and PropertyRenter -> uses the property entity (renter -> property).
- If entity != Entity.Null => URI.FromEntity(entity).
- If entity has ChirperAccountData => resolves InfoView uri via prefab => URI.FromInfoView.
- If null => empty string. Useful for creating clickable UI links that point to entities or infoviews.
-
private string GetAvatar(Entity chirpEntity)
Attempts to find an avatar icon for the chirp sender: - Resolves sender entity, maps CompanyData -> brand entity if present.
- Reads PrefabData and asks PrefabSystem for the prefab.
- Attempts ImageSystem.GetIcon(prefab); if present returns that.
- If prefab is ChirperAccount with InfoView -> returns infoView.m_IconPath.
-
If prefab is BrandPrefab -> returns brand thumbnail URL with size parameters (uses kBrandIconSize). Returns null if no avatar could be resolved.
-
private int GetRandomIndex(Entity chirpEntity)
Attempts to read a RandomLocalizationIndex buffer from the chirp's sender entity and return its first index. Returns 0 if unavailable. Used to resolve random localizations where needed. -
private uint GetTicks(uint frameIndex)
Converts a frame index into tick count relative to game start by subtracting TimeData.m_FirstFrame (reads singleton via m_TimeDataQuery). -
ChirpComparer:
public ChirpComparer(EntityManager entityManager)
constructor accepts EntityManager used for comparing Chirp components.public int Compare(Entity a, Entity b)
compares chirps by Chirp.m_CreationFrame (descending), then by Entity as tie-breaker.
Usage Example
// Example: Access the system and produce JSON for a single chirp entity.
// Assumes 'world' is your World instance and 'chirpEntity' is a valid Chirp entity.
var chirperSystem = world.GetOrCreateSystemManaged<Game.UI.InGame.ChirperUISystem>();
// IJsonWriter is an interface used by the UI binding layer. For testing/integration
// you can implement a simple writer or use the game's writer implementation.
IJsonWriter writer = new SimpleJsonWriter(); // placeholder: implement IJsonWriter
// Bind a chirp into the writer (not necessarily a newly created chirp)
chirperSystem.BindChirp(writer, chirpEntity);
// Alternatively, UI triggers are already registered by the system:
// - Trigger "chirper:addLike" with an Entity to like a chirp
// - Trigger "chirper:removeLike" with an Entity to remove like
// - Trigger "chirper:selectLink" with a URI string to select/focus an entity or infoview
Notes for modders: - The system relies heavily on Entity queries and other world-managed systems — avoid calling internal/private methods directly unless you understand Entity lifetimes. - BindChirp and BindChirpLink produce JSON structures expected by the UI; if extending chirp data for a mod, ensure the UI processing side is updated accordingly. - AddLike/RemoveLike use an EndFrameBarrier command buffer to safely mutate components; do not try to SetComponent directly from UI callbacks without using a command buffer. - GetSortedChirps returns a NativeArray allocated with Allocator.Temp; callers should use it immediately and not store it beyond the current frame.