refactor(config): 移除平台检测和配置相关代码
将应用配置信息移至Application类,移除平台检测和配置相关文件 简化ShaderManager的初始化逻辑,使用相对路径替代平台检测
This commit is contained in:
parent
61dea772f7
commit
d2660a86bb
|
|
@ -1,10 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <extra2d/config/app_config.h>
|
|
||||||
#include <extra2d/core/module.h>
|
#include <extra2d/core/module.h>
|
||||||
#include <extra2d/core/registry.h>
|
#include <extra2d/core/registry.h>
|
||||||
#include <extra2d/core/service_locator.h>
|
#include <extra2d/core/service_locator.h>
|
||||||
#include <extra2d/core/types.h>
|
#include <extra2d/core/types.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -25,6 +25,13 @@ public:
|
||||||
Application(const Application &) = delete;
|
Application(const Application &) = delete;
|
||||||
Application &operator=(const Application &) = delete;
|
Application &operator=(const Application &) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 应用信息
|
||||||
|
*/
|
||||||
|
std::string appName = "Extra2D App";
|
||||||
|
std::string appVersion = "1.0.0";
|
||||||
|
std::string organization = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 注册模块
|
* @brief 注册模块
|
||||||
* @tparam T 模块类型
|
* @tparam T 模块类型
|
||||||
|
|
@ -48,13 +55,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化(带配置)
|
|
||||||
* @param config 应用配置
|
|
||||||
* @return 初始化成功返回 true
|
|
||||||
*/
|
|
||||||
bool init(const AppConfig &config);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 关闭
|
* @brief 关闭
|
||||||
*/
|
*/
|
||||||
|
|
@ -131,8 +131,6 @@ private:
|
||||||
int frameCount_ = 0;
|
int frameCount_ = 0;
|
||||||
float fpsTimer_ = 0.0f;
|
float fpsTimer_ = 0.0f;
|
||||||
int currentFps_ = 0;
|
int currentFps_ = 0;
|
||||||
|
|
||||||
AppConfig appConfig_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace extra2d
|
} // namespace extra2d
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <extra2d/config/platform_config.h>
|
|
||||||
#include <extra2d/core/types.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace extra2d {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file app_config.h
|
|
||||||
* @brief 应用级别配置
|
|
||||||
*
|
|
||||||
* 本文件仅包含应用级别的配置项,不包含任何模块特定配置。
|
|
||||||
* 各模块应该在自己的模块文件中定义配置结构,并实现 IModuleConfig 接口。
|
|
||||||
*
|
|
||||||
* 模块配置通过 ModuleRegistry 注册,由 ConfigManager 统一管理。
|
|
||||||
* 这种设计遵循开闭原则,新增模块无需修改引擎核心代码。
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 应用配置结构体
|
|
||||||
* 仅包含应用级别的配置项,模块配置由各模块自行管理
|
|
||||||
*/
|
|
||||||
struct AppConfig {
|
|
||||||
std::string appName = "Extra2D App";
|
|
||||||
std::string appVersion = "1.0.0";
|
|
||||||
std::string organization = "";
|
|
||||||
std::string configFile = "config.json";
|
|
||||||
PlatformType targetPlatform = PlatformType::Auto;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 创建默认配置
|
|
||||||
* @return 默认的应用配置实例
|
|
||||||
*/
|
|
||||||
static AppConfig createDefault();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 验证配置的有效性
|
|
||||||
* @return 如果配置有效返回 true,否则返回 false
|
|
||||||
*/
|
|
||||||
bool validate() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 重置为默认值
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 合并另一个配置(非默认值覆盖当前值)
|
|
||||||
* @param other 要合并的配置
|
|
||||||
*/
|
|
||||||
void merge(const AppConfig& other);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查配置是否有效
|
|
||||||
* @return 如果所有必要字段都有效返回 true
|
|
||||||
*/
|
|
||||||
bool isValid() const { return validate(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <extra2d/core/types.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace extra2d {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file platform_config.h
|
|
||||||
* @brief 平台配置接口
|
|
||||||
*
|
|
||||||
* 平台配置只提供平台能力信息,不再直接修改应用配置。
|
|
||||||
* 各模块通过 IModuleConfig::applyPlatformConstraints() 处理平台约束。
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 平台类型枚举
|
|
||||||
*/
|
|
||||||
enum class PlatformType {
|
|
||||||
Auto,
|
|
||||||
Windows,
|
|
||||||
Switch,
|
|
||||||
Linux,
|
|
||||||
macOS
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 平台能力结构
|
|
||||||
*/
|
|
||||||
struct PlatformCapabilities {
|
|
||||||
bool supportsWindowed = true;
|
|
||||||
bool supportsFullscreen = true;
|
|
||||||
bool supportsBorderless = true;
|
|
||||||
bool supportsCursor = true;
|
|
||||||
bool supportsCursorHide = true;
|
|
||||||
bool supportsDPIAwareness = true;
|
|
||||||
bool supportsVSync = true;
|
|
||||||
bool supportsMultiMonitor = true;
|
|
||||||
bool supportsClipboard = true;
|
|
||||||
bool supportsGamepad = true;
|
|
||||||
bool supportsTouch = false;
|
|
||||||
bool supportsKeyboard = true;
|
|
||||||
bool supportsMouse = true;
|
|
||||||
bool supportsResize = true;
|
|
||||||
bool supportsHighDPI = true;
|
|
||||||
int maxTextureSize = 16384;
|
|
||||||
int preferredScreenWidth = 1920;
|
|
||||||
int preferredScreenHeight = 1080;
|
|
||||||
float defaultDPI = 96.0f;
|
|
||||||
|
|
||||||
bool hasWindowSupport() const { return supportsWindowed || supportsFullscreen || supportsBorderless; }
|
|
||||||
bool hasInputSupport() const { return supportsKeyboard || supportsMouse || supportsGamepad || supportsTouch; }
|
|
||||||
bool isDesktop() const { return supportsKeyboard && supportsMouse && supportsWindowed; }
|
|
||||||
bool isConsole() const { return !supportsWindowed && supportsGamepad; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 平台配置抽象接口
|
|
||||||
*/
|
|
||||||
class PlatformConfig {
|
|
||||||
public:
|
|
||||||
virtual ~PlatformConfig() = default;
|
|
||||||
|
|
||||||
virtual PlatformType platformType() const = 0;
|
|
||||||
virtual const char* platformName() const = 0;
|
|
||||||
virtual const PlatformCapabilities& capabilities() const = 0;
|
|
||||||
|
|
||||||
virtual int getRecommendedWidth() const = 0;
|
|
||||||
virtual int getRecommendedHeight() const = 0;
|
|
||||||
virtual bool isResolutionSupported(int width, int height) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 创建平台配置实例
|
|
||||||
* @param type 平台类型,默认为 Auto(自动检测)
|
|
||||||
* @return 平台配置的智能指针
|
|
||||||
*/
|
|
||||||
UniquePtr<PlatformConfig> createPlatformConfig(PlatformType type = PlatformType::Auto);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台类型名称
|
|
||||||
* @param type 平台类型枚举值
|
|
||||||
* @return 平台名称字符串
|
|
||||||
*/
|
|
||||||
const char* getPlatformTypeName(PlatformType type);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <extra2d/config/app_config.h>
|
|
||||||
#include <extra2d/config/platform_config.h>
|
|
||||||
#include <extra2d/core/types.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace extra2d {
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// 平台检测器工具类
|
|
||||||
// ============================================================================
|
|
||||||
class PlatformDetector {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief 检测当前运行平台
|
|
||||||
* @return 当前平台的类型
|
|
||||||
*/
|
|
||||||
static PlatformType detect();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台名称字符串
|
|
||||||
* @return 平台名称(如 "Windows", "Linux", "macOS", "Switch")
|
|
||||||
*/
|
|
||||||
static const char* platformName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取指定平台类型的名称
|
|
||||||
* @param type 平台类型
|
|
||||||
* @return 平台名称字符串
|
|
||||||
*/
|
|
||||||
static const char* platformName(PlatformType type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否为桌面平台
|
|
||||||
* @return 如果是桌面平台返回 true
|
|
||||||
*/
|
|
||||||
static bool isDesktopPlatform();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否为游戏主机平台
|
|
||||||
* @return 如果是游戏主机平台返回 true
|
|
||||||
*/
|
|
||||||
static bool isConsolePlatform();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否为移动平台
|
|
||||||
* @return 如果是移动平台返回 true
|
|
||||||
*/
|
|
||||||
static bool isMobilePlatform();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的能力
|
|
||||||
* @return 平台能力结构
|
|
||||||
*/
|
|
||||||
static PlatformCapabilities capabilities();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取指定平台的能力
|
|
||||||
* @param type 平台类型
|
|
||||||
* @return 平台能力结构
|
|
||||||
*/
|
|
||||||
static PlatformCapabilities capabilities(PlatformType type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的默认配置
|
|
||||||
* @return 平台默认的应用配置
|
|
||||||
*/
|
|
||||||
static AppConfig platformDefaults();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取指定平台的默认配置
|
|
||||||
* @param type 平台类型
|
|
||||||
* @return 平台默认的应用配置
|
|
||||||
*/
|
|
||||||
static AppConfig platformDefaults(PlatformType type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的推荐分辨率
|
|
||||||
* @param width 输出宽度
|
|
||||||
* @param height 输出高度
|
|
||||||
*/
|
|
||||||
static void getRecommendedResolution(int& width, int& height);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的默认 DPI
|
|
||||||
* @return 默认 DPI 值
|
|
||||||
*/
|
|
||||||
static float getDefaultDPI();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否支持指定功能
|
|
||||||
* @param feature 功能名称
|
|
||||||
* @return 如果支持返回 true
|
|
||||||
*/
|
|
||||||
static bool supportsFeature(const std::string& feature);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取系统内存大小
|
|
||||||
* @return 系统内存大小(MB),如果无法获取返回 0
|
|
||||||
*/
|
|
||||||
static int getSystemMemoryMB();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取 CPU 核心数
|
|
||||||
* @return CPU 核心数
|
|
||||||
*/
|
|
||||||
static int getCPUCoreCount();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查是否支持多线程渲染
|
|
||||||
* @return 如果支持返回 true
|
|
||||||
*/
|
|
||||||
static bool supportsMultithreadedRendering();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的配置路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 配置文件目录路径
|
|
||||||
*/
|
|
||||||
static std::string getConfigPath(const std::string& appName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的存档路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 存档文件目录路径
|
|
||||||
*/
|
|
||||||
static std::string getSavePath(const std::string& appName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的缓存路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 缓存文件目录路径
|
|
||||||
*/
|
|
||||||
static std::string getCachePath(const std::string& appName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的日志路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 日志文件目录路径
|
|
||||||
*/
|
|
||||||
static std::string getLogPath(const std::string& appName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的资源路径(Shader、纹理等)
|
|
||||||
* Switch平台使用romfs,其他平台使用相对路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 资源目录路径
|
|
||||||
*/
|
|
||||||
static std::string getResourcePath(const std::string& appName = "");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的Shader路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return Shader目录路径
|
|
||||||
*/
|
|
||||||
static std::string getShaderPath(const std::string& appName = "");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的Shader缓存路径
|
|
||||||
* Switch平台使用sdmc,其他平台使用系统缓存目录
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return Shader缓存目录路径
|
|
||||||
*/
|
|
||||||
static std::string getShaderCachePath(const std::string& appName = "");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否使用romfs(只读文件系统)
|
|
||||||
* @return 使用romfs返回true
|
|
||||||
*/
|
|
||||||
static bool usesRomfs();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否支持热重载
|
|
||||||
* Switch平台不支持热重载(romfs只读)
|
|
||||||
* @return 支持热重载返回true
|
|
||||||
*/
|
|
||||||
static bool supportsHotReload();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否为小端字节序
|
|
||||||
* @return 如果是小端字节序返回 true
|
|
||||||
*/
|
|
||||||
static bool isLittleEndian();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否为大端字节序
|
|
||||||
* @return 如果是大端字节序返回 true
|
|
||||||
*/
|
|
||||||
static bool isBigEndian();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台信息摘要
|
|
||||||
* @return 平台信息字符串
|
|
||||||
*/
|
|
||||||
static std::string getPlatformSummary();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static PlatformCapabilities getWindowsCapabilities();
|
|
||||||
static PlatformCapabilities getLinuxCapabilities();
|
|
||||||
static PlatformCapabilities getMacOSCapabilities();
|
|
||||||
static PlatformCapabilities getSwitchCapabilities();
|
|
||||||
|
|
||||||
static AppConfig getWindowsDefaults();
|
|
||||||
static AppConfig getLinuxDefaults();
|
|
||||||
static AppConfig getMacOSDefaults();
|
|
||||||
static AppConfig getSwitchDefaults();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -10,10 +10,7 @@
|
||||||
#include <extra2d/core/module.h>
|
#include <extra2d/core/module.h>
|
||||||
#include <extra2d/core/registry.h>
|
#include <extra2d/core/registry.h>
|
||||||
|
|
||||||
// Config
|
// Config removed - app info now in Application class
|
||||||
#include <extra2d/config/app_config.h>
|
|
||||||
#include <extra2d/config/platform_config.h>
|
|
||||||
#include <extra2d/config/platform_detector.h>
|
|
||||||
|
|
||||||
// Platform
|
// Platform
|
||||||
#include <extra2d/platform/iinput.h>
|
#include <extra2d/platform/iinput.h>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <extra2d/config/platform_detector.h>
|
|
||||||
#include <extra2d/graphics/shader/shader_cache.h>
|
#include <extra2d/graphics/shader/shader_cache.h>
|
||||||
#include <extra2d/graphics/shader/shader_hot_reloader.h>
|
#include <extra2d/graphics/shader/shader_hot_reloader.h>
|
||||||
#include <extra2d/graphics/shader/shader_interface.h>
|
#include <extra2d/graphics/shader/shader_interface.h>
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,10 @@ Application::~Application() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::init() {
|
bool Application::init() {
|
||||||
AppConfig cfg;
|
|
||||||
return init(cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Application::init(const AppConfig &config) {
|
|
||||||
if (initialized_) {
|
if (initialized_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
appConfig_ = config;
|
|
||||||
|
|
||||||
// 初始化所有模块(拓扑排序)
|
// 初始化所有模块(拓扑排序)
|
||||||
// 服务通过 E2D_AUTO_REGISTER_SERVICE 宏自动注册
|
// 服务通过 E2D_AUTO_REGISTER_SERVICE 宏自动注册
|
||||||
if (!Registry::instance().init()) {
|
if (!Registry::instance().init()) {
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
#include <extra2d/config/app_config.h>
|
|
||||||
#include <extra2d/utils/logger.h>
|
|
||||||
|
|
||||||
namespace extra2d {
|
|
||||||
|
|
||||||
AppConfig AppConfig::createDefault() {
|
|
||||||
AppConfig config;
|
|
||||||
|
|
||||||
config.appName = "Extra2D App";
|
|
||||||
config.appVersion = "1.0.0";
|
|
||||||
config.organization = "";
|
|
||||||
config.configFile = "config.json";
|
|
||||||
config.targetPlatform = PlatformType::Auto;
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppConfig::validate() const {
|
|
||||||
if (appName.empty()) {
|
|
||||||
E2D_LOG_ERROR("Config validation failed: app name cannot be empty");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (appVersion.empty()) {
|
|
||||||
E2D_LOG_ERROR("Config validation failed: app version cannot be empty");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (configFile.empty()) {
|
|
||||||
E2D_LOG_ERROR("Config validation failed: config file cannot be empty");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::reset() {
|
|
||||||
*this = createDefault();
|
|
||||||
E2D_LOG_INFO("App config reset to defaults");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::merge(const AppConfig& other) {
|
|
||||||
if (other.appName != "Extra2D App") {
|
|
||||||
appName = other.appName;
|
|
||||||
}
|
|
||||||
if (other.appVersion != "1.0.0") {
|
|
||||||
appVersion = other.appVersion;
|
|
||||||
}
|
|
||||||
if (!other.organization.empty()) {
|
|
||||||
organization = other.organization;
|
|
||||||
}
|
|
||||||
if (other.configFile != "config.json") {
|
|
||||||
configFile = other.configFile;
|
|
||||||
}
|
|
||||||
if (other.targetPlatform != PlatformType::Auto) {
|
|
||||||
targetPlatform = other.targetPlatform;
|
|
||||||
}
|
|
||||||
|
|
||||||
E2D_LOG_INFO("Merged app config");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,224 +0,0 @@
|
||||||
#include <extra2d/config/app_config.h>
|
|
||||||
#include <extra2d/config/platform_config.h>
|
|
||||||
#include <extra2d/utils/logger.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
#include <switch.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace extra2d {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class WindowsPlatformConfig : public PlatformConfig {
|
|
||||||
public:
|
|
||||||
WindowsPlatformConfig() {
|
|
||||||
caps_.supportsWindowed = true;
|
|
||||||
caps_.supportsFullscreen = true;
|
|
||||||
caps_.supportsBorderless = true;
|
|
||||||
caps_.supportsCursor = true;
|
|
||||||
caps_.supportsCursorHide = true;
|
|
||||||
caps_.supportsDPIAwareness = true;
|
|
||||||
caps_.supportsVSync = true;
|
|
||||||
caps_.supportsMultiMonitor = true;
|
|
||||||
caps_.supportsClipboard = true;
|
|
||||||
caps_.supportsGamepad = true;
|
|
||||||
caps_.supportsTouch = false;
|
|
||||||
caps_.supportsKeyboard = true;
|
|
||||||
caps_.supportsMouse = true;
|
|
||||||
caps_.supportsResize = true;
|
|
||||||
caps_.supportsHighDPI = true;
|
|
||||||
caps_.maxTextureSize = 16384;
|
|
||||||
caps_.preferredScreenWidth = 1920;
|
|
||||||
caps_.preferredScreenHeight = 1080;
|
|
||||||
caps_.defaultDPI = 96.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Windows; }
|
|
||||||
const char *platformName() const override { return "Windows"; }
|
|
||||||
const PlatformCapabilities &capabilities() const override { return caps_; }
|
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
|
||||||
return width >= 320 && height >= 240 && width <= caps_.maxTextureSize &&
|
|
||||||
height <= caps_.maxTextureSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PlatformCapabilities caps_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinuxPlatformConfig : public PlatformConfig {
|
|
||||||
public:
|
|
||||||
LinuxPlatformConfig() {
|
|
||||||
caps_.supportsWindowed = true;
|
|
||||||
caps_.supportsFullscreen = true;
|
|
||||||
caps_.supportsBorderless = true;
|
|
||||||
caps_.supportsCursor = true;
|
|
||||||
caps_.supportsCursorHide = true;
|
|
||||||
caps_.supportsDPIAwareness = true;
|
|
||||||
caps_.supportsVSync = true;
|
|
||||||
caps_.supportsMultiMonitor = true;
|
|
||||||
caps_.supportsClipboard = true;
|
|
||||||
caps_.supportsGamepad = true;
|
|
||||||
caps_.supportsTouch = false;
|
|
||||||
caps_.supportsKeyboard = true;
|
|
||||||
caps_.supportsMouse = true;
|
|
||||||
caps_.supportsResize = true;
|
|
||||||
caps_.supportsHighDPI = true;
|
|
||||||
caps_.maxTextureSize = 16384;
|
|
||||||
caps_.preferredScreenWidth = 1920;
|
|
||||||
caps_.preferredScreenHeight = 1080;
|
|
||||||
caps_.defaultDPI = 96.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Linux; }
|
|
||||||
const char *platformName() const override { return "Linux"; }
|
|
||||||
const PlatformCapabilities &capabilities() const override { return caps_; }
|
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
|
||||||
return width >= 320 && height >= 240;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PlatformCapabilities caps_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacOSPlatformConfig : public PlatformConfig {
|
|
||||||
public:
|
|
||||||
MacOSPlatformConfig() {
|
|
||||||
caps_.supportsWindowed = true;
|
|
||||||
caps_.supportsFullscreen = true;
|
|
||||||
caps_.supportsBorderless = true;
|
|
||||||
caps_.supportsCursor = true;
|
|
||||||
caps_.supportsCursorHide = true;
|
|
||||||
caps_.supportsDPIAwareness = true;
|
|
||||||
caps_.supportsVSync = true;
|
|
||||||
caps_.supportsMultiMonitor = true;
|
|
||||||
caps_.supportsClipboard = true;
|
|
||||||
caps_.supportsGamepad = true;
|
|
||||||
caps_.supportsTouch = false;
|
|
||||||
caps_.supportsKeyboard = true;
|
|
||||||
caps_.supportsMouse = true;
|
|
||||||
caps_.supportsResize = true;
|
|
||||||
caps_.supportsHighDPI = true;
|
|
||||||
caps_.maxTextureSize = 16384;
|
|
||||||
caps_.preferredScreenWidth = 1920;
|
|
||||||
caps_.preferredScreenHeight = 1080;
|
|
||||||
caps_.defaultDPI = 144.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::macOS; }
|
|
||||||
const char *platformName() const override { return "macOS"; }
|
|
||||||
const PlatformCapabilities &capabilities() const override { return caps_; }
|
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
|
||||||
return width >= 320 && height >= 240;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PlatformCapabilities caps_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SwitchPlatformConfig : public PlatformConfig {
|
|
||||||
public:
|
|
||||||
SwitchPlatformConfig() {
|
|
||||||
caps_.supportsWindowed = false;
|
|
||||||
caps_.supportsFullscreen = true;
|
|
||||||
caps_.supportsBorderless = false;
|
|
||||||
caps_.supportsCursor = false;
|
|
||||||
caps_.supportsCursorHide = false;
|
|
||||||
caps_.supportsDPIAwareness = false;
|
|
||||||
caps_.supportsVSync = true;
|
|
||||||
caps_.supportsMultiMonitor = false;
|
|
||||||
caps_.supportsClipboard = false;
|
|
||||||
caps_.supportsGamepad = true;
|
|
||||||
caps_.supportsTouch = true;
|
|
||||||
caps_.supportsKeyboard = false;
|
|
||||||
caps_.supportsMouse = false;
|
|
||||||
caps_.supportsResize = false;
|
|
||||||
caps_.supportsHighDPI = false;
|
|
||||||
caps_.maxTextureSize = 8192;
|
|
||||||
caps_.preferredScreenWidth = 1920;
|
|
||||||
caps_.preferredScreenHeight = 1080;
|
|
||||||
caps_.defaultDPI = 96.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Switch; }
|
|
||||||
const char *platformName() const override { return "Nintendo Switch"; }
|
|
||||||
const PlatformCapabilities &capabilities() const override { return caps_; }
|
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
|
||||||
return (width == 1920 && height == 1080) ||
|
|
||||||
(width == 1280 && height == 720);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PlatformCapabilities caps_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UniquePtr<PlatformConfig> createPlatformConfig(PlatformType type) {
|
|
||||||
if (type == PlatformType::Auto) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
type = PlatformType::Windows;
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
type = PlatformType::Switch;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
type = PlatformType::Linux;
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
type = PlatformType::macOS;
|
|
||||||
#else
|
|
||||||
type = PlatformType::Windows;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case PlatformType::Windows:
|
|
||||||
E2D_LOG_INFO("Creating Windows platform config");
|
|
||||||
return makeUnique<WindowsPlatformConfig>();
|
|
||||||
case PlatformType::Switch:
|
|
||||||
E2D_LOG_INFO("Creating Nintendo Switch platform config");
|
|
||||||
return makeUnique<SwitchPlatformConfig>();
|
|
||||||
case PlatformType::Linux:
|
|
||||||
E2D_LOG_INFO("Creating Linux platform config");
|
|
||||||
return makeUnique<LinuxPlatformConfig>();
|
|
||||||
case PlatformType::macOS:
|
|
||||||
E2D_LOG_INFO("Creating macOS platform config");
|
|
||||||
return makeUnique<MacOSPlatformConfig>();
|
|
||||||
default:
|
|
||||||
E2D_LOG_WARN("Unknown platform type, defaulting to Windows");
|
|
||||||
return makeUnique<WindowsPlatformConfig>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *getPlatformTypeName(PlatformType type) {
|
|
||||||
switch (type) {
|
|
||||||
case PlatformType::Auto:
|
|
||||||
return "Auto";
|
|
||||||
case PlatformType::Windows:
|
|
||||||
return "Windows";
|
|
||||||
case PlatformType::Switch:
|
|
||||||
return "Switch";
|
|
||||||
case PlatformType::Linux:
|
|
||||||
return "Linux";
|
|
||||||
case PlatformType::macOS:
|
|
||||||
return "macOS";
|
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,678 +0,0 @@
|
||||||
#include <extra2d/config/platform_detector.h>
|
|
||||||
#include <extra2d/config/platform_config.h>
|
|
||||||
#include <extra2d/utils/logger.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#include <psapi.h>
|
|
||||||
#elif defined(__linux__)
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
#include <switch.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace extra2d {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检测当前运行平台
|
|
||||||
* 使用编译时宏判断当前平台类型
|
|
||||||
* @return 当前平台的类型枚举值
|
|
||||||
*/
|
|
||||||
PlatformType PlatformDetector::detect() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
return PlatformType::Windows;
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return PlatformType::Switch;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
return PlatformType::Linux;
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
return PlatformType::macOS;
|
|
||||||
#else
|
|
||||||
return PlatformType::Windows;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台名称字符串
|
|
||||||
* @return 平台名称(如 "Windows", "Linux", "macOS", "Switch")
|
|
||||||
*/
|
|
||||||
const char* PlatformDetector::platformName() {
|
|
||||||
return platformName(detect());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取指定平台类型的名称
|
|
||||||
* @param type 平台类型
|
|
||||||
* @return 平台名称字符串
|
|
||||||
*/
|
|
||||||
const char* PlatformDetector::platformName(PlatformType type) {
|
|
||||||
switch (type) {
|
|
||||||
case PlatformType::Windows: return "Windows";
|
|
||||||
case PlatformType::Switch: return "Nintendo Switch";
|
|
||||||
case PlatformType::Linux: return "Linux";
|
|
||||||
case PlatformType::macOS: return "macOS";
|
|
||||||
case PlatformType::Auto: return "Auto";
|
|
||||||
default: return "Unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否为桌面平台
|
|
||||||
* @return 如果是桌面平台返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::isDesktopPlatform() {
|
|
||||||
PlatformType type = detect();
|
|
||||||
return type == PlatformType::Windows ||
|
|
||||||
type == PlatformType::Linux ||
|
|
||||||
type == PlatformType::macOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否为游戏主机平台
|
|
||||||
* @return 如果是游戏主机平台返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::isConsolePlatform() {
|
|
||||||
return detect() == PlatformType::Switch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否为移动平台
|
|
||||||
* @return 如果是移动平台返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::isMobilePlatform() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的能力
|
|
||||||
* @return 平台能力结构
|
|
||||||
*/
|
|
||||||
PlatformCapabilities PlatformDetector::capabilities() {
|
|
||||||
return capabilities(detect());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取指定平台的能力
|
|
||||||
* @param type 平台类型
|
|
||||||
* @return 平台能力结构
|
|
||||||
*/
|
|
||||||
PlatformCapabilities PlatformDetector::capabilities(PlatformType type) {
|
|
||||||
switch (type) {
|
|
||||||
case PlatformType::Windows:
|
|
||||||
return getWindowsCapabilities();
|
|
||||||
case PlatformType::Switch:
|
|
||||||
return getSwitchCapabilities();
|
|
||||||
case PlatformType::Linux:
|
|
||||||
return getLinuxCapabilities();
|
|
||||||
case PlatformType::macOS:
|
|
||||||
return getMacOSCapabilities();
|
|
||||||
default:
|
|
||||||
return getWindowsCapabilities();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的默认配置
|
|
||||||
* @return 平台默认的应用配置
|
|
||||||
*/
|
|
||||||
AppConfig PlatformDetector::platformDefaults() {
|
|
||||||
return platformDefaults(detect());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取指定平台的默认配置
|
|
||||||
* @param type 平台类型
|
|
||||||
* @return 平台默认的应用配置
|
|
||||||
*/
|
|
||||||
AppConfig PlatformDetector::platformDefaults(PlatformType type) {
|
|
||||||
switch (type) {
|
|
||||||
case PlatformType::Windows:
|
|
||||||
return getWindowsDefaults();
|
|
||||||
case PlatformType::Switch:
|
|
||||||
return getSwitchDefaults();
|
|
||||||
case PlatformType::Linux:
|
|
||||||
return getLinuxDefaults();
|
|
||||||
case PlatformType::macOS:
|
|
||||||
return getMacOSDefaults();
|
|
||||||
default:
|
|
||||||
return AppConfig::createDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的推荐分辨率
|
|
||||||
* @param width 输出宽度
|
|
||||||
* @param height 输出高度
|
|
||||||
*/
|
|
||||||
void PlatformDetector::getRecommendedResolution(int& width, int& height) {
|
|
||||||
PlatformCapabilities caps = capabilities();
|
|
||||||
width = caps.preferredScreenWidth;
|
|
||||||
height = caps.preferredScreenHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取当前平台的默认 DPI
|
|
||||||
* @return 默认 DPI 值
|
|
||||||
*/
|
|
||||||
float PlatformDetector::getDefaultDPI() {
|
|
||||||
return capabilities().defaultDPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查当前平台是否支持指定功能
|
|
||||||
* @param feature 功能名称
|
|
||||||
* @return 如果支持返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::supportsFeature(const std::string& feature) {
|
|
||||||
PlatformCapabilities caps = capabilities();
|
|
||||||
|
|
||||||
if (feature == "windowed") return caps.supportsWindowed;
|
|
||||||
if (feature == "fullscreen") return caps.supportsFullscreen;
|
|
||||||
if (feature == "borderless") return caps.supportsBorderless;
|
|
||||||
if (feature == "cursor") return caps.supportsCursor;
|
|
||||||
if (feature == "cursor_hide") return caps.supportsCursorHide;
|
|
||||||
if (feature == "dpi_awareness") return caps.supportsDPIAwareness;
|
|
||||||
if (feature == "vsync") return caps.supportsVSync;
|
|
||||||
if (feature == "multi_monitor") return caps.supportsMultiMonitor;
|
|
||||||
if (feature == "clipboard") return caps.supportsClipboard;
|
|
||||||
if (feature == "gamepad") return caps.supportsGamepad;
|
|
||||||
if (feature == "touch") return caps.supportsTouch;
|
|
||||||
if (feature == "keyboard") return caps.supportsKeyboard;
|
|
||||||
if (feature == "mouse") return caps.supportsMouse;
|
|
||||||
if (feature == "resize") return caps.supportsResize;
|
|
||||||
if (feature == "high_dpi") return caps.supportsHighDPI;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取系统内存大小
|
|
||||||
* @return 系统内存大小(MB),如果无法获取返回 0
|
|
||||||
*/
|
|
||||||
int PlatformDetector::getSystemMemoryMB() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
MEMORYSTATUSEX status;
|
|
||||||
status.dwLength = sizeof(status);
|
|
||||||
if (GlobalMemoryStatusEx(&status)) {
|
|
||||||
return static_cast<int>(status.ullTotalPhys / (1024 * 1024));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return 4096;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
struct sysinfo info;
|
|
||||||
if (sysinfo(&info) == 0) {
|
|
||||||
return static_cast<int>(info.totalram * info.mem_unit / (1024 * 1024));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
int mib[2] = {CTL_HW, HW_MEMSIZE};
|
|
||||||
int64_t memSize = 0;
|
|
||||||
size_t length = sizeof(memSize);
|
|
||||||
if (sysctl(mib, 2, &memSize, &length, nullptr, 0) == 0) {
|
|
||||||
return static_cast<int>(memSize / (1024 * 1024));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取 CPU 核心数
|
|
||||||
* @return CPU 核心数
|
|
||||||
*/
|
|
||||||
int PlatformDetector::getCPUCoreCount() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEM_INFO sysinfo;
|
|
||||||
GetSystemInfo(&sysinfo);
|
|
||||||
return static_cast<int>(sysinfo.dwNumberOfProcessors);
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return 4;
|
|
||||||
#elif defined(__linux__) || defined(__APPLE__)
|
|
||||||
long cores = sysconf(_SC_NPROCESSORS_ONLN);
|
|
||||||
return static_cast<int>(cores > 0 ? cores : 1);
|
|
||||||
#else
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查是否支持多线程渲染
|
|
||||||
* @return 如果支持返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::supportsMultithreadedRendering() {
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return getCPUCoreCount() >= 2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的配置路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 配置文件目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getConfigPath(const std::string& appName) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (SUCCEEDED(SHGetFolderPathA(nullptr, CSIDL_APPDATA, nullptr, 0, path))) {
|
|
||||||
return std::string(path) + "\\" + appName + "\\config";
|
|
||||||
}
|
|
||||||
return ".\\config";
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return "sdmc:/config/" + appName;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
const char* configHome = getenv("XDG_CONFIG_HOME");
|
|
||||||
if (configHome && configHome[0] != '\0') {
|
|
||||||
return std::string(configHome) + "/" + appName;
|
|
||||||
}
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/.config/" + appName;
|
|
||||||
}
|
|
||||||
return "./config";
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/Library/Application Support/" + appName + "/config";
|
|
||||||
}
|
|
||||||
return "./config";
|
|
||||||
#else
|
|
||||||
return "./config";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的存档路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 存档文件目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getSavePath(const std::string& appName) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (SUCCEEDED(SHGetFolderPathA(nullptr, CSIDL_APPDATA, nullptr, 0, path))) {
|
|
||||||
return std::string(path) + "\\" + appName + "\\saves";
|
|
||||||
}
|
|
||||||
return ".\\saves";
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return "sdmc:/saves/" + appName;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
const char* dataHome = getenv("XDG_DATA_HOME");
|
|
||||||
if (dataHome && dataHome[0] != '\0') {
|
|
||||||
return std::string(dataHome) + "/" + appName + "/saves";
|
|
||||||
}
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/.local/share/" + appName + "/saves";
|
|
||||||
}
|
|
||||||
return "./saves";
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/Library/Application Support/" + appName + "/saves";
|
|
||||||
}
|
|
||||||
return "./saves";
|
|
||||||
#else
|
|
||||||
return "./saves";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的缓存路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 缓存文件目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getCachePath(const std::string& appName) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (SUCCEEDED(SHGetFolderPathA(nullptr, CSIDL_LOCAL_APPDATA, nullptr, 0, path))) {
|
|
||||||
return std::string(path) + "\\" + appName + "\\cache";
|
|
||||||
}
|
|
||||||
return ".\\cache";
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return "sdmc:/cache/" + appName;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
const char* cacheHome = getenv("XDG_CACHE_HOME");
|
|
||||||
if (cacheHome && cacheHome[0] != '\0') {
|
|
||||||
return std::string(cacheHome) + "/" + appName;
|
|
||||||
}
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/.cache/" + appName;
|
|
||||||
}
|
|
||||||
return "./cache";
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/Library/Caches/" + appName;
|
|
||||||
}
|
|
||||||
return "./cache";
|
|
||||||
#else
|
|
||||||
return "./cache";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的日志路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 日志文件目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getLogPath(const std::string& appName) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
char path[MAX_PATH];
|
|
||||||
if (SUCCEEDED(SHGetFolderPathA(nullptr, CSIDL_LOCAL_APPDATA, nullptr, 0, path))) {
|
|
||||||
return std::string(path) + "\\" + appName + "\\logs";
|
|
||||||
}
|
|
||||||
return ".\\logs";
|
|
||||||
#elif defined(__SWITCH__)
|
|
||||||
return "sdmc:/logs/" + appName;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
const char* cacheHome = getenv("XDG_CACHE_HOME");
|
|
||||||
if (cacheHome && cacheHome[0] != '\0') {
|
|
||||||
return std::string(cacheHome) + "/" + appName + "/logs";
|
|
||||||
}
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/.cache/" + appName + "/logs";
|
|
||||||
}
|
|
||||||
return "./logs";
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd) home = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
if (home) {
|
|
||||||
return std::string(home) + "/Library/Logs/" + appName;
|
|
||||||
}
|
|
||||||
return "./logs";
|
|
||||||
#else
|
|
||||||
return "./logs";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的资源路径(Shader、纹理等)
|
|
||||||
* Switch平台使用romfs,其他平台使用相对路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return 资源目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getResourcePath(const std::string& appName) {
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
(void)appName;
|
|
||||||
return "romfs:/";
|
|
||||||
#else
|
|
||||||
(void)appName;
|
|
||||||
return "./resources/";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的Shader路径
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return Shader目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getShaderPath(const std::string& appName) {
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
(void)appName;
|
|
||||||
return "romfs:/shaders/";
|
|
||||||
#else
|
|
||||||
(void)appName;
|
|
||||||
return "./shaders/";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台特定的Shader缓存路径
|
|
||||||
* Switch平台使用sdmc,其他平台使用系统缓存目录
|
|
||||||
* @param appName 应用名称
|
|
||||||
* @return Shader缓存目录路径
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getShaderCachePath(const std::string& appName) {
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
std::string name = appName.empty() ? "extra2d" : appName;
|
|
||||||
return "sdmc:/cache/" + name + "/shaders/";
|
|
||||||
#else
|
|
||||||
return getCachePath(appName.empty() ? "extra2d" : appName) + "/shaders/";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否使用romfs(只读文件系统)
|
|
||||||
* @return 使用romfs返回true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::usesRomfs() {
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否支持热重载
|
|
||||||
* Switch平台不支持热重载(romfs只读)
|
|
||||||
* @return 支持热重载返回true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::supportsHotReload() {
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否为小端字节序
|
|
||||||
* @return 如果是小端字节序返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::isLittleEndian() {
|
|
||||||
union {
|
|
||||||
uint32_t i;
|
|
||||||
char c[4];
|
|
||||||
} test = {0x01020304};
|
|
||||||
return test.c[0] == 0x04;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查平台是否为大端字节序
|
|
||||||
* @return 如果是大端字节序返回 true
|
|
||||||
*/
|
|
||||||
bool PlatformDetector::isBigEndian() {
|
|
||||||
return !isLittleEndian();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取平台信息摘要
|
|
||||||
* @return 平台信息字符串
|
|
||||||
*/
|
|
||||||
std::string PlatformDetector::getPlatformSummary() {
|
|
||||||
std::string summary;
|
|
||||||
summary += "Platform: ";
|
|
||||||
summary += platformName();
|
|
||||||
summary += "\n";
|
|
||||||
summary += "Memory: ";
|
|
||||||
summary += std::to_string(getSystemMemoryMB());
|
|
||||||
summary += " MB\n";
|
|
||||||
summary += "CPU Cores: ";
|
|
||||||
summary += std::to_string(getCPUCoreCount());
|
|
||||||
summary += "\n";
|
|
||||||
summary += "Endianness: ";
|
|
||||||
summary += isLittleEndian() ? "Little Endian" : "Big Endian";
|
|
||||||
summary += "\n";
|
|
||||||
summary += "Desktop Platform: ";
|
|
||||||
summary += isDesktopPlatform() ? "Yes" : "No";
|
|
||||||
summary += "\n";
|
|
||||||
summary += "Console Platform: ";
|
|
||||||
summary += isConsolePlatform() ? "Yes" : "No";
|
|
||||||
summary += "\n";
|
|
||||||
summary += "Recommended Resolution: ";
|
|
||||||
int width, height;
|
|
||||||
getRecommendedResolution(width, height);
|
|
||||||
summary += std::to_string(width);
|
|
||||||
summary += "x";
|
|
||||||
summary += std::to_string(height);
|
|
||||||
summary += "\n";
|
|
||||||
summary += "Default DPI: ";
|
|
||||||
summary += std::to_string(static_cast<int>(getDefaultDPI()));
|
|
||||||
return summary;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformCapabilities PlatformDetector::getWindowsCapabilities() {
|
|
||||||
PlatformCapabilities caps;
|
|
||||||
caps.supportsWindowed = true;
|
|
||||||
caps.supportsFullscreen = true;
|
|
||||||
caps.supportsBorderless = true;
|
|
||||||
caps.supportsCursor = true;
|
|
||||||
caps.supportsCursorHide = true;
|
|
||||||
caps.supportsDPIAwareness = true;
|
|
||||||
caps.supportsVSync = true;
|
|
||||||
caps.supportsMultiMonitor = true;
|
|
||||||
caps.supportsClipboard = true;
|
|
||||||
caps.supportsGamepad = true;
|
|
||||||
caps.supportsTouch = false;
|
|
||||||
caps.supportsKeyboard = true;
|
|
||||||
caps.supportsMouse = true;
|
|
||||||
caps.supportsResize = true;
|
|
||||||
caps.supportsHighDPI = true;
|
|
||||||
caps.maxTextureSize = 16384;
|
|
||||||
caps.preferredScreenWidth = 1920;
|
|
||||||
caps.preferredScreenHeight = 1080;
|
|
||||||
caps.defaultDPI = 96.0f;
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformCapabilities PlatformDetector::getLinuxCapabilities() {
|
|
||||||
PlatformCapabilities caps;
|
|
||||||
caps.supportsWindowed = true;
|
|
||||||
caps.supportsFullscreen = true;
|
|
||||||
caps.supportsBorderless = true;
|
|
||||||
caps.supportsCursor = true;
|
|
||||||
caps.supportsCursorHide = true;
|
|
||||||
caps.supportsDPIAwareness = true;
|
|
||||||
caps.supportsVSync = true;
|
|
||||||
caps.supportsMultiMonitor = true;
|
|
||||||
caps.supportsClipboard = true;
|
|
||||||
caps.supportsGamepad = true;
|
|
||||||
caps.supportsTouch = false;
|
|
||||||
caps.supportsKeyboard = true;
|
|
||||||
caps.supportsMouse = true;
|
|
||||||
caps.supportsResize = true;
|
|
||||||
caps.supportsHighDPI = true;
|
|
||||||
caps.maxTextureSize = 16384;
|
|
||||||
caps.preferredScreenWidth = 1920;
|
|
||||||
caps.preferredScreenHeight = 1080;
|
|
||||||
caps.defaultDPI = 96.0f;
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformCapabilities PlatformDetector::getMacOSCapabilities() {
|
|
||||||
PlatformCapabilities caps;
|
|
||||||
caps.supportsWindowed = true;
|
|
||||||
caps.supportsFullscreen = true;
|
|
||||||
caps.supportsBorderless = true;
|
|
||||||
caps.supportsCursor = true;
|
|
||||||
caps.supportsCursorHide = true;
|
|
||||||
caps.supportsDPIAwareness = true;
|
|
||||||
caps.supportsVSync = true;
|
|
||||||
caps.supportsMultiMonitor = true;
|
|
||||||
caps.supportsClipboard = true;
|
|
||||||
caps.supportsGamepad = true;
|
|
||||||
caps.supportsTouch = false;
|
|
||||||
caps.supportsKeyboard = true;
|
|
||||||
caps.supportsMouse = true;
|
|
||||||
caps.supportsResize = true;
|
|
||||||
caps.supportsHighDPI = true;
|
|
||||||
caps.maxTextureSize = 16384;
|
|
||||||
caps.preferredScreenWidth = 1920;
|
|
||||||
caps.preferredScreenHeight = 1080;
|
|
||||||
caps.defaultDPI = 144.0f;
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformCapabilities PlatformDetector::getSwitchCapabilities() {
|
|
||||||
PlatformCapabilities caps;
|
|
||||||
caps.supportsWindowed = false;
|
|
||||||
caps.supportsFullscreen = true;
|
|
||||||
caps.supportsBorderless = false;
|
|
||||||
caps.supportsCursor = false;
|
|
||||||
caps.supportsCursorHide = false;
|
|
||||||
caps.supportsDPIAwareness = false;
|
|
||||||
caps.supportsVSync = true;
|
|
||||||
caps.supportsMultiMonitor = false;
|
|
||||||
caps.supportsClipboard = false;
|
|
||||||
caps.supportsGamepad = true;
|
|
||||||
caps.supportsTouch = true;
|
|
||||||
caps.supportsKeyboard = false;
|
|
||||||
caps.supportsMouse = false;
|
|
||||||
caps.supportsResize = false;
|
|
||||||
caps.supportsHighDPI = false;
|
|
||||||
caps.maxTextureSize = 8192;
|
|
||||||
caps.preferredScreenWidth = 1920;
|
|
||||||
caps.preferredScreenHeight = 1080;
|
|
||||||
caps.defaultDPI = 96.0f;
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppConfig PlatformDetector::getWindowsDefaults() {
|
|
||||||
AppConfig config = AppConfig::createDefault();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppConfig PlatformDetector::getLinuxDefaults() {
|
|
||||||
AppConfig config = AppConfig::createDefault();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppConfig PlatformDetector::getMacOSDefaults() {
|
|
||||||
AppConfig config = AppConfig::createDefault();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppConfig PlatformDetector::getSwitchDefaults() {
|
|
||||||
AppConfig config = AppConfig::createDefault();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -20,15 +20,20 @@ ShaderManager& ShaderManager::getInstance() {
|
||||||
* @return 初始化成功返回true,失败返回false
|
* @return 初始化成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
bool ShaderManager::init(Ptr<IShaderFactory> factory, const std::string& appName) {
|
bool ShaderManager::init(Ptr<IShaderFactory> factory, const std::string& appName) {
|
||||||
std::string shaderDir = PlatformDetector::getShaderPath(appName);
|
// 使用相对路径作为Shader目录
|
||||||
std::string cacheDir = PlatformDetector::getShaderCachePath(appName);
|
std::string shaderDir = "shaders/";
|
||||||
|
std::string cacheDir = "cache/shaders/";
|
||||||
hotReloadSupported_ = PlatformDetector::supportsHotReload();
|
|
||||||
|
// 非Switch平台支持热重载
|
||||||
E2D_LOG_INFO("Platform: {} (HotReload: {})",
|
#ifndef __SWITCH__
|
||||||
PlatformDetector::platformName(),
|
hotReloadSupported_ = true;
|
||||||
|
#else
|
||||||
|
hotReloadSupported_ = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
E2D_LOG_INFO("ShaderManager init (HotReload: {})",
|
||||||
hotReloadSupported_ ? "supported" : "not supported");
|
hotReloadSupported_ ? "supported" : "not supported");
|
||||||
|
|
||||||
return init(shaderDir, cacheDir, factory);
|
return init(shaderDir, cacheDir, factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +61,12 @@ bool ShaderManager::init(const std::string& shaderDir,
|
||||||
cacheDir_ = cacheDir;
|
cacheDir_ = cacheDir;
|
||||||
factory_ = factory;
|
factory_ = factory;
|
||||||
|
|
||||||
hotReloadSupported_ = PlatformDetector::supportsHotReload();
|
// 非Switch平台支持热重载
|
||||||
|
#ifndef __SWITCH__
|
||||||
|
hotReloadSupported_ = true;
|
||||||
|
#else
|
||||||
|
hotReloadSupported_ = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
if (!ShaderCache::getInstance().init(cacheDir_)) {
|
if (!ShaderCache::getInstance().init(cacheDir_)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue