mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-03 12:03:50 +00:00
"Fix and refine app initialization flow
- Update core application startup paths and cleanup logic - Adjust renderer & input subsystem integration for stability - Address recent staging source updates with robust error handling"
This commit is contained in:
parent
afeaa13562
commit
9b38e64f84
5 changed files with 1391 additions and 1208 deletions
|
|
@ -488,6 +488,7 @@ set(WOWEE_SOURCES
|
||||||
src/core/application.cpp
|
src/core/application.cpp
|
||||||
src/core/entity_spawner.cpp
|
src/core/entity_spawner.cpp
|
||||||
src/core/appearance_composer.cpp
|
src/core/appearance_composer.cpp
|
||||||
|
src/core/world_loader.cpp
|
||||||
src/core/window.cpp
|
src/core/window.cpp
|
||||||
src/core/input.cpp
|
src/core/input.cpp
|
||||||
src/core/logger.cpp
|
src/core/logger.cpp
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "core/input.hpp"
|
#include "core/input.hpp"
|
||||||
#include "core/entity_spawner.hpp"
|
#include "core/entity_spawner.hpp"
|
||||||
#include "core/appearance_composer.hpp"
|
#include "core/appearance_composer.hpp"
|
||||||
|
#include "core/world_loader.hpp"
|
||||||
#include "game/character.hpp"
|
#include "game/character.hpp"
|
||||||
#include "game/game_services.hpp"
|
#include "game/game_services.hpp"
|
||||||
#include "pipeline/blp_loader.hpp"
|
#include "pipeline/blp_loader.hpp"
|
||||||
|
|
@ -43,6 +44,8 @@ enum class AppState {
|
||||||
};
|
};
|
||||||
|
|
||||||
class Application {
|
class Application {
|
||||||
|
friend class WorldLoader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Application();
|
Application();
|
||||||
~Application();
|
~Application();
|
||||||
|
|
@ -98,14 +101,14 @@ public:
|
||||||
// Appearance composer access
|
// Appearance composer access
|
||||||
AppearanceComposer* getAppearanceComposer() { return appearanceComposer_.get(); }
|
AppearanceComposer* getAppearanceComposer() { return appearanceComposer_.get(); }
|
||||||
|
|
||||||
|
// World loader access
|
||||||
|
WorldLoader* getWorldLoader() { return worldLoader_.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
void render();
|
void render();
|
||||||
void setupUICallbacks();
|
void setupUICallbacks();
|
||||||
void spawnPlayerCharacter();
|
void spawnPlayerCharacter();
|
||||||
static const char* mapIdToName(uint32_t mapId);
|
|
||||||
static const char* mapDisplayName(uint32_t mapId);
|
|
||||||
void loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float z);
|
|
||||||
void buildFactionHostilityMap(uint8_t playerRace);
|
void buildFactionHostilityMap(uint8_t playerRace);
|
||||||
void setupTestTransport(); // Test transport boat for development
|
void setupTestTransport(); // Test transport boat for development
|
||||||
|
|
||||||
|
|
@ -125,6 +128,7 @@ private:
|
||||||
std::unique_ptr<pipeline::DBCLayout> dbcLayout_;
|
std::unique_ptr<pipeline::DBCLayout> dbcLayout_;
|
||||||
std::unique_ptr<EntitySpawner> entitySpawner_;
|
std::unique_ptr<EntitySpawner> entitySpawner_;
|
||||||
std::unique_ptr<AppearanceComposer> appearanceComposer_;
|
std::unique_ptr<AppearanceComposer> appearanceComposer_;
|
||||||
|
std::unique_ptr<WorldLoader> worldLoader_;
|
||||||
|
|
||||||
AppState state = AppState::AUTHENTICATION;
|
AppState state = AppState::AUTHENTICATION;
|
||||||
bool running = false;
|
bool running = false;
|
||||||
|
|
@ -147,13 +151,6 @@ private:
|
||||||
static inline const std::vector<std::string> emptyStringVec_;
|
static inline const std::vector<std::string> emptyStringVec_;
|
||||||
|
|
||||||
bool lastTaxiFlight_ = false;
|
bool lastTaxiFlight_ = false;
|
||||||
uint32_t loadedMapId_ = 0xFFFFFFFF; // Map ID of currently loaded terrain (0xFFFFFFFF = none)
|
|
||||||
uint32_t worldLoadGeneration_ = 0; // Incremented on each world entry to detect re-entrant loads
|
|
||||||
bool loadingWorld_ = false; // True while loadOnlineWorldTerrain is running
|
|
||||||
struct PendingWorldEntry {
|
|
||||||
uint32_t mapId; float x, y, z;
|
|
||||||
};
|
|
||||||
std::optional<PendingWorldEntry> pendingWorldEntry_; // Deferred world entry during loading
|
|
||||||
float taxiLandingClampTimer_ = 0.0f;
|
float taxiLandingClampTimer_ = 0.0f;
|
||||||
float worldEntryMovementGraceTimer_ = 0.0f;
|
float worldEntryMovementGraceTimer_ = 0.0f;
|
||||||
|
|
||||||
|
|
@ -175,29 +172,10 @@ private:
|
||||||
uint64_t chargeTargetGuid_ = 0;
|
uint64_t chargeTargetGuid_ = 0;
|
||||||
|
|
||||||
bool wasAutoAttacking_ = false;
|
bool wasAutoAttacking_ = false;
|
||||||
bool mapNameCacheLoaded_ = false;
|
|
||||||
std::unordered_map<uint32_t, std::string> mapNameById_;
|
|
||||||
|
|
||||||
// Quest marker billboard sprites (above NPCs)
|
// Quest marker billboard sprites (above NPCs)
|
||||||
void loadQuestMarkerModels(); // Now loads BLP textures
|
void loadQuestMarkerModels(); // Now loads BLP textures
|
||||||
void updateQuestMarkers(); // Updates billboard positions
|
void updateQuestMarkers(); // Updates billboard positions
|
||||||
|
|
||||||
// Background world preloader — warms AssetManager file cache for the
|
|
||||||
// expected world before the user clicks Enter World.
|
|
||||||
struct WorldPreload {
|
|
||||||
uint32_t mapId = 0;
|
|
||||||
std::string mapName;
|
|
||||||
int centerTileX = 0;
|
|
||||||
int centerTileY = 0;
|
|
||||||
std::atomic<bool> cancel{false};
|
|
||||||
std::vector<std::thread> workers;
|
|
||||||
};
|
|
||||||
std::unique_ptr<WorldPreload> worldPreload_;
|
|
||||||
void startWorldPreload(uint32_t mapId, const std::string& mapName, float serverX, float serverY);
|
|
||||||
void cancelWorldPreload();
|
|
||||||
void saveLastWorldInfo(uint32_t mapId, const std::string& mapName, float serverX, float serverY);
|
|
||||||
struct LastWorldInfo { uint32_t mapId = 0; std::string mapName; float x = 0, y = 0; bool valid = false; };
|
|
||||||
LastWorldInfo loadLastWorldInfo() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace core
|
} // namespace core
|
||||||
|
|
|
||||||
125
include/core/world_loader.hpp
Normal file
125
include/core/world_loader.hpp
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <optional>
|
||||||
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace wowee {
|
||||||
|
|
||||||
|
namespace rendering { class Renderer; }
|
||||||
|
namespace pipeline { class AssetManager; class DBCLayout; }
|
||||||
|
namespace game { class GameHandler; class World; }
|
||||||
|
namespace addons { class AddonManager; }
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
class Application;
|
||||||
|
class EntitySpawner;
|
||||||
|
class AppearanceComposer;
|
||||||
|
class Window;
|
||||||
|
|
||||||
|
/// Handles terrain streaming, map transitions, world preloading,
|
||||||
|
/// and coordinate-aware tile management for online world entry.
|
||||||
|
class WorldLoader {
|
||||||
|
public:
|
||||||
|
WorldLoader(Application& app,
|
||||||
|
rendering::Renderer* renderer,
|
||||||
|
pipeline::AssetManager* assetManager,
|
||||||
|
game::GameHandler* gameHandler,
|
||||||
|
EntitySpawner* entitySpawner,
|
||||||
|
AppearanceComposer* appearanceComposer,
|
||||||
|
Window* window,
|
||||||
|
game::World* world,
|
||||||
|
addons::AddonManager* addonManager);
|
||||||
|
~WorldLoader();
|
||||||
|
|
||||||
|
// Main terrain loading — drives loading screen, WMO/ADT detection, player spawn
|
||||||
|
void loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float z);
|
||||||
|
|
||||||
|
// Process deferred world entry (called from Application::update each frame)
|
||||||
|
void processPendingEntry();
|
||||||
|
|
||||||
|
// Map name utilities
|
||||||
|
static const char* mapIdToName(uint32_t mapId);
|
||||||
|
static const char* mapDisplayName(uint32_t mapId);
|
||||||
|
|
||||||
|
// Background preloading — warms AssetManager file cache
|
||||||
|
void startWorldPreload(uint32_t mapId, const std::string& mapName,
|
||||||
|
float serverX, float serverY);
|
||||||
|
void cancelWorldPreload();
|
||||||
|
|
||||||
|
// Persistent world info for session-to-session preloading
|
||||||
|
void saveLastWorldInfo(uint32_t mapId, const std::string& mapName,
|
||||||
|
float serverX, float serverY);
|
||||||
|
struct LastWorldInfo {
|
||||||
|
uint32_t mapId = 0;
|
||||||
|
std::string mapName;
|
||||||
|
float x = 0, y = 0;
|
||||||
|
bool valid = false;
|
||||||
|
};
|
||||||
|
LastWorldInfo loadLastWorldInfo() const;
|
||||||
|
|
||||||
|
// State accessors
|
||||||
|
uint32_t getLoadedMapId() const { return loadedMapId_; }
|
||||||
|
bool isLoadingWorld() const { return loadingWorld_; }
|
||||||
|
bool hasPendingEntry() const { return pendingWorldEntry_.has_value(); }
|
||||||
|
|
||||||
|
// Get cached map name by ID (returns empty string if not found)
|
||||||
|
std::string getMapNameById(uint32_t mapId) const {
|
||||||
|
auto it = mapNameById_.find(mapId);
|
||||||
|
return (it != mapNameById_.end()) ? it->second : std::string{};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set pending world entry for deferred processing via processPendingEntry()
|
||||||
|
void setPendingEntry(uint32_t mapId, float x, float y, float z) {
|
||||||
|
pendingWorldEntry_ = PendingWorldEntry{mapId, x, y, z};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset methods (for logout / character switch)
|
||||||
|
void resetLoadedMap() { loadedMapId_ = 0xFFFFFFFF; }
|
||||||
|
void resetMapNameCache() { mapNameCacheLoaded_ = false; mapNameById_.clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Application& app_;
|
||||||
|
rendering::Renderer* renderer_;
|
||||||
|
pipeline::AssetManager* assetManager_;
|
||||||
|
game::GameHandler* gameHandler_;
|
||||||
|
EntitySpawner* entitySpawner_;
|
||||||
|
AppearanceComposer* appearanceComposer_;
|
||||||
|
Window* window_;
|
||||||
|
game::World* world_;
|
||||||
|
addons::AddonManager* addonManager_;
|
||||||
|
|
||||||
|
uint32_t loadedMapId_ = 0xFFFFFFFF; // Map ID of currently loaded terrain (0xFFFFFFFF = none)
|
||||||
|
uint32_t worldLoadGeneration_ = 0; // Incremented on each world entry to detect re-entrant loads
|
||||||
|
bool loadingWorld_ = false; // True while loadOnlineWorldTerrain is running
|
||||||
|
|
||||||
|
struct PendingWorldEntry {
|
||||||
|
uint32_t mapId; float x, y, z;
|
||||||
|
};
|
||||||
|
std::optional<PendingWorldEntry> pendingWorldEntry_;
|
||||||
|
|
||||||
|
// Map.dbc name cache (loaded once per session)
|
||||||
|
bool mapNameCacheLoaded_ = false;
|
||||||
|
std::unordered_map<uint32_t, std::string> mapNameById_;
|
||||||
|
|
||||||
|
// Background world preloader — warms AssetManager file cache for the
|
||||||
|
// expected world before the user clicks Enter World.
|
||||||
|
struct WorldPreload {
|
||||||
|
uint32_t mapId = 0;
|
||||||
|
std::string mapName;
|
||||||
|
int centerTileX = 0;
|
||||||
|
int centerTileY = 0;
|
||||||
|
std::atomic<bool> cancel{false};
|
||||||
|
std::vector<std::thread> workers;
|
||||||
|
};
|
||||||
|
std::unique_ptr<WorldPreload> worldPreload_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace wowee
|
||||||
File diff suppressed because it is too large
Load diff
1217
src/core/world_loader.cpp
Normal file
1217
src/core/world_loader.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue