refactor: decouple Application singleton by extracting core subsystems and updating interfaces

- Add `audio::AudioCoordinator` interface and implementation
- Modify `Application` to reduce singleton usage and move controller responsibilities:
  - application.hpp
  - application.cpp
- Update UI and audio headers/sources:
  - game_screen.hpp
  - game_screen.cpp
  - ui_manager.hpp
  - audio_coordinator.hpp
  - audio_coordinator.cpp
- Project config touched:
  - CMakeLists.txt
This commit is contained in:
Paul 2026-04-01 20:38:37 +03:00
parent 9b38e64f84
commit d43397163e
8 changed files with 179 additions and 3 deletions

View file

@ -0,0 +1,87 @@
#include "audio/audio_coordinator.hpp"
#include "audio/audio_engine.hpp"
#include "audio/music_manager.hpp"
#include "audio/footstep_manager.hpp"
#include "audio/activity_sound_manager.hpp"
#include "audio/mount_sound_manager.hpp"
#include "audio/npc_voice_manager.hpp"
#include "audio/ambient_sound_manager.hpp"
#include "audio/ui_sound_manager.hpp"
#include "audio/combat_sound_manager.hpp"
#include "audio/spell_sound_manager.hpp"
#include "audio/movement_sound_manager.hpp"
#include "pipeline/asset_manager.hpp"
#include "core/logger.hpp"
namespace wowee {
namespace audio {
AudioCoordinator::AudioCoordinator() = default;
AudioCoordinator::~AudioCoordinator() {
shutdown();
}
bool AudioCoordinator::initialize() {
// Initialize AudioEngine (singleton)
if (!AudioEngine::instance().initialize()) {
LOG_WARNING("Failed to initialize AudioEngine - audio will be disabled");
audioAvailable_ = false;
return false;
}
audioAvailable_ = true;
// Create all audio managers (initialized later with asset manager)
musicManager_ = std::make_unique<MusicManager>();
footstepManager_ = std::make_unique<FootstepManager>();
activitySoundManager_ = std::make_unique<ActivitySoundManager>();
mountSoundManager_ = std::make_unique<MountSoundManager>();
npcVoiceManager_ = std::make_unique<NpcVoiceManager>();
ambientSoundManager_ = std::make_unique<AmbientSoundManager>();
uiSoundManager_ = std::make_unique<UiSoundManager>();
combatSoundManager_ = std::make_unique<CombatSoundManager>();
spellSoundManager_ = std::make_unique<SpellSoundManager>();
movementSoundManager_ = std::make_unique<MovementSoundManager>();
LOG_INFO("AudioCoordinator initialized with ", 10, " audio managers");
return true;
}
void AudioCoordinator::initializeWithAssets(pipeline::AssetManager* assetManager) {
if (!audioAvailable_ || !assetManager) return;
// MusicManager needs asset manager for zone music lookups
if (musicManager_) {
musicManager_->initialize(assetManager);
}
// Other managers may need asset manager for sound bank loading
// (Add similar calls as needed for other managers)
LOG_INFO("AudioCoordinator initialized with asset manager");
}
void AudioCoordinator::shutdown() {
// Reset all managers first (they may reference AudioEngine)
movementSoundManager_.reset();
spellSoundManager_.reset();
combatSoundManager_.reset();
uiSoundManager_.reset();
ambientSoundManager_.reset();
npcVoiceManager_.reset();
mountSoundManager_.reset();
activitySoundManager_.reset();
footstepManager_.reset();
musicManager_.reset();
// Shutdown audio engine last
if (audioAvailable_) {
AudioEngine::instance().shutdown();
audioAvailable_ = false;
}
LOG_INFO("AudioCoordinator shutdown complete");
}
} // namespace audio
} // namespace wowee

View file

@ -31,6 +31,7 @@
#include "audio/footstep_manager.hpp"
#include "audio/activity_sound_manager.hpp"
#include "audio/audio_engine.hpp"
#include "audio/audio_coordinator.hpp"
#include "addons/addon_manager.hpp"
#include <imgui.h>
#include "pipeline/m2_loader.hpp"
@ -223,6 +224,11 @@ bool Application::initialize() {
renderer.get(), assetManager.get(), gameHandler.get(),
dbcLayout_.get(), entitySpawner_.get());
// Wire AppearanceComposer to UI components (Phase A singleton breaking)
if (uiManager) {
uiManager->setAppearanceComposer(appearanceComposer_.get());
}
// Ensure the main in-world CharacterRenderer can load textures immediately.
// Previously this was only wired during terrain initialization, which meant early spawns
// (before terrain load) would render with white fallback textures (notably hair).

View file

@ -2,6 +2,7 @@
#include "ui/ui_colors.hpp"
#include "rendering/vk_context.hpp"
#include "core/application.hpp"
#include "core/appearance_composer.hpp"
#include "addons/addon_manager.hpp"
#include "core/coordinates.hpp"
#include "core/input.hpp"
@ -631,7 +632,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
if (inventoryScreen.consumeEquipmentDirty() || gameHandler.consumeOnlineEquipmentDirty()) {
updateCharacterGeosets(gameHandler.getInventory());
updateCharacterTextures(gameHandler.getInventory());
if (auto* ac = core::Application::getInstance().getAppearanceComposer()) ac->loadEquippedWeapons();
if (appearanceComposer_) appearanceComposer_->loadEquippedWeapons();
inventoryScreen.markPreviewDirty();
// Update renderer weapon type for animation selection
auto* r = core::Application::getInstance().getRenderer();