// Toasts/Components/AC_ToastSystem.ts import type { S_ToastMessage } from '#root/Toasts/Structs/S_ToastMessage.ts'; import type { S_ToastSettings } from '#root/Toasts/Structs/S_ToastSettings.ts'; import type { WBP_Toast } from '#root/Toasts/UI/WBP_Toast.ts'; import { WBP_ToastContainer } from '#root/Toasts/UI/WBP_ToastContainer.ts'; import { ActorComponent } from '#root/UE/ActorComponent.ts'; import { CreateWidget } from '#root/UE/CteateWidget.ts'; import type { Float } from '#root/UE/Float.ts'; import type { Integer } from '#root/UE/Integer.ts'; import { SystemLibrary } from '#root/UE/SystemLibrary.ts'; import type { Text } from '#root/UE/Text.ts'; import { UEArray } from '#root/UE/UEArray.ts'; import { E_MessageType } from '#root/UI/Enums/E_MessageType.ts'; /** * Toast Notification System Component * Manages temporary status messages with automatic positioning and lifecycle * Provides visual feedback for debug operations and system events */ export class AC_ToastSystem extends ActorComponent { // ════════════════════════════════════════════════════════════════════════════════════════ // FUNCTIONS // ════════════════════════════════════════════════════════════════════════════════════════ /** * Check if toast system should process updates this frame * @returns True if system is initialized and enabled * @pure * @category Toast Management */ private ShouldProcessToasts(): boolean { /** * Validate system state and settings */ const function1 = (isEnabled: boolean): boolean => this.IsInitialized && isEnabled; return function1(this.ToastSettings.IsEnabled); } /** * Remove expired toasts from the system * @category Toast Lifecycle */ private RemoveExpiredToasts(): void { let i = 0; /** * Check if there are more toasts to process */ const HasMoreToastsToCheck = (activeToastsLength: Integer): boolean => i < activeToastsLength; while (HasMoreToastsToCheck(this.ActiveToasts.length)) { /** * Check if toast has exceeded its display duration */ const IsToastExpired = ( currentTime: Float, createdTime: Float, duration: Float ): boolean => currentTime - createdTime > duration; const el = this.ActiveToasts.Get(i); if ( IsToastExpired( SystemLibrary.GetGameTimeInSeconds(), el.CreatedTime, el.Duration ) ) { const widget = this.ToastWidgets.Get(i); if (SystemLibrary.IsValid(widget)) { if (SystemLibrary.IsValid(this.ToastContainer)) { this.ToastContainer.RemoveToast(widget); } } this.ActiveToasts.RemoveIndex(i); this.ToastWidgets.RemoveIndex(i); } else { i++; } } } /** * Enforce maximum visible toasts limit * Removes oldest toasts when limit is exceeded * @category Toast Lifecycle */ private EnforceToastLimit(): void { /** * Check if current toast count exceeds maximum allowed */ const ExceedsToastLimit = ( activeToastsLength: Integer, maxVisibleToasts: Integer ): boolean => activeToastsLength >= maxVisibleToasts; while ( ExceedsToastLimit( this.ActiveToasts.length, this.ToastSettings.MaxVisibleToasts ) ) { const widget = this.ToastWidgets.Get(0); if (SystemLibrary.IsValid(widget)) { if (SystemLibrary.IsValid(this.ToastContainer)) { this.ToastContainer.RemoveToast(widget); } } this.ActiveToasts.RemoveIndex(0); this.ToastWidgets.RemoveIndex(0); } } /** * Create and display a new toast message * @param Message - Text to display in the toast * @param Type - Type of toast (affects color and styling) * @param Duration - How long to display toast (optional, uses default) * @returns Toast ID for tracking * @example * // Create success toast * ShowToast("Test passed!", E_MessageType.Success, 2.0) * // Create error toast with default duration * ShowToast("Test failed!", E_MessageType.Error) * @category Toast Creation */ public ShowToast( Message: Text = '', Type: E_MessageType = E_MessageType.Info, Duration: Float = 0 ): Integer { if (this.ShouldProcessToasts()) { const toastDuration = Duration !== 0 ? Duration : this.ToastSettings.DefaultDuration; const currentTime = SystemLibrary.GetGameTimeInSeconds(); const newToast: S_ToastMessage = { ID: this.NextToastID++, Message, Type, Duration: toastDuration, CreatedTime: currentTime, }; this.EnforceToastLimit(); if (SystemLibrary.IsValid(this.ToastContainer)) { const toastWidget = this.ToastContainer.AddToast(Message, Type); if (SystemLibrary.IsValid(toastWidget)) { this.ActiveToasts.Add(newToast); this.ToastWidgets.Add(toastWidget); this.LogToConsole(Type, Message); return newToast.ID; } else { return -1; } } } this.LogToConsole(Type, Message); return -1; } /** * Main update loop for toast system * Removes expired toasts automatically * @category System Main Loop */ public UpdateToastSystem(): void { if (this.ShouldProcessToasts()) { this.RemoveExpiredToasts(); } } /** * Get toast widgets for testing purposes * @returns Array of active toast widgets * @category Testing */ public GetTestData(): UEArray { return this.ToastWidgets; } /** * Initialize toast system with container widget * @example * // Initialize toast system in main character * this.ToastSystemComponent.InitializeToastSystem(); * @category System Setup */ public InitializeToastSystem(): void { this.ToastContainer = CreateWidget(WBP_ToastContainer); this.ToastContainer.InitializeContainer(); this.IsInitialized = true; this.NextToastID = 1; } /** * Log toast message to console if enabled * @param Type - Message type for formatting * @param Message - Message text to log * @category System Utilities */ public LogToConsole(Type: E_MessageType, Message: Text): void { if (this.ToastSettings.AlsoLogToConsole) { SystemLibrary.PrintString(`[${Type}] ${Message}`, false); } } // ════════════════════════════════════════════════════════════════════════════════════════ // VARIABLES // ════════════════════════════════════════════════════════════════════════════════════════ /** * Toast system configuration settings * Controls capacity, duration, and logging behavior * @category System Config * @instanceEditable true */ public ToastSettings: S_ToastSettings = { MaxVisibleToasts: 5, DefaultDuration: 3.0, AlsoLogToConsole: true, IsEnabled: true, }; /** * System initialization state flag * Set to true after successful InitializeToastSystem call * @category System State */ private IsInitialized: boolean = false; /** * Next unique ID for new toasts * Incremented for each new toast * @category System State */ private NextToastID: Integer = 1; /** * Toast container widget that handles positioning and layout * @category Container Management */ private ToastContainer: WBP_ToastContainer | null = null; /** * Array of currently active toast messages * Contains all visible toasts with metadata * @category Toast Management */ private ActiveToasts: UEArray = new UEArray([]); /** * Array of toast widget instances * Corresponds to ActiveToasts array for UI display * @category Widget Management */ private ToastWidgets: UEArray = new UEArray([]); }