You are viewing documentation for v1.1. Switch to current version →

⚙️ CommonUI Technical Deep-Dive

Short Description

A technical overview of the interface-driven, flyweight-processor architecture behind the CommonUI Foundation.

Long Description

The CommonUI Foundation decouples UI logic from widget assets using a "Processor" pattern. This allows the core C++ systems to manage state, theming, and input across a wide variety of widget types (Standard UMG, CommonUI, or custom Slate) without requiring them to inherit from a specific base class. Instead, widgets simply implement the IGorgeousUIWidget_I interface to become "system-aware."

🏗️ Core Architecture

The system operates as a triangle between the Subsystem, the Shared Processors, and the Widget Instances.

graph TD
    subgraph "Core Infrastructure"
        Subsystem["UGorgeousUIFoundationSubsystem"]
        Registry["Processor Registry"]
    end

    subgraph "Logic Layer (Flyweights)"
        P_Button["Button Processor"]
        P_Text["Text Processor"]
        P_Progress["Progress Processor"]
    end

    subgraph "Visual Layer (Widgets)"
        W1["Confirm Button (UMG)"]
        W2["Health Bar (CommonUI)"]
        W3["Title Text (Slate)"]
    end

    Subsystem --> Registry
    Registry --> P_Button
    Registry --> P_Text
    Registry --> P_Progress

    P_Button -.->|Applies Logic| W1
    P_Progress -.->|Applies Logic| W2
    P_Text -.->|Applies Logic| W3

    W1 -->|Registers| Subsystem
    W2 -->|Registers| Subsystem
    W3 -->|Registers| Subsystem

1. The Flyweight Processor Pattern

Unlike traditional architectures where logic lives inside the widget class, Gorgeous Things uses Flyweight Processors.

  • Singleton Instance: Only one instance of UGorgeousButtonProcessor exists for the entire game.
  • Stateless Execution: The processor does not store widget data. Every function (e.g., OnSignalReceived) receives the specific widget pointer as an argument.
  • Decoupling: This allows the same logic to be applied to different widget classes as long as they provide the same properties or functions.

2. Interface-Driven Registration

Any object can participate in the UI system by implementing IGorgeousUIWidget_I.

  • Binding Tag: Defines what "type" of data this widget cares about (e.g., UI.Element.Health).
  • Routing ID: Optional identifier for disambiguation (e.g., Slot_0).
  • Registration: When a widget is initialized, it registers itself with the UGorgeousUIFoundationSubsystem. The subsystem then looks up the appropriate Processor based on the widget's class.

🔄 State Transition Lifecycle

The Subsystem manages global UI states (Combat, Menu, Inventory) via a coordinated transition handshake.

  1. State Request: SwitchUIState is called with a new UGorgeousUIState_DA.
  2. Started Event: OnTransitionStarted is broadcast. Widgets use this to trigger Outro animations.
  3. Transitioning: The Subsystem tracks all widgets that are currently "Transitioning."
  4. Ready Handshake: As widgets finish their animations, they call NotifyWidgetTransitionComplete.
  5. State Swap: Once all registered widgets are ready, the Subsystem performs the actual swap:
    • Pushes new Input Mapping Contexts.
    • Applies the state's specific Theme (if any).
    • Updates Overlay configurations.
  6. Finished Event: OnTransitionFinished is broadcast. Widgets use this to trigger Intro animations.

📡 Signal Bridge Integration

The UI system is a primary consumer of the Signal Bridge.

  • Global Listeners: The Subsystem listens for global signals like UI.Signal.FocusRequest or UI.Signal.Message.
  • Targeted Routing: Signals can be routed to specific widgets using their Binding Tag and Routing ID.
  • Payload Unpacking: Processors use reflection to automatically map signal payloads to widget properties.

⌨️ Input Bridging

The system bridges Enhanced Input to the UI using a Tag-based approach.

  • Input Bindings: UGorgeousInputBinding_DA maps Input Actions to Gameplay Tags (e.g., IA_Confirm -> UI.Action.Confirm).
  • State-Aware Input: Each UI State can push its own Mapping Contexts and Bindings.
  • Device Agnostic: The system detects the active input device (Gamepad vs. Keyboard) and notifies the Theme system to swap icon brushes automatically.