diff --git a/Extra2D/include/extra2d/app/application.h b/Extra2D/include/extra2d/app/application.h index df343e9..4bfc6aa 100644 --- a/Extra2D/include/extra2d/app/application.h +++ b/Extra2D/include/extra2d/app/application.h @@ -131,7 +131,7 @@ public: * @brief 进入场景 * @param scene 场景指针 */ - void enterScene(Ptr scene); + void enterScene(SharedPtr scene); /** * @brief 获取帧间隔时间 diff --git a/Extra2D/include/extra2d/core/object_pool.h b/Extra2D/include/extra2d/core/object_pool.h new file mode 100644 index 0000000..4fb407d --- /dev/null +++ b/Extra2D/include/extra2d/core/object_pool.h @@ -0,0 +1,675 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace extra2d { + +// ============================================================================ +// IPoolable - 可池化对象接口 +// 实现此接口的对象在归还对象池时会自动调用 reset() 方法 +// ============================================================================ +class IPoolable { +public: + /** + * @brief 虚析构函数 + */ + virtual ~IPoolable() = default; + + /** + * @brief 重置对象状态 + * 当对象归还到对象池时自动调用,用于清理对象状态以便复用 + */ + virtual void reset() = 0; +}; + +// ============================================================================ +// is_poolable_v - 类型特征,检测类型是否实现 IPoolable 接口 +// ============================================================================ +template +struct is_poolable : std::is_base_of {}; + +template +inline constexpr bool is_poolable_v = is_poolable::value; + +// ============================================================================ +// ObjectPoolStats - 对象池统计信息 +// ============================================================================ +struct ObjectPoolStats { + size_t totalCapacity = 0; // 总容量(已分配对象数) + size_t activeCount = 0; // 活跃对象数(正在使用) + size_t freeCount = 0; // 空闲对象数(可用于分配) + size_t peakUsage = 0; // 峰值使用量 + size_t totalAcquires = 0; // 总获取次数 + size_t totalReleases = 0; // 总归还次数 +}; + +// ============================================================================ +// ControlBlock - PooledPtr 的控制块,管理引用计数 +// ============================================================================ +struct ControlBlock { + std::atomic refCount{1}; // 引用计数 + void* pool = nullptr; // 所属对象池指针 + void* object = nullptr; // 对象指针 + + /** + * @brief 增加引用计数 + * @return 增加后的引用计数 + */ + int32 addRef() { + return refCount.fetch_add(1, std::memory_order_relaxed) + 1; + } + + /** + * @brief 减少引用计数 + * @return 减少后的引用计数 + */ + int32 release() { + return refCount.fetch_sub(1, std::memory_order_acq_rel) - 1; + } + + /** + * @brief 获取当前引用计数 + * @return 当前引用计数 + */ + int32 getRefCount() const { + return refCount.load(std::memory_order_relaxed); + } +}; + +// ============================================================================ +// ObjectPool - 线程安全的通用对象池模板 +// ============================================================================ +template +class ObjectPool { +public: + // ======================================================================== + // 构造和析构 + // ======================================================================== + + /** + * @brief 默认构造函数 + */ + ObjectPool() = default; + + /** + * @brief 析构函数 + */ + ~ObjectPool() { + clear(); + } + + // 禁止拷贝 + ObjectPool(const ObjectPool&) = delete; + ObjectPool& operator=(const ObjectPool&) = delete; + + // 允许移动 + ObjectPool(ObjectPool&& other) noexcept { + std::lock_guard lock(other.mutex_); + freeList_ = std::move(other.freeList_); + allObjects_ = std::move(other.allObjects_); + stats_ = other.stats_; + other.stats_ = ObjectPoolStats{}; + } + + ObjectPool& operator=(ObjectPool&& other) noexcept { + if (this != &other) { + std::scoped_lock lock(mutex_, other.mutex_); + clearUnsafe(); + freeList_ = std::move(other.freeList_); + allObjects_ = std::move(other.allObjects_); + stats_ = other.stats_; + other.stats_ = ObjectPoolStats{}; + } + return *this; + } + + // ======================================================================== + // 对象获取和归还 + // ======================================================================== + + /** + * @brief 从对象池获取一个对象 + * 如果池中有空闲对象则复用,否则创建新对象 + * @param args 构造参数 + * @return 对象指针和控制块 + */ + template + std::pair acquire(Args&&... args) { + std::lock_guard lock(mutex_); + + T* obj = nullptr; + ControlBlock* cb = nullptr; + + if (!freeList_.empty()) { + // 从空闲列表获取 + auto& front = freeList_.front(); + obj = front.first; + cb = front.second; + freeList_.pop_front(); + + // 重新构造对象(placement new) + new (obj) T(std::forward(args)...); + } else { + // 创建新对象 + obj = new T(std::forward(args)...); + cb = new ControlBlock(); + cb->pool = this; + cb->object = obj; + allObjects_.push_back({obj, cb}); + stats_.totalCapacity++; + } + + stats_.activeCount++; + stats_.freeCount = freeList_.size(); + stats_.totalAcquires++; + stats_.peakUsage = std::max(stats_.peakUsage, stats_.activeCount); + + return {obj, cb}; + } + + /** + * @brief 归还对象到对象池 + * @param cb 控制块指针 + */ + void release(ControlBlock* cb) { + if (!cb) return; + + T* obj = static_cast(cb->object); + + std::lock_guard lock(mutex_); + + // 如果对象实现了 IPoolable,调用 reset() + if constexpr (is_poolable_v) { + static_cast(obj)->reset(); + } else { + // 显式调用析构函数 + obj->~T(); + } + + // 重置控制块 + cb->refCount.store(1, std::memory_order_relaxed); + + // 加入空闲列表 + freeList_.push_back({obj, cb}); + + stats_.activeCount--; + stats_.freeCount = freeList_.size(); + stats_.totalReleases++; + } + + // ======================================================================== + // 预分配和内存管理 + // ======================================================================== + + /** + * @brief 预分配指定数量的对象 + * @param count 预分配数量 + */ + void preallocate(size_t count) { + std::lock_guard lock(mutex_); + + for (size_t i = 0; i < count; ++i) { + T* obj = new T(); + ControlBlock* cb = new ControlBlock(); + cb->pool = this; + cb->object = obj; + freeList_.push_back({obj, cb}); + allObjects_.push_back({obj, cb}); + } + + stats_.totalCapacity += count; + stats_.freeCount = freeList_.size(); + } + + /** + * @brief 清空所有对象 + */ + void clear() { + std::lock_guard lock(mutex_); + clearUnsafe(); + } + + /** + * @brief 收缩空闲列表,释放多余的空闲对象 + * @param keepCount 保留的空闲对象数量 + * @return 释放的对象数量 + */ + size_t shrink(size_t keepCount = 0) { + std::lock_guard lock(mutex_); + + size_t released = 0; + while (freeList_.size() > keepCount) { + auto& back = freeList_.back(); + T* obj = back.first; + ControlBlock* cb = back.second; + + // 从 allObjects_ 中移除 + allObjects_.erase( + std::remove(allObjects_.begin(), allObjects_.end(), back), + allObjects_.end()); + + delete obj; + delete cb; + freeList_.pop_back(); + released++; + stats_.totalCapacity--; + } + + stats_.freeCount = freeList_.size(); + return released; + } + + // ======================================================================== + // 统计信息 + // ======================================================================== + + /** + * @brief 获取统计信息 + * @return 统计信息结构 + */ + ObjectPoolStats getStats() const { + std::lock_guard lock(mutex_); + return stats_; + } + + /** + * @brief 获取当前活跃对象数 + * @return 活跃对象数 + */ + size_t activeCount() const { + std::lock_guard lock(mutex_); + return stats_.activeCount; + } + + /** + * @brief 获取当前空闲对象数 + * @return 空闲对象数 + */ + size_t freeCount() const { + std::lock_guard lock(mutex_); + return stats_.freeCount; + } + +private: + /** + * @brief 无锁清空(内部使用) + */ + void clearUnsafe() { + for (auto& pair : allObjects_) { + delete pair.first; + delete pair.second; + } + allObjects_.clear(); + freeList_.clear(); + stats_ = ObjectPoolStats{}; + } + + mutable std::mutex mutex_; + std::deque> freeList_; // 空闲列表 + std::vector> allObjects_; // 所有对象(用于析构) + mutable ObjectPoolStats stats_; +}; + +// ============================================================================ +// PooledPtr - 池化智能指针,行为与 shared_ptr 兼容 +// ============================================================================ +template +class PooledPtr { +public: + // ======================================================================== + // 构造和析构 + // ======================================================================== + + /** + * @brief 默认构造函数(空指针) + */ + PooledPtr() : ptr_(nullptr), controlBlock_(nullptr) {} + + /** + * @brief 从 nullptr 构造 + */ + PooledPtr(std::nullptr_t) : ptr_(nullptr), controlBlock_(nullptr) {} + + /** + * @brief 从对象指针和控制块构造 + * @param ptr 对象指针 + * @param cb 控制块 + */ + PooledPtr(T* ptr, ControlBlock* cb) : ptr_(ptr), controlBlock_(cb) {} + + /** + * @brief 析构函数,引用计数归零时归还对象池 + */ + ~PooledPtr() { + releaseRef(); + } + + // ======================================================================== + // 拷贝语义 + // ======================================================================== + + /** + * @brief 拷贝构造函数 + * @param other 另一个 PooledPtr + */ + PooledPtr(const PooledPtr& other) + : ptr_(other.ptr_), controlBlock_(other.controlBlock_) { + if (controlBlock_) { + controlBlock_->addRef(); + } + } + + /** + * @brief 拷贝赋值运算符 + * @param other 另一个 PooledPtr + * @return 引用 + */ + PooledPtr& operator=(const PooledPtr& other) { + if (this != &other) { + releaseRef(); + ptr_ = other.ptr_; + controlBlock_ = other.controlBlock_; + if (controlBlock_) { + controlBlock_->addRef(); + } + } + return *this; + } + + // ======================================================================== + // 移动语义 + // ======================================================================== + + /** + * @brief 移动构造函数 + * @param other 另一个 PooledPtr + */ + PooledPtr(PooledPtr&& other) noexcept + : ptr_(other.ptr_), controlBlock_(other.controlBlock_) { + other.ptr_ = nullptr; + other.controlBlock_ = nullptr; + } + + /** + * @brief 移动赋值运算符 + * @param other 另一个 PooledPtr + * @return 引用 + */ + PooledPtr& operator=(PooledPtr&& other) noexcept { + if (this != &other) { + releaseRef(); + ptr_ = other.ptr_; + controlBlock_ = other.controlBlock_; + other.ptr_ = nullptr; + other.controlBlock_ = nullptr; + } + return *this; + } + + // ======================================================================== + // 类型转换构造(支持多态) + // ======================================================================== + + /** + * @brief 从其他类型的 PooledPtr 构造(支持向上转型) + */ + template >> + PooledPtr(const PooledPtr& other) + : ptr_(other.get()), controlBlock_(other.controlBlock()) { + if (controlBlock_) { + controlBlock_->addRef(); + } + } + + /** + * @brief 从其他类型的 PooledPtr 移动构造(支持向上转型) + */ + template >> + PooledPtr(PooledPtr&& other) noexcept + : ptr_(other.get()), controlBlock_(other.controlBlock()) { + other.reset(); + } + + // ======================================================================== + // 访问器 + // ======================================================================== + + /** + * @brief 获取原始指针 + * @return 原始指针 + */ + T* get() const { return ptr_; } + + /** + * @brief 获取控制块 + * @return 控制块指针 + */ + ControlBlock* controlBlock() const { return controlBlock_; } + + /** + * @brief 获取引用计数 + * @return 引用计数 + */ + int32 useCount() const { + return controlBlock_ ? controlBlock_->getRefCount() : 0; + } + + /** + * @brief 检查是否唯一引用 + * @return 是否唯一引用 + */ + bool unique() const { + return useCount() == 1; + } + + /** + * @brief 检查是否有效 + * @return 是否有效 + */ + bool valid() const { return ptr_ != nullptr; } + + // ======================================================================== + // 运算符重载 + // ======================================================================== + + /** + * @brief 箭头运算符 + */ + T* operator->() const { return ptr_; } + + /** + * @brief 解引用运算符 + */ + T& operator*() const { return *ptr_; } + + /** + * @brief 布尔转换运算符 + */ + explicit operator bool() const { return valid(); } + + /** + * @brief 取反运算符 + */ + bool operator!() const { return !valid(); } + + // ======================================================================== + // 重置 + // ======================================================================== + + /** + * @brief 重置为空指针 + */ + void reset() { + releaseRef(); + ptr_ = nullptr; + controlBlock_ = nullptr; + } + + /** + * @brief 重置为新的对象 + * @param ptr 新对象指针 + * @param cb 新控制块 + */ + void reset(T* ptr, ControlBlock* cb) { + releaseRef(); + ptr_ = ptr; + controlBlock_ = cb; + } + + // ======================================================================== + // 比较运算符 + // ======================================================================== + + /** + * @brief 相等比较 + */ + bool operator==(const PooledPtr& other) const { + return ptr_ == other.ptr_; + } + + /** + * @brief 不等比较 + */ + bool operator!=(const PooledPtr& other) const { + return ptr_ != other.ptr_; + } + + /** + * @brief 与 nullptr 比较 + */ + bool operator==(std::nullptr_t) const { + return ptr_ == nullptr; + } + + /** + * @brief 与 nullptr 比较 + */ + bool operator!=(std::nullptr_t) const { + return ptr_ != nullptr; + } + +private: + /** + * @brief 释放引用 + */ + void releaseRef() { + if (controlBlock_ && controlBlock_->release() == 0) { + // 引用计数归零,归还对象池 + auto* pool = static_cast*>(controlBlock_->pool); + if (pool) { + pool->release(controlBlock_); + } + } + } + + T* ptr_; + ControlBlock* controlBlock_; + + // 允许其他类型的 PooledPtr 访问私有成员 + template + friend class PooledPtr; +}; + +// ============================================================================ +// ObjectPoolManager - 全局对象池管理器 +// ============================================================================ +class ObjectPoolManager { +public: + /** + * @brief 获取单例实例 + * @return 单例引用 + */ + static ObjectPoolManager& instance() { + static ObjectPoolManager instance; + return instance; + } + + // 禁止拷贝和移动 + ObjectPoolManager(const ObjectPoolManager&) = delete; + ObjectPoolManager& operator=(const ObjectPoolManager&) = delete; + + // ======================================================================== + // 类型池访问 + // ======================================================================== + + /** + * @brief 获取指定类型的对象池 + * @return 对象池引用 + */ + template + ObjectPool& getPool() { + std::lock_guard lock(mutex_); + + using PoolPtr = UniquePtr>; + static PoolPtr pool = makeUnique>(); + return *pool; + } + + // ======================================================================== + // 预分配 + // ======================================================================== + + /** + * @brief 预分配指定类型的对象 + * @param count 预分配数量 + */ + template + void preallocate(size_t count) { + getPool().preallocate(count); + } + + // ======================================================================== + // 统计信息 + // ======================================================================== + + /** + * @brief 获取指定类型的统计信息 + * @return 统计信息 + */ + template + ObjectPoolStats getStats() { + return getPool().getStats(); + } + + /** + * @brief 收缩指定类型的对象池 + * @param keepCount 保留的空闲对象数量 + * @return 释放的对象数量 + */ + template + size_t shrink(size_t keepCount = 0) { + return getPool().shrink(keepCount); + } + +private: + ObjectPoolManager() = default; + mutable std::mutex mutex_; +}; + +// ============================================================================ +// 辅助函数 - 从对象池创建对象 +// ============================================================================ + +/** + * @brief 从对象池获取对象 + * @param args 构造参数 + * @return PooledPtr 智能指针 + */ +template +PooledPtr makePooled(Args&&... args) { + auto& pool = ObjectPoolManager::instance().getPool(); + auto [ptr, cb] = pool.acquire(std::forward(args)...); + return PooledPtr(ptr, cb); +} + +} // namespace extra2d diff --git a/Extra2D/include/extra2d/core/types.h b/Extra2D/include/extra2d/core/types.h index b3720eb..1b4256d 100644 --- a/Extra2D/include/extra2d/core/types.h +++ b/Extra2D/include/extra2d/core/types.h @@ -5,6 +5,15 @@ #include #include +// 前向声明 +namespace extra2d { +template class PooledPtr; +template class ObjectPool; +struct ControlBlock; +class ObjectPoolManager; +template PooledPtr makePooled(Args&&...); +} + namespace extra2d { // --------------------------------------------------------------------------- @@ -16,18 +25,20 @@ namespace extra2d { // --------------------------------------------------------------------------- // 智能指针别名 // --------------------------------------------------------------------------- -template using Ptr = std::shared_ptr; +// Ptr 使用对象池支持的智能指针(透明替换原有 shared_ptr) +template using Ptr = PooledPtr; + +// SharedPtr 保留为 std::shared_ptr(兼容旧代码) template using SharedPtr = std::shared_ptr; template using UniquePtr = std::unique_ptr; template using WeakPtr = std::weak_ptr; -/// 创建 shared_ptr 的便捷函数 -template inline Ptr makePtr(Args &&...args) { - return std::make_shared(std::forward(args)...); -} +/// 创建 Ptr 的便捷函数(使用对象池) +template inline Ptr makePtr(Args &&...args); +/// 创建 shared_ptr 的便捷函数(兼容旧代码) template inline SharedPtr makeShared(Args &&...args) { return std::make_shared(std::forward(args)...); } @@ -56,3 +67,15 @@ using uint32 = std::uint32_t; using uint64 = std::uint64_t; } // namespace extra2d + +// 包含对象池实现(需要完整类型定义) +#include + +namespace extra2d { + +// makePtr 实现(放在 include 之后,因为需要完整的 PooledPtr 定义) +template inline Ptr makePtr(Args &&...args) { + return makePooled(std::forward(args)...); +} + +} // namespace extra2d diff --git a/Extra2D/include/extra2d/graphics/opengl/gl_renderer.h b/Extra2D/include/extra2d/graphics/opengl/gl_renderer.h index b2bd972..e0964ce 100644 --- a/Extra2D/include/extra2d/graphics/opengl/gl_renderer.h +++ b/Extra2D/include/extra2d/graphics/opengl/gl_renderer.h @@ -90,7 +90,7 @@ private: IWindow* window_; GLSpriteBatch spriteBatch_; - Ptr shapeShader_; + SharedPtr shapeShader_; GLuint shapeVao_; GLuint shapeVbo_; diff --git a/Extra2D/include/extra2d/graphics/opengl/gl_shader_new.h b/Extra2D/include/extra2d/graphics/opengl/gl_shader_new.h index a832af8..00205fb 100644 --- a/Extra2D/include/extra2d/graphics/opengl/gl_shader_new.h +++ b/Extra2D/include/extra2d/graphics/opengl/gl_shader_new.h @@ -174,7 +174,7 @@ public: * @param fragSource 片段着色器源码 * @return 创建的Shader实例 */ - Ptr createFromSource( + SharedPtr createFromSource( const std::string& name, const std::string& vertSource, const std::string& fragSource) override; @@ -185,7 +185,7 @@ public: * @param binary 编译后的二进制数据 * @return 创建的Shader实例 */ - Ptr createFromBinary( + SharedPtr createFromBinary( const std::string& name, const std::vector& binary) override; diff --git a/Extra2D/include/extra2d/graphics/render_target.h b/Extra2D/include/extra2d/graphics/render_target.h index 90b0ea2..3dd4f1e 100644 --- a/Extra2D/include/extra2d/graphics/render_target.h +++ b/Extra2D/include/extra2d/graphics/render_target.h @@ -150,7 +150,7 @@ public: /** * @brief 创建渲染目标的静态工厂方法 */ - static Ptr createFromConfig(const RenderTargetConfig &config); + static SharedPtr createFromConfig(const RenderTargetConfig &config); /** * @brief 获取当前绑定的渲染目标ID @@ -274,7 +274,7 @@ public: /** * @brief 创建新的渲染目标 */ - Ptr createRenderTarget(const RenderTargetConfig &config); + SharedPtr createRenderTarget(const RenderTargetConfig &config); /** * @brief 获取默认渲染目标 @@ -299,8 +299,8 @@ private: RenderTargetMgr(const RenderTargetMgr &) = delete; RenderTargetMgr &operator=(const RenderTargetMgr &) = delete; - Ptr defaultRenderTarget_; - std::vector> renderTargets_; + SharedPtr defaultRenderTarget_; + std::vector> renderTargets_; bool initialized_ = false; }; diff --git a/Extra2D/include/extra2d/graphics/shader_cache.h b/Extra2D/include/extra2d/graphics/shader_cache.h index 1ab93f5..1625e33 100644 --- a/Extra2D/include/extra2d/graphics/shader_cache.h +++ b/Extra2D/include/extra2d/graphics/shader_cache.h @@ -54,7 +54,7 @@ public: * @param name Shader名称 * @return 缓存条目指针,不存在返回nullptr */ - Ptr loadCache(const std::string& name); + SharedPtr loadCache(const std::string& name); /** * @brief 保存编译结果到缓存 diff --git a/Extra2D/include/extra2d/graphics/shader_interface.h b/Extra2D/include/extra2d/graphics/shader_interface.h index e343d1d..d53ddd9 100644 --- a/Extra2D/include/extra2d/graphics/shader_interface.h +++ b/Extra2D/include/extra2d/graphics/shader_interface.h @@ -124,7 +124,7 @@ public: * @param fragSource 片段着色器源码 * @return 创建的Shader实例 */ - virtual Ptr createFromSource( + virtual SharedPtr createFromSource( const std::string& name, const std::string& vertSource, const std::string& fragSource) = 0; @@ -135,7 +135,7 @@ public: * @param binary 编译后的二进制数据 * @return 创建的Shader实例 */ - virtual Ptr createFromBinary( + virtual SharedPtr createFromBinary( const std::string& name, const std::vector& binary) = 0; diff --git a/Extra2D/include/extra2d/graphics/shader_manager.h b/Extra2D/include/extra2d/graphics/shader_manager.h index ce34937..abc5efd 100644 --- a/Extra2D/include/extra2d/graphics/shader_manager.h +++ b/Extra2D/include/extra2d/graphics/shader_manager.h @@ -13,7 +13,7 @@ namespace extra2d { // ============================================================================ // Shader重载回调 // ============================================================================ -using ShaderReloadCallback = std::function newShader)>; +using ShaderReloadCallback = std::function newShader)>; // ============================================================================ // Shader管理器 - 统一入口 @@ -37,7 +37,7 @@ public: * @param appName 应用名称(用于缓存目录) * @return 初始化成功返回true,失败返回false */ - bool init(Ptr factory, const std::string& appName = "extra2d"); + bool init(SharedPtr factory, const std::string& appName = "extra2d"); /** * @brief 初始化Shader系统 @@ -48,7 +48,7 @@ public: */ bool init(const std::string& shaderDir, const std::string& cacheDir, - Ptr factory); + SharedPtr factory); /** * @brief 关闭Shader系统 @@ -79,7 +79,7 @@ public: * @param fragPath 片段着色器文件路径 * @return 加载的Shader实例 */ - Ptr loadFromFiles(const std::string& name, + SharedPtr loadFromFiles(const std::string& name, const std::string& vertPath, const std::string& fragPath); @@ -88,7 +88,7 @@ public: * @param path 组合Shader文件路径 * @return 加载的Shader实例 */ - Ptr loadFromCombinedFile(const std::string& path); + SharedPtr loadFromCombinedFile(const std::string& path); /** * @brief 从源码加载Shader @@ -97,7 +97,7 @@ public: * @param fragSource 片段着色器源码 * @return 加载的Shader实例 */ - Ptr loadFromSource(const std::string& name, + SharedPtr loadFromSource(const std::string& name, const std::string& vertSource, const std::string& fragSource); @@ -106,7 +106,7 @@ public: * @param name Shader名称 * @return Shader实例,不存在返回nullptr */ - Ptr get(const std::string& name) const; + SharedPtr get(const std::string& name) const; /** * @brief 检查Shader是否存在 @@ -170,7 +170,7 @@ public: * @param name 内置Shader名称 * @return Shader实例 */ - Ptr getBuiltin(const std::string& name); + SharedPtr getBuiltin(const std::string& name); /** * @brief 加载所有内置Shader @@ -202,11 +202,11 @@ private: std::string shaderDir_; std::string cacheDir_; - Ptr factory_; + SharedPtr factory_; ShaderLoader loader_; struct ShaderInfo { - Ptr shader; + SharedPtr shader; ShaderMetadata metadata; ShaderReloadCallback reloadCallback; std::string vertSource; @@ -227,7 +227,7 @@ private: * @param fragSource 片段着色器源码 * @return Shader实例 */ - Ptr loadFromCache(const std::string& name, + SharedPtr loadFromCache(const std::string& name, const std::string& sourceHash, const std::string& vertSource, const std::string& fragSource); diff --git a/Extra2D/include/extra2d/graphics/shader_preset.h b/Extra2D/include/extra2d/graphics/shader_preset.h index 18dd3fc..1084dec 100644 --- a/Extra2D/include/extra2d/graphics/shader_preset.h +++ b/Extra2D/include/extra2d/graphics/shader_preset.h @@ -46,49 +46,49 @@ public: * @param params 水波纹效果参数 * @return 配置好的着色器 */ - static Ptr Water(const WaterParams& params = {}); + static SharedPtr Water(const WaterParams& params = {}); /** * @brief 创建描边效果着色器 * @param params 描边效果参数 * @return 配置好的着色器 */ - static Ptr Outline(const OutlineParams& params = {}); + static SharedPtr Outline(const OutlineParams& params = {}); /** * @brief 创建扭曲效果着色器 * @param params 扭曲效果参数 * @return 配置好的着色器 */ - static Ptr Distortion(const DistortionParams& params = {}); + static SharedPtr Distortion(const DistortionParams& params = {}); /** * @brief 创建像素化效果着色器 * @param params 像素化效果参数 * @return 配置好的着色器 */ - static Ptr Pixelate(const PixelateParams& params = {}); + static SharedPtr Pixelate(const PixelateParams& params = {}); /** * @brief 创建反相效果着色器 * @param params 反相效果参数 * @return 配置好的着色器 */ - static Ptr Invert(const InvertParams& params = {}); + static SharedPtr Invert(const InvertParams& params = {}); /** * @brief 创建灰度效果着色器 * @param params 灰度效果参数 * @return 配置好的着色器 */ - static Ptr Grayscale(const GrayscaleParams& params = {}); + static SharedPtr Grayscale(const GrayscaleParams& params = {}); /** * @brief 创建模糊效果着色器 * @param params 模糊效果参数 * @return 配置好的着色器 */ - static Ptr Blur(const BlurParams& params = {}); + static SharedPtr Blur(const BlurParams& params = {}); /** * @brief 创建灰度+描边组合效果着色器 @@ -96,7 +96,7 @@ public: * @param outlineParams 描边效果参数 * @return 配置好的着色器 */ - static Ptr GrayscaleOutline(const GrayscaleParams& grayParams, + static SharedPtr GrayscaleOutline(const GrayscaleParams& grayParams, const OutlineParams& outlineParams); /** @@ -105,8 +105,8 @@ public: * @param invParams 反相效果参数 * @return 配置好的着色器 */ - static Ptr PixelateInvert(const PixelateParams& pixParams, + static SharedPtr PixelateInvert(const PixelateParams& pixParams, const InvertParams& invParams); }; -} // namespace extra2d +} diff --git a/Extra2D/include/extra2d/scene/node.h b/Extra2D/include/extra2d/scene/node.h index 8a2cf86..7146b2b 100644 --- a/Extra2D/include/extra2d/scene/node.h +++ b/Extra2D/include/extra2d/scene/node.h @@ -18,6 +18,7 @@ struct RenderCommand; // ============================================================================ // 节点基类 - 场景图的基础 +// 注意:Node 使用 SharedPtr 而非 Ptr,因为需要 enable_shared_from_this 支持 // ============================================================================ class Node : public std::enable_shared_from_this { public: @@ -27,23 +28,23 @@ public: // ------------------------------------------------------------------------ // 层级管理 // ------------------------------------------------------------------------ - void addChild(Ptr child); + void addChild(SharedPtr child); /** * @brief 批量添加子节点 * @param children 子节点列表 */ - void addChildren(std::vector> &&children); + void addChildren(std::vector> &&children); - void removeChild(Ptr child); + void removeChild(SharedPtr child); void removeChildByName(const std::string &name); void detach(); void clearChildren(); - Ptr getParent() const { return parent_.lock(); } - const std::vector> &getChildren() const { return children_; } - Ptr findChild(const std::string &name) const; - Ptr findChildByTag(int tag) const; + SharedPtr getParent() const { return parent_.lock(); } + const std::vector> &getChildren() const { return children_; } + SharedPtr findChild(const std::string &name) const; + SharedPtr findChildByTag(int tag) const; // ------------------------------------------------------------------------ // 变换属性 @@ -191,18 +192,18 @@ private: mutable glm::mat4 worldTransform_; // 64 bytes // 2. 字符串和容器(24-32字节) - std::string name_; // 32 bytes - std::vector> children_; // 24 bytes + std::string name_; // 32 bytes + std::vector> children_; // 24 bytes // 3. 子节点索引(加速查找) - std::unordered_map> nameIndex_; // 56 bytes - std::unordered_map> tagIndex_; // 56 bytes + std::unordered_map> nameIndex_; // 56 bytes + std::unordered_map> tagIndex_; // 56 bytes // 4. 事件分发器 EventDispatcher eventDispatcher_; // 大小取决于实现 // 5. 父节点引用 - WeakPtr parent_; // 16 bytes + std::weak_ptr parent_; // 16 bytes // 7. 变换属性(按访问频率分组) Vec2 position_ = Vec2::Zero(); // 8 bytes diff --git a/Extra2D/include/extra2d/scene/scene.h b/Extra2D/include/extra2d/scene/scene.h index 89b8b65..23a7e09 100644 --- a/Extra2D/include/extra2d/scene/scene.h +++ b/Extra2D/include/extra2d/scene/scene.h @@ -12,6 +12,7 @@ struct RenderCommand; // ============================================================================ // 场景类 - 节点容器,管理整个场景图 +// 注意:Scene 继承自 Node,使用 SharedPtr 因为需要 enable_shared_from_this // ============================================================================ class Scene : public Node { public: @@ -27,8 +28,8 @@ public: // ------------------------------------------------------------------------ // 摄像机 // ------------------------------------------------------------------------ - void setCamera(Ptr camera); - Ptr getCamera() const { return camera_; } + void setCamera(SharedPtr camera); + SharedPtr getCamera() const { return camera_; } Camera *getActiveCamera() const { return camera_ ? camera_.get() : defaultCamera_.get(); @@ -63,7 +64,7 @@ public: // ------------------------------------------------------------------------ // 静态创建方法 // ------------------------------------------------------------------------ - static Ptr create(); + static SharedPtr create(); protected: void onEnter() override; @@ -80,8 +81,8 @@ private: Color backgroundColor_ = Colors::Black; Size viewportSize_ = Size::Zero(); - Ptr camera_; - Ptr defaultCamera_; + SharedPtr camera_; + SharedPtr defaultCamera_; bool paused_ = false; }; diff --git a/Extra2D/include/extra2d/scene/scene_manager.h b/Extra2D/include/extra2d/scene/scene_manager.h index 1f3f14a..6b4f08d 100644 --- a/Extra2D/include/extra2d/scene/scene_manager.h +++ b/Extra2D/include/extra2d/scene/scene_manager.h @@ -22,17 +22,17 @@ public: static SceneManager &get(); - void runWithScene(Ptr scene); - void replaceScene(Ptr scene); - void pushScene(Ptr scene); + void runWithScene(SharedPtr scene); + void replaceScene(SharedPtr scene); + void pushScene(SharedPtr scene); void popScene(); void popToRootScene(); void popToScene(const std::string &name); - Ptr getCurrentScene() const; - Ptr getPreviousScene() const; - Ptr getRootScene() const; - Ptr getSceneByName(const std::string &name) const; + SharedPtr getCurrentScene() const; + SharedPtr getPreviousScene() const; + SharedPtr getRootScene() const; + SharedPtr getSceneByName(const std::string &name) const; size_t getSceneCount() const { return sceneStack_.size(); } bool isEmpty() const { return sceneStack_.empty(); } @@ -56,19 +56,19 @@ public: SceneManager(const SceneManager &) = delete; SceneManager &operator=(const SceneManager &) = delete; - void enterScene(Ptr scene); + void enterScene(SharedPtr scene); private: void doSceneSwitch(); void dispatchPointerEvents(Scene &scene); - std::stack> sceneStack_; - std::unordered_map> namedScenes_; + std::stack> sceneStack_; + std::unordered_map> namedScenes_; bool isTransitioning_ = false; TransitionCallback transitionCallback_; - Ptr nextScene_; + SharedPtr nextScene_; bool sendCleanupToScene_ = false; Node *hoverTarget_ = nullptr; diff --git a/Extra2D/include/extra2d/scene/shape_node.h b/Extra2D/include/extra2d/scene/shape_node.h index e0af481..ddb2485 100644 --- a/Extra2D/include/extra2d/scene/shape_node.h +++ b/Extra2D/include/extra2d/scene/shape_node.h @@ -14,6 +14,7 @@ enum class ShapeType { Point, Line, Rect, Circle, Triangle, Polygon }; // ============================================================================ // 形状节点 - 用于绘制几何形状 +// 注意:ShapeNode 继承自 Node,使用 SharedPtr 因为需要 enable_shared_from_this // ============================================================================ class ShapeNode : public Node { public: @@ -23,41 +24,47 @@ public: // ------------------------------------------------------------------------ // 静态创建方法 // ------------------------------------------------------------------------ - static Ptr create(); + static SharedPtr create(); // 点 - static Ptr createPoint(const Vec2 &pos, const Color &color); + static SharedPtr createPoint(const Vec2 &pos, const Color &color); // 线 - static Ptr createLine(const Vec2 &start, const Vec2 &end, - const Color &color, float width = 1.0f); + static SharedPtr createLine(const Vec2 &start, const Vec2 &end, + const Color &color, + float width = 1.0f); // 矩形 - static Ptr createRect(const Rect &rect, const Color &color, - float width = 1.0f); - static Ptr createFilledRect(const Rect &rect, const Color &color); + static SharedPtr createRect(const Rect &rect, const Color &color, + float width = 1.0f); + static SharedPtr createFilledRect(const Rect &rect, + const Color &color); // 圆形 - static Ptr createCircle(const Vec2 ¢er, float radius, - const Color &color, int segments = 32, - float width = 1.0f); - static Ptr createFilledCircle(const Vec2 ¢er, float radius, + static SharedPtr createCircle(const Vec2 ¢er, float radius, const Color &color, - int segments = 32); + int segments = 32, + float width = 1.0f); + static SharedPtr createFilledCircle(const Vec2 ¢er, + float radius, + const Color &color, + int segments = 32); // 三角形 - static Ptr createTriangle(const Vec2 &p1, const Vec2 &p2, - const Vec2 &p3, const Color &color, - float width = 1.0f); - static Ptr createFilledTriangle(const Vec2 &p1, const Vec2 &p2, - const Vec2 &p3, - const Color &color); + static SharedPtr createTriangle(const Vec2 &p1, const Vec2 &p2, + const Vec2 &p3, const Color &color, + float width = 1.0f); + static SharedPtr createFilledTriangle(const Vec2 &p1, + const Vec2 &p2, + const Vec2 &p3, + const Color &color); // 多边形 - static Ptr createPolygon(const std::vector &points, - const Color &color, float width = 1.0f); - static Ptr createFilledPolygon(const std::vector &points, - const Color &color); + static SharedPtr createPolygon(const std::vector &points, + const Color &color, + float width = 1.0f); + static SharedPtr + createFilledPolygon(const std::vector &points, const Color &color); // ------------------------------------------------------------------------ // 属性设置 diff --git a/Extra2D/include/extra2d/scene/sprite.h b/Extra2D/include/extra2d/scene/sprite.h index 185ac29..7e54373 100644 --- a/Extra2D/include/extra2d/scene/sprite.h +++ b/Extra2D/include/extra2d/scene/sprite.h @@ -7,6 +7,7 @@ namespace extra2d { // ============================================================================ // 精灵节点 +// 注意:Sprite 继承自 Node,使用 SharedPtr 因为需要 enable_shared_from_this // ============================================================================ class Sprite : public Node { public: @@ -33,9 +34,9 @@ public: bool isFlipY() const { return flipY_; } // 静态创建方法 - static Ptr create(); - static Ptr create(Ptr texture); - static Ptr create(Ptr texture, const Rect &rect); + static SharedPtr create(); + static SharedPtr create(Ptr texture); + static SharedPtr create(Ptr texture, const Rect &rect); Rect getBounds() const override; @@ -52,4 +53,4 @@ private: bool flipY_ = false; }; -} // namespace extra2d +} diff --git a/Extra2D/include/extra2d/services/scene_service.h b/Extra2D/include/extra2d/services/scene_service.h index 742893a..12b672c 100644 --- a/Extra2D/include/extra2d/services/scene_service.h +++ b/Extra2D/include/extra2d/services/scene_service.h @@ -13,17 +13,17 @@ class ISceneService : public IService { public: virtual ~ISceneService() = default; - virtual void runWithScene(Ptr scene) = 0; - virtual void replaceScene(Ptr scene) = 0; - virtual void pushScene(Ptr scene) = 0; + virtual void runWithScene(SharedPtr scene) = 0; + virtual void replaceScene(SharedPtr scene) = 0; + virtual void pushScene(SharedPtr scene) = 0; virtual void popScene() = 0; virtual void popToRootScene() = 0; virtual void popToScene(const std::string& name) = 0; - virtual Ptr getCurrentScene() const = 0; - virtual Ptr getPreviousScene() const = 0; - virtual Ptr getRootScene() const = 0; - virtual Ptr getSceneByName(const std::string& name) const = 0; + virtual SharedPtr getCurrentScene() const = 0; + virtual SharedPtr getPreviousScene() const = 0; + virtual SharedPtr getRootScene() const = 0; + virtual SharedPtr getSceneByName(const std::string& name) const = 0; virtual size_t getSceneCount() const = 0; virtual bool isEmpty() const = 0; @@ -37,7 +37,7 @@ public: virtual void end() = 0; virtual void purgeCachedScenes() = 0; - virtual void enterScene(Ptr scene) = 0; + virtual void enterScene(SharedPtr scene) = 0; }; /** @@ -55,17 +55,17 @@ public: void shutdown() override; void update(float deltaTime) override; - void runWithScene(Ptr scene) override; - void replaceScene(Ptr scene) override; - void pushScene(Ptr scene) override; + void runWithScene(SharedPtr scene) override; + void replaceScene(SharedPtr scene) override; + void pushScene(SharedPtr scene) override; void popScene() override; void popToRootScene() override; void popToScene(const std::string& name) override; - Ptr getCurrentScene() const override; - Ptr getPreviousScene() const override; - Ptr getRootScene() const override; - Ptr getSceneByName(const std::string& name) const override; + SharedPtr getCurrentScene() const override; + SharedPtr getPreviousScene() const override; + SharedPtr getRootScene() const override; + SharedPtr getSceneByName(const std::string& name) const override; size_t getSceneCount() const override; bool isEmpty() const override; @@ -79,7 +79,7 @@ public: void end() override; void purgeCachedScenes() override; - void enterScene(Ptr scene) override; + void enterScene(SharedPtr scene) override; SceneManager& getManager() { return manager_; } const SceneManager& getManager() const { return manager_; } diff --git a/Extra2D/src/app/application.cpp b/Extra2D/src/app/application.cpp index 285d591..b27e68e 100644 --- a/Extra2D/src/app/application.cpp +++ b/Extra2D/src/app/application.cpp @@ -383,7 +383,7 @@ SharedPtr Application::camera() { return ServiceLocator::instance().getService(); } -void Application::enterScene(Ptr scene) { +void Application::enterScene(SharedPtr scene) { auto sceneService = ServiceLocator::instance().getService(); if (sceneService && scene) { scene->setViewportSize(static_cast(window_->width()), diff --git a/Extra2D/src/graphics/opengl/gl_shader_new.cpp b/Extra2D/src/graphics/opengl/gl_shader_new.cpp index 2ca141c..dcdad02 100644 --- a/Extra2D/src/graphics/opengl/gl_shader_new.cpp +++ b/Extra2D/src/graphics/opengl/gl_shader_new.cpp @@ -269,7 +269,7 @@ GLint GLShaderNew::getUniformLocation(const std::string& name) { * @param fragSource 片段着色器源码 * @return 创建的Shader实例 */ -Ptr GLShaderFactory::createFromSource( +SharedPtr GLShaderFactory::createFromSource( const std::string& name, const std::string& vertSource, const std::string& fragSource) { @@ -291,7 +291,7 @@ Ptr GLShaderFactory::createFromSource( * @param binary 编译后的二进制数据 * @return 创建的Shader实例 */ -Ptr GLShaderFactory::createFromBinary( +SharedPtr GLShaderFactory::createFromBinary( const std::string& name, const std::vector& binary) { diff --git a/Extra2D/src/graphics/render_target.cpp b/Extra2D/src/graphics/render_target.cpp index f1f442a..7f12c7f 100644 --- a/Extra2D/src/graphics/render_target.cpp +++ b/Extra2D/src/graphics/render_target.cpp @@ -383,9 +383,9 @@ bool RenderTarget::saveToFile(const std::string &filepath) { * * 静态工厂方法,创建并初始化渲染目标 */ -Ptr +SharedPtr RenderTarget::createFromConfig(const RenderTargetConfig &config) { - auto rt = std::make_shared(); + auto rt = makeShared(); if (rt->create(config)) { return rt; } @@ -741,7 +741,7 @@ void RenderTargetMgr::shutdown() { * * 创建新的渲染目标并由管理器管理 */ -Ptr +SharedPtr RenderTargetMgr::createRenderTarget(const RenderTargetConfig &config) { if (!initialized_) { E2D_ERROR("渲染目标管理器未初始化"); diff --git a/Extra2D/src/graphics/shader_cache.cpp b/Extra2D/src/graphics/shader_cache.cpp index 1ead6a9..7f2712e 100644 --- a/Extra2D/src/graphics/shader_cache.cpp +++ b/Extra2D/src/graphics/shader_cache.cpp @@ -74,7 +74,7 @@ bool ShaderCache::hasValidCache(const std::string& name, const std::string& sour * @param name Shader名称 * @return 缓存条目指针,不存在返回nullptr */ -Ptr ShaderCache::loadCache(const std::string& name) { +SharedPtr ShaderCache::loadCache(const std::string& name) { auto it = cacheMap_.find(name); if (it == cacheMap_.end()) { return nullptr; diff --git a/Extra2D/src/graphics/shader_manager.cpp b/Extra2D/src/graphics/shader_manager.cpp index 7d95d70..de22ece 100644 --- a/Extra2D/src/graphics/shader_manager.cpp +++ b/Extra2D/src/graphics/shader_manager.cpp @@ -19,7 +19,7 @@ ShaderManager& ShaderManager::getInstance() { * @param appName 应用名称(用于缓存目录) * @return 初始化成功返回true,失败返回false */ -bool ShaderManager::init(Ptr factory, const std::string& appName) { +bool ShaderManager::init(SharedPtr factory, const std::string& appName) { std::string shaderDir = PlatformDetector::getShaderPath(appName); std::string cacheDir = PlatformDetector::getShaderCachePath(appName); @@ -41,7 +41,7 @@ bool ShaderManager::init(Ptr factory, const std::string& appName */ bool ShaderManager::init(const std::string& shaderDir, const std::string& cacheDir, - Ptr factory) { + SharedPtr factory) { if (initialized_) { E2D_LOG_WARN("ShaderManager already initialized"); return true; @@ -112,7 +112,7 @@ void ShaderManager::shutdown() { * @param fragPath 片段着色器文件路径 * @return 加载的Shader实例 */ -Ptr ShaderManager::loadFromFiles(const std::string& name, +SharedPtr ShaderManager::loadFromFiles(const std::string& name, const std::string& vertPath, const std::string& fragPath) { if (!initialized_) { @@ -132,7 +132,7 @@ Ptr ShaderManager::loadFromFiles(const std::string& name, } std::string sourceHash = ShaderCache::computeHash(result.vertSource, result.fragSource); - Ptr shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource); + SharedPtr shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource); if (!shader) { shader = factory_->createFromSource(name, result.vertSource, result.fragSource); @@ -181,7 +181,7 @@ Ptr ShaderManager::loadFromFiles(const std::string& name, * @param path 组合Shader文件路径 * @return 加载的Shader实例 */ -Ptr ShaderManager::loadFromCombinedFile(const std::string& path) { +SharedPtr ShaderManager::loadFromCombinedFile(const std::string& path) { if (!initialized_) { E2D_LOG_ERROR("ShaderManager not initialized"); return nullptr; @@ -202,7 +202,7 @@ Ptr ShaderManager::loadFromCombinedFile(const std::string& path) { } std::string sourceHash = ShaderCache::computeHash(result.vertSource, result.fragSource); - Ptr shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource); + SharedPtr shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource); if (!shader) { shader = factory_->createFromSource(name, result.vertSource, result.fragSource); @@ -250,7 +250,7 @@ Ptr ShaderManager::loadFromCombinedFile(const std::string& path) { * @param fragSource 片段着色器源码 * @return 加载的Shader实例 */ -Ptr ShaderManager::loadFromSource(const std::string& name, +SharedPtr ShaderManager::loadFromSource(const std::string& name, const std::string& vertSource, const std::string& fragSource) { if (!initialized_) { @@ -263,7 +263,7 @@ Ptr ShaderManager::loadFromSource(const std::string& name, return it->second.shader; } - Ptr shader = factory_->createFromSource(name, vertSource, fragSource); + SharedPtr shader = factory_->createFromSource(name, vertSource, fragSource); if (!shader) { E2D_LOG_ERROR("Failed to create shader from source: {}", name); return nullptr; @@ -286,7 +286,7 @@ Ptr ShaderManager::loadFromSource(const std::string& name, * @param name Shader名称 * @return Shader实例,不存在返回nullptr */ -Ptr ShaderManager::get(const std::string& name) const { +SharedPtr ShaderManager::get(const std::string& name) const { auto it = shaders_.find(name); if (it != shaders_.end()) { return it->second.shader; @@ -403,7 +403,7 @@ bool ShaderManager::reload(const std::string& name) { } } - Ptr newShader = factory_->createFromSource(name, vertSource, fragSource); + SharedPtr newShader = factory_->createFromSource(name, vertSource, fragSource); if (!newShader) { E2D_LOG_ERROR("Failed to reload shader: {}", name); return false; @@ -426,8 +426,8 @@ bool ShaderManager::reload(const std::string& name) { * @param name 内置Shader名称 * @return Shader实例 */ -Ptr ShaderManager::getBuiltin(const std::string& name) { - Ptr shader = get(name); +SharedPtr ShaderManager::getBuiltin(const std::string& name) { + SharedPtr shader = get(name); if (shader) { return shader; } @@ -487,7 +487,7 @@ bool ShaderManager::loadBuiltinShaders() { * @param fragSource 片段着色器源码 * @return Shader实例 */ -Ptr ShaderManager::loadFromCache(const std::string& name, +SharedPtr ShaderManager::loadFromCache(const std::string& name, const std::string& sourceHash, const std::string& vertSource, const std::string& fragSource) { @@ -499,12 +499,12 @@ Ptr ShaderManager::loadFromCache(const std::string& name, return nullptr; } - Ptr entry = ShaderCache::getInstance().loadCache(name); + SharedPtr entry = ShaderCache::getInstance().loadCache(name); if (!entry || entry->binary.empty()) { return nullptr; } - Ptr shader = factory_->createFromBinary(name, entry->binary); + SharedPtr shader = factory_->createFromBinary(name, entry->binary); if (shader) { E2D_LOG_DEBUG("Shader loaded from cache: {}", name); } diff --git a/Extra2D/src/graphics/shader_preset.cpp b/Extra2D/src/graphics/shader_preset.cpp index 5c590ab..1bd5484 100644 --- a/Extra2D/src/graphics/shader_preset.cpp +++ b/Extra2D/src/graphics/shader_preset.cpp @@ -9,8 +9,8 @@ namespace extra2d { * @param params 水波纹效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Water(const WaterParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("water"); +SharedPtr ShaderPreset::Water(const WaterParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("water"); if (!shader) { E2D_LOG_ERROR("Failed to get water shader"); return nullptr; @@ -28,8 +28,8 @@ Ptr ShaderPreset::Water(const WaterParams ¶ms) { * @param params 描边效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Outline(const OutlineParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("outline"); +SharedPtr ShaderPreset::Outline(const OutlineParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("outline"); if (!shader) { E2D_LOG_ERROR("Failed to get outline shader"); return nullptr; @@ -47,8 +47,8 @@ Ptr ShaderPreset::Outline(const OutlineParams ¶ms) { * @param params 扭曲效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Distortion(const DistortionParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("distortion"); +SharedPtr ShaderPreset::Distortion(const DistortionParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("distortion"); if (!shader) { E2D_LOG_ERROR("Failed to get distortion shader"); return nullptr; @@ -65,8 +65,8 @@ Ptr ShaderPreset::Distortion(const DistortionParams ¶ms) { * @param params 像素化效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Pixelate(const PixelateParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("pixelate"); +SharedPtr ShaderPreset::Pixelate(const PixelateParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("pixelate"); if (!shader) { E2D_LOG_ERROR("Failed to get pixelate shader"); return nullptr; @@ -82,8 +82,8 @@ Ptr ShaderPreset::Pixelate(const PixelateParams ¶ms) { * @param params 反相效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Invert(const InvertParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("invert"); +SharedPtr ShaderPreset::Invert(const InvertParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("invert"); if (!shader) { E2D_LOG_ERROR("Failed to get invert shader"); return nullptr; @@ -99,8 +99,8 @@ Ptr ShaderPreset::Invert(const InvertParams ¶ms) { * @param params 灰度效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Grayscale(const GrayscaleParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("grayscale"); +SharedPtr ShaderPreset::Grayscale(const GrayscaleParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("grayscale"); if (!shader) { E2D_LOG_ERROR("Failed to get grayscale shader"); return nullptr; @@ -116,8 +116,8 @@ Ptr ShaderPreset::Grayscale(const GrayscaleParams ¶ms) { * @param params 模糊效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::Blur(const BlurParams ¶ms) { - Ptr shader = ShaderManager::getInstance().get("blur"); +SharedPtr ShaderPreset::Blur(const BlurParams ¶ms) { + SharedPtr shader = ShaderManager::getInstance().get("blur"); if (!shader) { E2D_LOG_ERROR("Failed to get blur shader"); return nullptr; @@ -134,13 +134,13 @@ Ptr ShaderPreset::Blur(const BlurParams ¶ms) { * @param outlineParams 描边效果参数 * @return 配置好的着色器 */ -Ptr +SharedPtr ShaderPreset::GrayscaleOutline(const GrayscaleParams &grayParams, const OutlineParams &outlineParams) { std::string shaderDir = ShaderManager::getInstance().getShaderDir(); std::string shaderPath = shaderDir + "effects/grayscale_outline.shader"; - Ptr shader = + SharedPtr shader = ShaderManager::getInstance().loadFromCombinedFile(shaderPath); if (!shader) { E2D_LOG_ERROR("Failed to load grayscale_outline shader from: {}", @@ -163,12 +163,12 @@ ShaderPreset::GrayscaleOutline(const GrayscaleParams &grayParams, * @param invParams 反相效果参数 * @return 配置好的着色器 */ -Ptr ShaderPreset::PixelateInvert(const PixelateParams &pixParams, +SharedPtr ShaderPreset::PixelateInvert(const PixelateParams &pixParams, const InvertParams &invParams) { std::string shaderDir = ShaderManager::getInstance().getShaderDir(); std::string shaderPath = shaderDir + "effects/pixelate_invert.shader"; - Ptr shader = + SharedPtr shader = ShaderManager::getInstance().loadFromCombinedFile(shaderPath); if (!shader) { E2D_LOG_ERROR("Failed to load pixelate_invert shader from: {}", shaderPath); diff --git a/Extra2D/src/scene/node.cpp b/Extra2D/src/scene/node.cpp index 2e5b06f..c9be0b4 100644 --- a/Extra2D/src/scene/node.cpp +++ b/Extra2D/src/scene/node.cpp @@ -27,7 +27,7 @@ Node::~Node() { clearChildren(); } * * 将子节点添加到当前节点的子节点列表中,自动从原父节点分离 */ -void Node::addChild(Ptr child) { +void Node::addChild(SharedPtr child) { if (!child || child.get() == this) { return; } @@ -59,7 +59,7 @@ void Node::addChild(Ptr child) { * * 高效地批量添加多个子节点,预分配内存以减少扩容次数 */ -void Node::addChildren(std::vector> &&children) { +void Node::addChildren(std::vector> &&children) { // 预留空间,避免多次扩容 size_t newSize = children_.size() + children.size(); if (newSize > children_.capacity()) { @@ -102,7 +102,7 @@ void Node::addChildren(std::vector> &&children) { * * 从子节点列表中移除指定节点,并触发相应的退出回调 */ -void Node::removeChild(Ptr child) { +void Node::removeChild(SharedPtr child) { if (!child) return; @@ -146,7 +146,7 @@ void Node::detach() { auto p = parent_.lock(); if (p) { // 安全获取 shared_ptr,避免在对象未由 shared_ptr 管理时崩溃 - Ptr self; + SharedPtr self; try { self = shared_from_this(); } catch (const std::bad_weak_ptr &) { @@ -183,7 +183,7 @@ void Node::clearChildren() { * * 使用哈希索引进行O(1)时间复杂度查找 */ -Ptr Node::findChild(const std::string &name) const { +SharedPtr Node::findChild(const std::string &name) const { // 使用哈希索引,O(1) 查找 auto it = nameIndex_.find(name); if (it != nameIndex_.end()) { @@ -199,7 +199,7 @@ Ptr Node::findChild(const std::string &name) const { * * 使用哈希索引进行O(1)时间复杂度查找 */ -Ptr Node::findChildByTag(int tag) const { +SharedPtr Node::findChildByTag(int tag) const { // 使用哈希索引,O(1) 查找 auto it = tagIndex_.find(tag); if (it != tagIndex_.end()) { @@ -617,7 +617,7 @@ void Node::sortChildren() { } else { // 大数组使用标准排序 std::sort(children_.begin(), children_.end(), - [](const Ptr &a, const Ptr &b) { + [](const SharedPtr &a, const SharedPtr &b) { return a->getZOrder() < b->getZOrder(); }); } diff --git a/Extra2D/src/scene/scene.cpp b/Extra2D/src/scene/scene.cpp index 05670c4..87a9e83 100644 --- a/Extra2D/src/scene/scene.cpp +++ b/Extra2D/src/scene/scene.cpp @@ -10,13 +10,13 @@ namespace extra2d { * * 创建默认相机实例 */ -Scene::Scene() { defaultCamera_ = makePtr(); } +Scene::Scene() { defaultCamera_ = makeShared(); } /** * @brief 设置场景相机 * @param camera 要设置的相机智能指针 */ -void Scene::setCamera(Ptr camera) { camera_ = camera; } +void Scene::setCamera(SharedPtr camera) { camera_ = camera; } /** * @brief 设置视口大小 @@ -122,6 +122,6 @@ void Scene::collectRenderCommands(std::vector &commands, * @brief 创建场景对象 * @return 新创建的场景智能指针 */ -Ptr Scene::create() { return makePtr(); } +SharedPtr Scene::create() { return makeShared(); } } // namespace extra2d diff --git a/Extra2D/src/scene/scene_manager.cpp b/Extra2D/src/scene/scene_manager.cpp index 184e5af..e532c45 100644 --- a/Extra2D/src/scene/scene_manager.cpp +++ b/Extra2D/src/scene/scene_manager.cpp @@ -16,14 +16,14 @@ namespace { * @param worldPos 世界坐标位置 * @return 命中的节点指针,未命中返回nullptr */ -Node *hitTestTopmost(const Ptr &node, const Vec2 &worldPos) { +Node *hitTestTopmost(const SharedPtr &node, const Vec2 &worldPos) { if (!node || !node->isVisible()) { return nullptr; } - std::vector> children = node->getChildren(); + std::vector> children = node->getChildren(); std::stable_sort(children.begin(), children.end(), - [](const Ptr &a, const Ptr &b) { + [](const SharedPtr &a, const SharedPtr &b) { return a->getZOrder() < b->getZOrder(); }); @@ -74,7 +74,7 @@ SceneManager &SceneManager::get() { * * 此方法应在应用启动时调用一次,设置初始场景 */ -void SceneManager::runWithScene(Ptr scene) { +void SceneManager::runWithScene(SharedPtr scene) { if (!scene) { return; } @@ -95,7 +95,7 @@ void SceneManager::runWithScene(Ptr scene) { * * 移除当前场景并替换为新场景,场景栈大小保持不变 */ -void SceneManager::replaceScene(Ptr scene) { +void SceneManager::replaceScene(SharedPtr scene) { if (!scene || isTransitioning_) { return; } @@ -121,7 +121,7 @@ void SceneManager::replaceScene(Ptr scene) { * * 如果场景栈为空则运行场景,否则替换当前场景 */ -void SceneManager::enterScene(Ptr scene) { +void SceneManager::enterScene(SharedPtr scene) { if (!scene || isTransitioning_) { return; } @@ -139,7 +139,7 @@ void SceneManager::enterScene(Ptr scene) { * * 将新场景压入栈顶,暂停当前场景 */ -void SceneManager::pushScene(Ptr scene) { +void SceneManager::pushScene(SharedPtr scene) { if (!scene || isTransitioning_) { return; } @@ -204,8 +204,8 @@ void SceneManager::popToScene(const std::string &name) { return; } - std::stack> tempStack; - Ptr target = nullptr; + std::stack> tempStack; + SharedPtr target = nullptr; while (!sceneStack_.empty()) { auto scene = sceneStack_.top(); @@ -227,7 +227,7 @@ void SceneManager::popToScene(const std::string &name) { * @brief 获取当前场景 * @return 当前栈顶场景的智能指针,栈为空时返回nullptr */ -Ptr SceneManager::getCurrentScene() const { +SharedPtr SceneManager::getCurrentScene() const { if (sceneStack_.empty()) { return nullptr; } @@ -238,7 +238,7 @@ Ptr SceneManager::getCurrentScene() const { * @brief 获取前一个场景 * @return 栈顶下一个场景的智能指针,不存在时返回nullptr */ -Ptr SceneManager::getPreviousScene() const { +SharedPtr SceneManager::getPreviousScene() const { if (sceneStack_.size() < 2) { return nullptr; } @@ -252,13 +252,13 @@ Ptr SceneManager::getPreviousScene() const { * @brief 获取根场景 * @return 栈底场景的智能指针,栈为空时返回nullptr */ -Ptr SceneManager::getRootScene() const { +SharedPtr SceneManager::getRootScene() const { if (sceneStack_.empty()) { return nullptr; } auto tempStack = sceneStack_; - Ptr root; + SharedPtr root; while (!tempStack.empty()) { root = tempStack.top(); tempStack.pop(); @@ -271,7 +271,7 @@ Ptr SceneManager::getRootScene() const { * @param name 场景名称 * @return 找到的场景智能指针,未找到返回nullptr */ -Ptr SceneManager::getSceneByName(const std::string &name) const { +SharedPtr SceneManager::getSceneByName(const std::string &name) const { auto it = namedScenes_.find(name); if (it != namedScenes_.end()) { return it->second; @@ -396,7 +396,7 @@ void SceneManager::dispatchPointerEvents(Scene &scene) { worldPos = camera->screenToWorld(screenPos); } - Ptr root = scene.shared_from_this(); + SharedPtr root = scene.shared_from_this(); Node *newHover = hitTestTopmost(root, worldPos); if (newHover != hoverTarget_) { diff --git a/Extra2D/src/scene/shape_node.cpp b/Extra2D/src/scene/shape_node.cpp index 95c8a88..6f0c846 100644 --- a/Extra2D/src/scene/shape_node.cpp +++ b/Extra2D/src/scene/shape_node.cpp @@ -18,7 +18,7 @@ ShapeNode::ShapeNode() = default; * @brief 创建空的形状节点 * @return 新创建的形状节点智能指针 */ -Ptr ShapeNode::create() { return makePtr(); } +SharedPtr ShapeNode::create() { return makeShared(); } /** * @brief 创建点形状节点 @@ -26,8 +26,8 @@ Ptr ShapeNode::create() { return makePtr(); } * @param color 点的颜色 * @return 新创建的点形状节点智能指针 */ -Ptr ShapeNode::createPoint(const Vec2 &pos, const Color &color) { - auto node = makePtr(); +SharedPtr ShapeNode::createPoint(const Vec2 &pos, const Color &color) { + auto node = makeShared(); node->shapeType_ = ShapeType::Point; node->color_ = color; node->points_ = {pos}; @@ -42,9 +42,9 @@ Ptr ShapeNode::createPoint(const Vec2 &pos, const Color &color) { * @param width 线段宽度 * @return 新创建的线段形状节点智能指针 */ -Ptr ShapeNode::createLine(const Vec2 &start, const Vec2 &end, +SharedPtr ShapeNode::createLine(const Vec2 &start, const Vec2 &end, const Color &color, float width) { - auto node = makePtr(); + auto node = makeShared(); node->shapeType_ = ShapeType::Line; node->color_ = color; node->lineWidth_ = width; @@ -59,9 +59,9 @@ Ptr ShapeNode::createLine(const Vec2 &start, const Vec2 &end, * @param width 边框线宽 * @return 新创建的矩形形状节点智能指针 */ -Ptr ShapeNode::createRect(const Rect &rect, const Color &color, +SharedPtr ShapeNode::createRect(const Rect &rect, const Color &color, float width) { - auto node = makePtr(); + auto node = makeShared(); node->shapeType_ = ShapeType::Rect; node->color_ = color; node->lineWidth_ = width; @@ -78,7 +78,7 @@ Ptr ShapeNode::createRect(const Rect &rect, const Color &color, * @param color 矩形填充颜色 * @return 新创建的填充矩形形状节点智能指针 */ -Ptr ShapeNode::createFilledRect(const Rect &rect, +SharedPtr ShapeNode::createFilledRect(const Rect &rect, const Color &color) { auto node = createRect(rect, color, 0); node->filled_ = true; @@ -94,17 +94,16 @@ Ptr ShapeNode::createFilledRect(const Rect &rect, * @param width 边框线宽 * @return 新创建的圆形形状节点智能指针 */ -Ptr ShapeNode::createCircle(const Vec2 ¢er, float radius, +SharedPtr ShapeNode::createCircle(const Vec2 ¢er, float radius, const Color &color, int segments, float width) { - auto node = makePtr(); + auto node = makeShared(); node->shapeType_ = ShapeType::Circle; node->color_ = color; node->lineWidth_ = width; node->segments_ = segments; node->filled_ = false; node->points_ = {center}; - // Store radius in a point for simplicity node->addPoint(Vec2(radius, 0)); return node; } @@ -117,7 +116,7 @@ Ptr ShapeNode::createCircle(const Vec2 ¢er, float radius, * @param segments 圆的分段数(边数) * @return 新创建的填充圆形形状节点智能指针 */ -Ptr ShapeNode::createFilledCircle(const Vec2 ¢er, float radius, +SharedPtr ShapeNode::createFilledCircle(const Vec2 ¢er, float radius, const Color &color, int segments) { auto node = createCircle(center, radius, color, segments, 0); node->filled_ = true; @@ -133,10 +132,10 @@ Ptr ShapeNode::createFilledCircle(const Vec2 ¢er, float radius, * @param width 边框线宽 * @return 新创建的三角形形状节点智能指针 */ -Ptr ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2, +SharedPtr ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Color &color, float width) { - auto node = makePtr(); + auto node = makeShared(); node->shapeType_ = ShapeType::Triangle; node->color_ = color; node->lineWidth_ = width; @@ -153,7 +152,7 @@ Ptr ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2, * @param color 三角形填充颜色 * @return 新创建的填充三角形形状节点智能指针 */ -Ptr ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2, +SharedPtr ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Color &color) { auto node = createTriangle(p1, p2, p3, color, 0); @@ -168,9 +167,9 @@ Ptr ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2, * @param width 边框线宽 * @return 新创建的多边形形状节点智能指针 */ -Ptr ShapeNode::createPolygon(const std::vector &points, +SharedPtr ShapeNode::createPolygon(const std::vector &points, const Color &color, float width) { - auto node = makePtr(); + auto node = makeShared(); node->shapeType_ = ShapeType::Polygon; node->color_ = color; node->lineWidth_ = width; @@ -185,7 +184,7 @@ Ptr ShapeNode::createPolygon(const std::vector &points, * @param color 多边形填充颜色 * @return 新创建的填充多边形形状节点智能指针 */ -Ptr ShapeNode::createFilledPolygon(const std::vector &points, +SharedPtr ShapeNode::createFilledPolygon(const std::vector &points, const Color &color) { auto node = createPolygon(points, color, 0); node->filled_ = true; @@ -444,4 +443,4 @@ void ShapeNode::generateRenderCommand(std::vector &commands, commands.push_back(std::move(cmd)); } -} // namespace extra2d +} diff --git a/Extra2D/src/scene/sprite.cpp b/Extra2D/src/scene/sprite.cpp index d5368c4..f29aa64 100644 --- a/Extra2D/src/scene/sprite.cpp +++ b/Extra2D/src/scene/sprite.cpp @@ -68,15 +68,15 @@ void Sprite::setFlipY(bool flip) { flipY_ = flip; } * @brief 创建空精灵 * @return 新创建的精灵智能指针 */ -Ptr Sprite::create() { return makePtr(); } +SharedPtr Sprite::create() { return makeShared(); } /** * @brief 创建带纹理的精灵 * @param texture 精灵使用的纹理 * @return 新创建的精灵智能指针 */ -Ptr Sprite::create(Ptr texture) { - return makePtr(texture); +SharedPtr Sprite::create(Ptr texture) { + return makeShared(texture); } /** @@ -85,8 +85,8 @@ Ptr Sprite::create(Ptr texture) { * @param rect 纹理区域 * @return 新创建的精灵智能指针 */ -Ptr Sprite::create(Ptr texture, const Rect &rect) { - auto sprite = makePtr(texture); +SharedPtr Sprite::create(Ptr texture, const Rect &rect) { + auto sprite = makeShared(texture); sprite->setTextureRect(rect); return sprite; } diff --git a/Extra2D/src/services/scene_service.cpp b/Extra2D/src/services/scene_service.cpp index 2ef197a..dbda303 100644 --- a/Extra2D/src/services/scene_service.cpp +++ b/Extra2D/src/services/scene_service.cpp @@ -28,15 +28,15 @@ void SceneService::update(float deltaTime) { } } -void SceneService::runWithScene(Ptr scene) { +void SceneService::runWithScene(SharedPtr scene) { manager_.runWithScene(scene); } -void SceneService::replaceScene(Ptr scene) { +void SceneService::replaceScene(SharedPtr scene) { manager_.replaceScene(scene); } -void SceneService::pushScene(Ptr scene) { +void SceneService::pushScene(SharedPtr scene) { manager_.pushScene(scene); } @@ -52,19 +52,19 @@ void SceneService::popToScene(const std::string& name) { manager_.popToScene(name); } -Ptr SceneService::getCurrentScene() const { +SharedPtr SceneService::getCurrentScene() const { return manager_.getCurrentScene(); } -Ptr SceneService::getPreviousScene() const { +SharedPtr SceneService::getPreviousScene() const { return manager_.getPreviousScene(); } -Ptr SceneService::getRootScene() const { +SharedPtr SceneService::getRootScene() const { return manager_.getRootScene(); } -Ptr SceneService::getSceneByName(const std::string& name) const { +SharedPtr SceneService::getSceneByName(const std::string& name) const { return manager_.getSceneByName(name); } @@ -104,7 +104,7 @@ void SceneService::purgeCachedScenes() { manager_.purgeCachedScenes(); } -void SceneService::enterScene(Ptr scene) { +void SceneService::enterScene(SharedPtr scene) { manager_.enterScene(scene); } diff --git a/xmake.lua b/xmake.lua index 11db356..5d3a8ce 100644 --- a/xmake.lua +++ b/xmake.lua @@ -85,9 +85,21 @@ end if target_plat ~= "switch" then add_requires("glm") add_requires("nlohmann_json") - add_requires("libsdl2") + local sdl2_configs = { + configs = { + wayland = false + } + } + if target_plat == "linux" then + local is_wayland = os.getenv("XDG_SESSION_TYPE") == "wayland" + if is_wayland then + sdl2_configs.configs.wayland = true + end + end + add_requires("libsdl2", sdl2_configs) end + -- ============================================== -- 加载构建目标 -- ==============================================