Skip to content

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.