[code] toast module refactoring

main
Nikolay Petrov 2025-10-03 04:10:20 +05:00
parent b60b7201c5
commit df35fae518
12 changed files with 236 additions and 447 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,6 @@
// Toasts/Components/AC_ToastSystem.ts // Toasts/Components/AC_ToastSystem.ts
import type { S_ToastMessage } from '#root/Toasts/Structs/S_ToastMessage.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 type { WBP_Toast } from '#root/Toasts/UI/WBP_Toast.ts';
import { WBP_ToastContainer } from '#root/Toasts/UI/WBP_ToastContainer.ts'; import { WBP_ToastContainer } from '#root/Toasts/UI/WBP_ToastContainer.ts';
import { ActorComponent } from '#root/UE/ActorComponent.ts'; import { ActorComponent } from '#root/UE/ActorComponent.ts';
@ -33,10 +32,8 @@ export class AC_ToastSystem extends ActorComponent {
/** /**
* Validate system state and settings * Validate system state and settings
*/ */
const function1 = (isEnabled: boolean): boolean =>
this.IsInitialized && isEnabled;
return function1(this.ToastSettings.IsEnabled); return this.IsInitialized && this.IsEnabled;
} }
/** /**
@ -101,12 +98,7 @@ export class AC_ToastSystem extends ActorComponent {
maxVisibleToasts: Integer maxVisibleToasts: Integer
): boolean => activeToastsLength >= maxVisibleToasts; ): boolean => activeToastsLength >= maxVisibleToasts;
while ( while (ExceedsToastLimit(this.ActiveToasts.length, this.MaxVisibleToasts)) {
ExceedsToastLimit(
this.ActiveToasts.length,
this.ToastSettings.MaxVisibleToasts
)
) {
const widget = this.ToastWidgets.Get(0); const widget = this.ToastWidgets.Get(0);
if (SystemLibrary.IsValid(widget)) { if (SystemLibrary.IsValid(widget)) {
@ -136,19 +128,16 @@ export class AC_ToastSystem extends ActorComponent {
public ShowToast( public ShowToast(
Message: Text = '', Message: Text = '',
Type: E_MessageType = E_MessageType.Info, Type: E_MessageType = E_MessageType.Info,
Duration: Float = 0 Duration: Float = 5
): Integer { ): Integer {
if (this.ShouldProcessToasts()) { if (this.ShouldProcessToasts()) {
const toastDuration =
Duration !== 0 ? Duration : this.ToastSettings.DefaultDuration;
const currentTime = SystemLibrary.GetGameTimeInSeconds(); const currentTime = SystemLibrary.GetGameTimeInSeconds();
const newToast: S_ToastMessage = { const newToast: S_ToastMessage = {
ID: this.NextToastID++, ID: this.NextToastID++,
Message, Message,
Type, Type,
Duration: toastDuration, Duration,
CreatedTime: currentTime, CreatedTime: currentTime,
}; };
@ -184,12 +173,21 @@ export class AC_ToastSystem extends ActorComponent {
} }
/** /**
* Get toast widgets for testing purposes * Get system state and configuration for testing purposes
* @returns Array of active toast widgets * Provides read-only access to private configuration and active widgets
* @returns Object containing toast widgets array and system configuration
* @category Testing * @category Testing
*/ */
public GetTestData(): UEArray<WBP_Toast> { public GetTestData(): {
return this.ToastWidgets; ToastWidgets: UEArray<WBP_Toast>;
MaxVisibleToasts: Integer;
IsEnabled: boolean;
} {
return {
ToastWidgets: this.ToastWidgets,
MaxVisibleToasts: this.MaxVisibleToasts,
IsEnabled: this.IsEnabled,
};
} }
/** /**
@ -213,7 +211,7 @@ export class AC_ToastSystem extends ActorComponent {
* @category System Utilities * @category System Utilities
*/ */
public LogToConsole(Type: E_MessageType, Message: Text): void { public LogToConsole(Type: E_MessageType, Message: Text): void {
if (this.ToastSettings.AlsoLogToConsole) { if (this.AlsoLogToConsole) {
SystemLibrary.PrintString(`[${Type}] ${Message}`, false); SystemLibrary.PrintString(`[${Type}] ${Message}`, false);
} }
} }
@ -223,17 +221,34 @@ export class AC_ToastSystem extends ActorComponent {
// ════════════════════════════════════════════════════════════════════════════════════════ // ════════════════════════════════════════════════════════════════════════════════════════
/** /**
* Toast system configuration settings * Maximum number of simultaneously visible toast notifications
* Controls capacity, duration, and logging behavior * When limit is exceeded, oldest toasts are automatically removed
* @default 5
* @range 1-10 recommended
* @category System Config * @category System Config
* @instanceEditable true * @instanceEditable true
*/ */
public ToastSettings: S_ToastSettings = { private readonly MaxVisibleToasts: Integer = 5;
MaxVisibleToasts: 5,
DefaultDuration: 3.0, /**
AlsoLogToConsole: true, * Duplicate all toast messages to console output for debugging
IsEnabled: true, * 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 * System initialization state flag

Binary file not shown.

View File

@ -1,11 +0,0 @@
// Toasts/Structs/S_ToastSettings.ts
import type { Float } from '#root/UE/Float.ts';
import type { Integer } from '#root/UE/Integer.ts';
export interface S_ToastSettings {
MaxVisibleToasts: Integer;
DefaultDuration: Float;
AlsoLogToConsole: boolean;
IsEnabled: boolean;
}

Binary file not shown.

View File

@ -10,6 +10,7 @@
- **Типизированные сообщения:** Цветовая дифференциация по типу (Info, Success, Warning, Error, Debug) - **Типизированные сообщения:** Цветовая дифференциация по типу (Info, Success, Warning, Error, Debug)
- **Ограниченная емкость:** Контролируемое количество видимых уведомлений - **Ограниченная емкость:** Контролируемое количество видимых уведомлений
- **Integration ready:** Тесная интеграция с Debug HUD и другими системами - **Integration ready:** Тесная интеграция с Debug HUD и другими системами
- **Instance-editable config:** Настройки доступны для изменения в Blueprint editor
## Компоненты системы ## Компоненты системы
@ -24,7 +25,7 @@
- `InitializeToastSystem()` - Инициализация контейнера и системы - `InitializeToastSystem()` - Инициализация контейнера и системы
- `ShowToast()` - Создание нового уведомления с возвратом ID - `ShowToast()` - Создание нового уведомления с возвратом ID
- `UpdateToastSystem()` - Main loop для удаления expired toast - `UpdateToastSystem()` - Main loop для удаления expired toast
- `EnforceToastLimit()` - Контроль максимального количества - `GetTestData()` - Возврат данных для тестирования
### WBP_ToastContainer (UI Container) ### WBP_ToastContainer (UI Container)
**Ответственности:** **Ответственности:**
@ -33,32 +34,16 @@
- Добавление и удаление child toast widgets - Добавление и удаление child toast widgets
- Viewport integration для корректного отображения - Viewport integration для корректного отображения
**Ключевые функции:**
- `AddToast()` - Создание и добавление нового toast widget
- `RemoveToast()` - Безопасное удаление toast из контейнера
- `InitializeContainer()` - Настройка visibility и добавление в viewport
### WBP_Toast (Individual Widget) ### WBP_Toast (Individual Widget)
**Ответственности:** **Ответственности:**
- Отображение текста уведомления - Отображение текста уведомления
- Динамическое изменение цвета фона по типу сообщения - Динамическое изменение цвета фона по типу сообщения
- Обновление содержимого в runtime - Обновление содержимого в runtime
- Viewport lifecycle management
**Ключевые функции:**
- `InitializeToast()` - Инициализация с сообщением и типом
- `SetMessage()` - Обновление текста уведомления
- `SetToastType()` - Изменение типа и стилизации
### BFL_Colors (Color Management Library) ### BFL_Colors (Color Management Library)
**Ответственности:** **Ответственности:**
- Цветовая схема для разных типов сообщений - Цветовая схема для разных типов сообщений
- Консистентная стилизация across всей системы - Консистентная стилизация across всей системы
- Alpha channel поддержка для прозрачности
- Type-safe color mapping
**Ключевые функции:**
- `GetColorByMessageType()` - Возвращает Color по типу сообщения
## Типы уведомлений ## Типы уведомлений
@ -69,126 +54,133 @@ enum E_MessageType {
Success = 'Success', // Успешные операции Success = 'Success', // Успешные операции
Warning = 'Warning', // Предупреждения Warning = 'Warning', // Предупреждения
Error = 'Error', // Ошибки Error = 'Error', // Ошибки
Debug = 'Debug', // Debug информация Debug = 'Debug' // Debug информация
Test = 'Test' // Тестовые сообщения
} }
``` ```
### Цветовая схема ### Цветовая схема
- **Info:** Синий (#0066CC)
- **Success:** Зеленый (#00CC66)
- **Warning:** Оранжевый (#FF9900)
- **Error:** Красный (#CC0000)
- **Debug:** Фиолетовый (#9933CC)
## API Reference
### ShowToast()
```typescript ```typescript
GetColorByMessageType(Type: E_MessageType, Alpha: Byte): Color { public ShowToast(
Info: Color(226, 144, 74, Alpha) Message: Text = '',
Success: Color(92, 184, 92, Alpha) Type: E_MessageType = E_MessageType.Info,
Warning: Color(78, 173, 240, Alpha) Duration: Float = 5
Error: Color(79, 83, 217, Alpha) ): Integer
Debug: Color(125, 117, 108, Alpha) ```
**Описание:** Создает и отображает новое toast уведомление
**Возвращает:** Toast ID (положительное число) или -1 при неудаче
**Parameters:**
- `Message` - Текст уведомления
- `Type` - Тип сообщения (Info/Success/Warning/Error/Debug)
- `Duration` - Время отображения в секундах (по умолчанию 5)
**Примеры:**
```typescript
// Стандартное использование
this.ToastComponent.ShowToast("Save complete", E_MessageType.Success)
// Кастомная длительность
this.ToastComponent.ShowToast("Critical error!", E_MessageType.Error, 10)
```
### GetTestData()
```typescript
public GetTestData(): {
ToastWidgets: UEArray<WBP_Toast>;
MaxVisibleToasts: Integer;
IsEnabled: boolean;
} }
``` ```
**Описание:** Возвращает данные системы для тестирования
**Возвращает:** Объект с активными widgets и конфигурацией
## Структуры данных **Использование в тестах:**
### S_ToastMessage
```typescript ```typescript
interface S_ToastMessage { const data = this.ToastComponent.GetTestData()
ID: Integer // Уникальный идентификатор (1, 2, 3...) this.AssertEqual(data.ToastWidgets.length, 5, "Should not exceed max")
Message: Text // Текст уведомления this.AssertEqual(data.MaxVisibleToasts, 5, "Default limit check")
Type: E_MessageType // Тип для цветовой схемы this.AssertTrue(data.IsEnabled, "System should be enabled")
Duration: Float // Время жизни в секундах (default: 3.0)
CreatedTime: Float // Timestamp создания для lifecycle tracking
}
``` ```
### S_ToastSettings ### InitializeToastSystem()
```typescript ```typescript
interface S_ToastSettings { public InitializeToastSystem(): void
MaxVisibleToasts: Integer // Максимум видимых (default: 5) ```
DefaultDuration: Float // Длительность по умолчанию (3.0s) **Описание:** Инициализирует систему, создает UI контейнер
AlsoLogToConsole: boolean // Дублировать в console.log **Обязательность:** Должна быть вызвана ДО любых вызовов ShowToast()
IsEnabled: boolean // Главный выключатель системы
} ### UpdateToastSystem()
```typescript
public UpdateToastSystem(): void
```
**Описание:** Main loop функция, обрабатывает removal expired toast
**Вызов:** Должна вызываться каждый frame в Tick
## Алгоритмы работы
### Создание toast
```
ShowToast(Message, Type, Duration):
1. ShouldProcessToasts() - проверка IsInitialized && IsEnabled
2. Создание S_ToastMessage с уникальным ID
3. EnforceToastLimit() - удаление oldest если >= MaxVisibleToasts
4. ToastContainer.AddToast() - создание widget
5. Add в ActiveToasts и ToastWidgets
6. LogToConsole() если AlsoLogToConsole = true
7. Return ID или -1
``` ```
## Жизненный цикл Toast ### Удаление expired toast
### Создание уведомления
``` ```
1. ShowToast() вызывается с параметрами RemoveExpiredToasts() в UpdateToastSystem():
2. Проверка ShouldProcessToasts() (система включена?) 1. Loop через ActiveToasts
3. EnforceToastLimit() - удаление oldest при превышении лимита 2. Для каждого toast проверка: (CurrentTime - CreatedTime > Duration)
4. Создание S_ToastMessage с уникальным ID 3. Если expired:
5. ToastContainer.AddToast() создает WBP_Toast widget - ToastContainer.RemoveToast(widget)
6. Добавление в ActiveToasts и ToastWidgets массивы
7. LogToConsole() при включенной настройке
8. Возврат Toast ID для tracking
```
### Обновление системы
```
UpdateToastSystem() каждый frame:
1. ShouldProcessToasts() проверка готовности
2. RemoveExpiredToasts() - поиск expired по времени
3. Для каждого expired toast:
- ToastContainer.RemoveToast() удаление из UI
- RemoveIndex() из ActiveToasts и ToastWidgets - RemoveIndex() из ActiveToasts и ToastWidgets
- SetVisibility(Hidden) и RemoveFromParent()
``` ```
### Контроль лимитов ### Контроль лимитов
``` ```
EnforceToastLimit() при превышении MaxVisibleToasts: EnforceToastLimit():
1. while (ActiveToasts.length >= MaxVisibleToasts) 1. while (ActiveToasts.length >= MaxVisibleToasts)
2. Получение oldest toast (index 0) 2. Удаление oldest toast (index 0)
3. ToastContainer.RemoveToast() удаление widget 3. RemoveIndex(0) из обоих массивов
4. RemoveIndex(0) из обоих массивов
5. Repeat until в пределах лимита
``` ```
## Производительность ## Производительность
### Оптимизации
- **Единственный таймер:** Один GetGameTimeInSeconds() вызов на Update
- **Массивная обработка:** Batch removal в RemoveExpiredToasts
- **Ленивое создание:** Widget создается только при отображении
- **Memory pool:** Переиспользование widget instances (planned)
### Benchmarks ### Benchmarks
- **Инициализация:** <1ms (создание контейнера) - **Инициализация:** <1ms
- **ShowToast:** <0.1ms на создание (без UI rendering) - **ShowToast:** <0.1ms на создание
- **UpdateToastSystem:** <0.05ms при 5 активных toast - **UpdateToastSystem:** <0.05ms при 5 активных toast
- **RemoveExpiredToasts:** <0.02ms per expired toast
- **Memory footprint:** ~50 байт на активный toast - **Memory footprint:** ~50 байт на активный toast
### Performance considerations
- **UI rendering cost:** Widget creation дороже логической обработки
- **String operations:** Message copying минимизирована
- **Array operations:** Remove операции O(n), но n ≤ 5
- **Timer precision:** GetGameTimeInSeconds() dependency
## Система тестирования ## Система тестирования
### FT_ToastsSystemInitialization ### FT_ToastsSystemInitialization
**Проверяет базовую инициализацию:** **Проверяет базовую инициализацию:**
- Корректность default settings (IsEnabled = true) - Корректность default settings (IsEnabled = true, MaxVisibleToasts = 5)
- Валидность MaxVisibleToasts > 0
- Успешность InitializeToastSystem() - Успешность InitializeToastSystem()
### FT_ToastsDurationHandling ### FT_ToastsDurationHandling
**Тестирует создание и ID assignment:** **Тестирует ID assignment:**
- ShowToast() возвращает валидные положительные ID - ShowToast() возвращает валидные положительные ID
- Два последовательных toast получают разные ID - Каждый toast получает уникальный ID
- Система корректно increment NextToastID
### FT_ToastsToastCreation ### FT_ToastsToastCreation
**Валидирует создание по всем типам:** **Валидирует создание по всем типам:**
```typescript - Info, Success, Warning, Error, Debug
ToastTypes: UEArray<E_MessageType> = [ - Все типы создают валидные widgets
E_MessageType.Info,
E_MessageType.Success,
E_MessageType.Warning,
E_MessageType.Error,
E_MessageType.Debug
]
```
### FT_ToastLimit ### FT_ToastLimit
**Проверяет контроль лимитов:** **Проверяет контроль лимитов:**
@ -198,229 +190,53 @@ ToastTypes: UEArray<E_MessageType> = [
### FT_ToastsEdgeCases ### FT_ToastsEdgeCases
**Тестирует граничные условия:** **Тестирует граничные условия:**
- **Empty message:** ShowToast() без параметров - Empty message
- **Long message:** 500-символьный текст - Long message (500 символов)
- **Multiline message:** Сообщение с \n переносами - Multiline message
- Все edge cases должны возвращать валидные ID > 0
## Интеграция с системами ## Интеграция с системами
### С Debug HUD System ### С Debug HUD System
```typescript ```typescript
// В AC_DebugHUD.InitializeDebugHUD() this.ToastComponent.ShowToast('Debug HUD Initialized', E_MessageType.Success)
this.ToastComponent.ShowToast(
'Debug HUD Initialized',
E_MessageType.Success
)
// В ToggleVisualDebug()
this.ToastComponent.ShowToast(
`Visual Debug ${enabled ? 'Enabled' : 'Disabled'}`
)
``` ```
### С Main Character (BP_MainCharacter) ### С Main Character
```typescript ```typescript
// В EventBeginPlay() - инициализация первой // В EventBeginPlay
if (this.ShowDebugInfo) { this.ToastSystemComponent.InitializeToastSystem()
this.ToastSystemComponent.InitializeToastSystem()
this.DebugHUDComponent.InitializeDebugHUD(
this.MovementComponent,
this.ToastSystemComponent // передача reference
)
}
// В EventTick() - обновление каждый frame // В Tick
if (this.ShowDebugInfo) { this.ToastSystemComponent.UpdateToastSystem()
this.ToastSystemComponent.UpdateToastSystem()
}
``` ```
### С Console Logging ## Миграция с предыдущей версии
### Изменения в рефакторинге
1. ✅ Убрана структура `S_ToastSettings`
2. ✅ Переменные стали прямыми полями компонента с `@instanceEditable`
3. ✅ `ShowToast()` теперь имеет `Duration: Float = 5` (было 0)
4. ✅ `GetTestData()` возвращает расширенный объект
### Breaking Changes
#### 1. Доступ к настройкам
```typescript ```typescript
// Настройка AlsoLogToConsole = true дублирует все toast в console // ❌ Старый код
LogToConsole(Type: E_MessageType, Message: Text): void { if (this.ToastComponent.ToastSettings.IsEnabled) { }
if (this.ToastSettings.AlsoLogToConsole) {
SystemLibrary.PrintString(`[${Type}] ${Message}`, false) // ✅ Новый код - используем GetTestData()
} const data = this.ToastComponent.GetTestData()
} if (data.IsEnabled) { }
``` ```
## API Reference #### 2. ShowToast Duration
### Публичные методы
#### InitializeToastSystem()
```typescript ```typescript
InitializeToastSystem(): void // ❌ Старый код - 0 означал default
``` this.ShowToast("Message", E_MessageType.Info, 0)
**Описание:** Инициализирует систему с созданием UI контейнера
**Когда вызывать:** EventBeginPlay в main character, до использования ShowToast
**Эффекты:** Создает WBP_ToastContainer, устанавливает IsInitialized = true
#### ShowToast() // ✅ Новый код - просто не передавать
```typescript this.ShowToast("Message", E_MessageType.Info)
ShowToast(
Message: Text = '',
Type: E_MessageType = E_MessageType.Info,
Duration: Float = 0
): Integer
```
**Параметры:**
- `Message` - Текст уведомления (default: пустая строка)
- `Type` - Тип сообщения для стилизации (default: Info)
- `Duration` - Время жизни, 0 = default (default: используется DefaultDuration)
**Возвращает:** Toast ID > 0 при успехе, -1 при ошибке
**Требования:** Система должна быть инициализирована
#### UpdateToastSystem()
```typescript
UpdateToastSystem(): void
```
**Описание:** Main update loop, удаляет expired toast
**Когда вызывать:** EventTick в main character каждый frame
**Эффекты:** Автоматическое удаление истекших уведомлений
#### GetTestData()
```typescript
GetTestData(): UEArray<WBP_Toast>
```
**Описание:** Возвращает активные toast widgets для тестирования
**Use case:** Валидация в автотестах, debug проверки
### Публичные свойства
#### ToastSettings (Instance Editable)
```typescript
ToastSettings: S_ToastSettings = {
MaxVisibleToasts: 5, // Максимум одновременных уведомлений
DefaultDuration: 3.0, // Время жизни по умолчанию (секунды)
AlsoLogToConsole: true, // Дублирование в console.log
IsEnabled: true // Главный выключатель системы
}
```
### Приватные свойства
#### IsInitialized (Read-only)
```typescript
private IsInitialized: boolean = false
```
**Описание:** Флаг успешной инициализации системы
**Use case:** Проверка готовности в ShouldProcessToasts()
#### NextToastID (Auto-increment)
```typescript
private NextToastID: Integer = 1
```
**Описание:** Счетчик для генерации уникальных ID
**Behavior:** Инкрементируется при каждом ShowToast() вызове
## Расширяемость
### Добавление новых типов сообщений
1. Расширить `E_MessageType` enum
2. Добавить цветовую схему в `BFL_Colors.GetColorByMessageType()`
3. Обновить test coverage в `FT_ToastsToastCreation`
### Пример добавления "Critical" типа:
```typescript
// 1. Enum
enum E_MessageType {
// ... existing types
Critical = 'Critical' // Критические системные ошибки
}
// 2. Color mapping
case E_MessageType.Critical:
return new Color(255, 0, 0, Alpha) // Ярко-красный
// 3. Test coverage
private ToastTypes: UEArray<E_MessageType> = [
// ... existing types
E_MessageType.Critical
]
```
### Новые функциональности
- **Toast priorities:** Разные приоритеты для разных типов
- **Interactive toasts:** Кликабельные уведомления с действиями
- **Toast animations:** Fade in/out эффекты при показе/скрытии
- **Persistent toasts:** Уведомления без auto-expire
- **Toast categories:** Группировка по системам (Debug, Movement, Audio)
## Известные ограничения
### Текущие ограничения
1. **Fixed capacity** - Жестко заданный лимит в 5 уведомлений
2. **No priority system** - FIFO удаление без учета важности
3. **Simple layout** - Только вертикальное расположение
4. **No persistence** - Все toast временные, нет постоянных
### Архитектурные ограничения
1. **Single container** - Одно место отображения для всех toast
2. **No categorization** - Невозможно группировать по системам
3. **Linear time complexity** - RemoveExpiredToasts O(n) по количеству toast
4. **No animation system** - Статичное появление/исчезновение
## Планы развития (Stage 3+)
### Краткосрочные улучшения
1. **Animation system** - Плавные fade in/out переходы
2. **Priority queues** - Важные сообщения вытесняют менее важные
3. **Categorization** - Группировка toast по системам
4. **Interactive elements** - Кликабельные действия в уведомлениях
### Долгосрочные цели
1. **Multiple containers** - Разные области экрана для разных типов
2. **Rich content support** - Иконки, прогресс-бары, форматированный текст
3. **Sound integration** - Audio feedback для разных типов уведомлений
4. **Network synchronization** - Синхронизация toast между клиентами
## Интеграционные точки
### С Audio System
- **Type-specific sounds:** Разные звуки для Success/Error/Warning
- **Audio cues:** Звуковое подтверждение важных уведомлений
- **Volume control:** Отдельная настройка громкости для toast sounds
### С Input System
- **Hotkey dismiss:** Клавиша для ручного закрытия всех toast
- **Interactive toasts:** Keyboard/mouse взаимодействие с уведомлениями
- **Accessibility:** Screen reader поддержка для toast content
### С Settings System
- **User preferences:** Настройки длительности, количества, типов
- **Profile persistence:** Сохранение настроек between sessions
- **Runtime configuration:** Изменение параметров без перезагрузки
## Файловая структура
```
Content/
├── Toasts/
│ ├── Components/
│ │ └── AC_ToastSystem.ts # Core toast management
│ ├── Structs/
│ │ ├── S_ToastMessage.ts # Individual toast data
│ │ └── S_ToastSettings.ts # System configuration
│ ├── UI/
│ │ ├── WBP_Toast.ts # Individual toast widget
│ │ └── WBP_ToastContainer.ts # Layout container
│ └── Tests/
│ ├── FT_ToastLimit.ts # Capacity management
│ ├── FT_ToastsDurationHandling.ts # Basic functionality
│ ├── FT_ToastsEdgeCases.ts # Edge case handling
│ ├── FT_ToastsSystemInitialization.ts # Setup testing
│ └── FT_ToastsToastCreation.ts # Type coverage
├── UI/
│ ├── Enums/
│ │ └── E_MessageType.ts # Toast type definitions
│ └── Libraries/
│ └── BFL_Colors.ts # Color scheme management
└── Blueprints/
└── BP_MainCharacter.ts # Integration point
``` ```
## Best Practices ## Best Practices
@ -429,105 +245,77 @@ Content/
```typescript ```typescript
// ✅ Хорошо - инициализация перед использованием // ✅ Хорошо - инициализация перед использованием
this.ToastSystemComponent.InitializeToastSystem() this.ToastSystemComponent.InitializeToastSystem()
const toastId = this.ToastSystemComponent.ShowToast("Success!", E_MessageType.Success) this.ToastSystemComponent.ShowToast("Success!", E_MessageType.Success)
// ✅ Хорошо - проверка системы // ✅ Хорошо - кастомная длительность
if (this.ToastSystemComponent.ToastSettings.IsEnabled) { this.ToastSystemComponent.ShowToast("Error!", E_MessageType.Error, 10.0)
this.ToastSystemComponent.ShowToast("Debug info", E_MessageType.Debug)
}
// ✅ Хорошо - кастомная длительность для важных сообщений
this.ToastSystemComponent.ShowToast(
"Critical error occurred",
E_MessageType.Error,
10.0 // 10 секунд для критических ошибок
)
// ❌ Плохо - использование без инициализации // ❌ Плохо - использование без инициализации
const toastId = this.ToastSystemComponent.ShowToast("Message") // может вернуть -1 this.ToastSystemComponent.ShowToast("Message") // вернет -1
// ❌ Плохо - игнорирование return value
this.ToastSystemComponent.ShowToast("Important") // не проверяем успешность
``` ```
### Рекомендации по типам сообщений ### Рекомендации по типам
- **Info:** Общая информация, подсказки пользователю - **Info:** Общая информация
- **Success:** Подтверждение успешных операций (сохранение, загрузка) - **Success:** Подтверждение операций
- **Warning:** Предупреждения о потенциальных проблемах - **Warning:** Предупреждения
- **Error:** Ошибки, требующие внимания пользователя - **Error:** Критические ошибки
- **Debug:** Техническая информация для разработчиков - **Debug:** Техническая информация
### Performance recommendations ### Рекомендации по Duration
- Используйте короткие сообщения для лучшей читаемости - **1-2s:** Простые подтверждения
- Избегайте spam toast - группируйте похожие уведомления - **5s (default):** Большинство уведомлений
- Настройте AlsoLogToConsole = false в production для performance - **8-10s:** Errors, warnings, важные события
- Регулируйте DefaultDuration based на важность системы
## Статистика использования
### Типичные паттерны использования
```typescript
// Debug system notifications (30% всех toast)
this.ToastComponent.ShowToast("Debug HUD Initialized", E_MessageType.Success)
this.ToastComponent.ShowToast("Visual Debug Enabled", E_MessageType.Info)
// Error reporting (25% всех toast)
this.ToastComponent.ShowToast("Failed to create widget", E_MessageType.Error)
this.ToastComponent.ShowToast("Movement component invalid", E_MessageType.Error)
// System status updates (25% всех toast)
this.ToastComponent.ShowToast("System ready", E_MessageType.Success)
this.ToastComponent.ShowToast("Configuration loaded", E_MessageType.Info)
// Test notifications (20% всех toast)
this.ToastComponent.ShowToast("Test passed!", E_MessageType.Success)
this.ToastComponent.ShowToast("Limit test toast 1", E_MessageType.Info, 10)
```
### Usage metrics (из тестов)
- **Average toast lifetime:** 3.0 секунды (DefaultDuration)
- **Peak concurrent toasts:** 5 (MaxVisibleToasts)
- **Message length range:** 0-500 символов (edge case testing)
- **Success rate:** 99.9% (только при неинициализированной системе возврат -1)
## Troubleshooting ## Troubleshooting
### Частые проблемы ### Toast не отображаются
1. **Toast не отображаются** - ✅ Проверить что `InitializeToastSystem()` вызван
- Проверить IsEnabled в ToastSettings - ✅ Проверить `IsEnabled = true` через `GetTestData()`
- Убедиться что InitializeToastSystem() вызван - ✅ Проверить что `UpdateToastSystem()` вызывается
- Проверить что UpdateToastSystem() вызывается в Tick
2. **Toast исчезают слишком быстро/медленно** ### Toast исчезают слишком быстро
- Настроить DefaultDuration в ToastSettings - ✅ Передавать кастомную Duration в ShowToast()
- Передавать кастомную Duration в ShowToast() - ✅ Проверить что время в секундах
- Проверить что время не в milliseconds вместо seconds
3. **Слишком много toast одновременно** ### Слишком много toast
- Настроить MaxVisibleToasts в ToastSettings - ✅ Настроить MaxVisibleToasts в Blueprint
- Группировать похожие уведомления - ✅ Группировать похожие уведомления
- Использовать different Duration для разных типов
4. **Memory leaks при большом количестве toast** ## Файловая структура
- Убедиться что UpdateToastSystem() вызывается для cleanup
- Проверить что expired toast корректно удаляются из массивов ```
- Мониторить ActiveToasts.length во время runtime Content/
├── Toasts/
│ ├── Components/
│ │ └── AC_ToastSystem.ts
│ ├── Structs/
│ │ └── S_ToastMessage.ts
│ ├── UI/
│ │ ├── WBP_Toast.ts
│ │ └── WBP_ToastContainer.ts
│ └── Tests/
│ ├── FT_ToastLimit.ts
│ ├── FT_ToastsDurationHandling.ts
│ ├── FT_ToastsEdgeCases.ts
│ ├── FT_ToastsSystemInitialization.ts
│ └── FT_ToastsToastCreation.ts
├── UI/
│ ├── Enums/
│ │ └── E_MessageType.ts
│ └── Libraries/
│ └── BFL_Colors.ts
└── Blueprints/
└── BP_MainCharacter.ts
```
## Заключение ## Заключение
Toast System представляет собой надежную и гибкую систему для отображения временных уведомлений в игровом интерфейсе. Система обеспечивает автоматическое управление жизненным циклом, типизированную стилизацию и эффективную интеграцию с другими системами проекта. Toast System после рефакторинга представляет собой более чистую и maintainable архитектуру.
**Ключевые достижения:** **Ключевые достижения:**
- ✅ Полностью автоматическое управление lifecycle без memory leaks - ✅ Упрощена структура (убрана S_ToastSettings)
- ✅ Comprehensive test coverage (5 test scenarios covering edge cases) - ✅ Улучшен API с явным default Duration = 5s
- ✅ Типизированная система с цветовой дифференциацией - ✅ GetTestData() предоставляет доступ к конфигурации
- ✅ Контролируемая емкость с automatic oldest removal - ✅ Instance-editable переменные для Blueprint
- ✅ Production-ready performance (<0.1ms per operation) - ✅ Полная test coverage
- ✅ Seamless integration с Debug HUD и Main Character - ✅ Production-ready performance
**Готовность к production:**
- Все автотесты покрывают edge cases и boundary conditions
- Performance benchmarks соответствуют real-time требованиям
- Memory management протестирован на длительных сессиях
- API documented и готово к расширению новыми функциями
- Integration points четко определены для других систем

BIN
Content/Toasts/Tests/FT_ToastLimit.uasset (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.