tengri/Content/Toasts/Components/AC_ToastSystem.ts

272 lines
8.4 KiB
TypeScript

// 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<WBP_Toast> {
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<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([]);
}