287 lines
9.0 KiB
TypeScript
287 lines
9.0 KiB
TypeScript
// Toasts/Components/AC_ToastSystem.ts
|
|
|
|
import type { S_ToastMessage } from '#root/Toasts/Structs/S_ToastMessage.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
|
|
*/
|
|
|
|
return this.IsInitialized && this.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.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 = 5
|
|
): Integer {
|
|
if (this.ShouldProcessToasts()) {
|
|
const currentTime = SystemLibrary.GetGameTimeInSeconds();
|
|
|
|
const newToast: S_ToastMessage = {
|
|
ID: this.NextToastID++,
|
|
Message,
|
|
Type,
|
|
Duration,
|
|
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 system state and configuration for testing purposes
|
|
* Provides read-only access to private configuration and active widgets
|
|
* @returns Object containing toast widgets array and system configuration
|
|
* @category Testing
|
|
*/
|
|
public GetTestData(): {
|
|
ToastWidgets: UEArray<WBP_Toast>;
|
|
MaxVisibleToasts: Integer;
|
|
IsEnabled: boolean;
|
|
} {
|
|
return {
|
|
ToastWidgets: this.ToastWidgets,
|
|
MaxVisibleToasts: this.MaxVisibleToasts,
|
|
IsEnabled: this.IsEnabled,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 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.AlsoLogToConsole) {
|
|
SystemLibrary.PrintString(`[${Type}] ${Message}`, false);
|
|
}
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// VARIABLES
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Maximum number of simultaneously visible toast notifications
|
|
* When limit is exceeded, oldest toasts are automatically removed
|
|
* @default 5
|
|
* @range 1-10 recommended
|
|
* @category System Config
|
|
* @instanceEditable true
|
|
*/
|
|
private readonly MaxVisibleToasts: Integer = 5;
|
|
|
|
/**
|
|
* Duplicate all toast messages to console output for debugging
|
|
* Format: [MessageType] Message text
|
|
* @default true
|
|
* @recommendation Set false in production builds for performance
|
|
* @category System Config
|
|
* @instanceEditable true
|
|
*/
|
|
private readonly AlsoLogToConsole: boolean = true;
|
|
|
|
/**
|
|
* Master switch for the entire toast system
|
|
* When disabled: ShowToast() returns -1, widgets are not created
|
|
* LogToConsole still works if AlsoLogToConsole is true
|
|
* @default true
|
|
* @category System Config
|
|
* @instanceEditable true
|
|
*/
|
|
private readonly IsEnabled: boolean = 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<S_ToastMessage> = new UEArray([]);
|
|
|
|
/**
|
|
* Array of toast widget instances
|
|
* Corresponds to ActiveToasts array for UI display
|
|
* @category Widget Management
|
|
*/
|
|
private ToastWidgets: UEArray<WBP_Toast> = new UEArray([]);
|
|
}
|