diff --git a/include/app/application.h b/include/app/application.h index 24d5b5b..b03e658 100644 --- a/include/app/application.h +++ b/include/app/application.h @@ -85,7 +85,7 @@ public: // ------------------------------------------------------------------------ // 便捷方法 // ------------------------------------------------------------------------ - void enterScene(Ptr scene); + void enterScene(IntrusivePtr scene); float deltaTime() const { return deltaTime_; } float totalTime() const { return totalTime_; } diff --git a/include/audio/audio_engine.h b/include/audio/audio_engine.h index 57aac15..8da0ec4 100644 --- a/include/audio/audio_engine.h +++ b/include/audio/audio_engine.h @@ -1,9 +1,9 @@ #pragma once +#include #include #include #include -#include namespace extra2d { @@ -21,10 +21,10 @@ public: bool initialize(); void shutdown(); - std::shared_ptr loadSound(const std::string& filePath); - std::shared_ptr loadSound(const std::string& name, const std::string& filePath); + IntrusivePtr loadSound(const std::string& filePath); + IntrusivePtr loadSound(const std::string& name, const std::string& filePath); - std::shared_ptr getSound(const std::string& name); + IntrusivePtr getSound(const std::string& name); void unloadSound(const std::string& name); void unloadAllSounds(); @@ -39,7 +39,7 @@ private: AudioEngine() = default; ~AudioEngine(); - std::unordered_map> sounds_; + std::unordered_map> sounds_; float masterVolume_ = 1.0f; bool initialized_ = false; }; diff --git a/include/audio/sound.h b/include/audio/sound.h index 7493047..a095052 100644 --- a/include/audio/sound.h +++ b/include/audio/sound.h @@ -1,7 +1,7 @@ #pragma once +#include #include -#include struct Mix_Chunk; @@ -9,7 +9,7 @@ namespace extra2d { class AudioEngine; -class Sound { +class Sound : public RefCounted { public: ~Sound(); diff --git a/include/core/intrusive_ptr.h b/include/core/intrusive_ptr.h new file mode 100644 index 0000000..cbb665c --- /dev/null +++ b/include/core/intrusive_ptr.h @@ -0,0 +1,172 @@ +#pragma once + +#include +#include +#include + +namespace extra2d { + +// ============================================================================ +// 侵入式智能指针 +// 参考 Cocos2d-x 的 IntrusivePtr 设计 +// ============================================================================ +template +class IntrusivePtr { +public: + using element_type = T; + + // 默认构造函数 + IntrusivePtr() : _ptr(nullptr) {} + + // 从原始指针构造 + IntrusivePtr(T* p) : _ptr(p) { + if (_ptr) { + _ptr->addRef(); + } + } + + // 拷贝构造函数 + IntrusivePtr(const IntrusivePtr& r) : _ptr(r._ptr) { + if (_ptr) { + _ptr->addRef(); + } + } + + // 从派生类拷贝构造 + template + IntrusivePtr(const IntrusivePtr& r) : _ptr(r.get()) { + if (_ptr) { + _ptr->addRef(); + } + } + + // 移动构造函数 + IntrusivePtr(IntrusivePtr&& r) noexcept : _ptr(r.release()) {} + + // 从派生类移动构造 + template + IntrusivePtr(IntrusivePtr&& r) noexcept : _ptr(r.release()) {} + + // 析构函数 + ~IntrusivePtr() { + if (_ptr) { + _ptr->release(); + } + } + + // 获取原始指针 + T* get() const { return _ptr; } + + // 解引用操作符 + T& operator*() const { return *_ptr; } + + // 箭头操作符 + T* operator->() const { return _ptr; } + + // 转换为原始指针(隐式转换) + operator T*() const { return _ptr; } + + // 赋值操作符 - 原始指针 + IntrusivePtr& operator=(T* p) { + reset(p); + return *this; + } + + // 赋值操作符 - 同类型 + IntrusivePtr& operator=(const IntrusivePtr& r) { + return *this = r._ptr; + } + + // 赋值操作符 - 派生类 + template + IntrusivePtr& operator=(const IntrusivePtr& r) { + return *this = r.get(); + } + + // 移动赋值 + IntrusivePtr& operator=(IntrusivePtr&& r) noexcept { + IntrusivePtr(std::move(r)).swap(*this); + return *this; + } + + // 从派生类移动赋值 + template + IntrusivePtr& operator=(IntrusivePtr&& r) noexcept { + IntrusivePtr(std::move(r)).swap(*this); + return *this; + } + + // 比较操作符 + bool operator==(std::nullptr_t) const { return _ptr == nullptr; } + bool operator==(T* r) const { return _ptr == r; } + bool operator!=(std::nullptr_t) const { return _ptr != nullptr; } + bool operator!=(T* r) const { return _ptr != r; } + bool operator<(const IntrusivePtr& r) const { return _ptr < r._ptr; } + + // 重置指针 + void reset() noexcept { + if (_ptr) { + _ptr->release(); + } + _ptr = nullptr; + } + + void reset(T* p) { + // 先增加新指针的引用计数,再释放旧指针 + // 这样可以处理自赋值的情况 + if (p) { + p->addRef(); + } + if (_ptr) { + _ptr->release(); + } + _ptr = p; + } + + // 交换指针 + void swap(T** pp) noexcept { + T* p = _ptr; + _ptr = *pp; + *pp = p; + } + + void swap(IntrusivePtr& r) noexcept { + swap(&r._ptr); + } + + // 释放指针所有权(不减少引用计数) + T* release() { + T* retVal = _ptr; + _ptr = nullptr; + return retVal; + } + +private: + T* _ptr; +}; + +// ============================================================================ +// 辅助函数 +// ============================================================================ + +// 创建 IntrusivePtr 的便捷函数 +template +inline IntrusivePtr makePtr(Args&&... args) { + return IntrusivePtr(new T(std::forward(args)...)); +} + +} // namespace extra2d + +// ============================================================================ +// std::hash 特化 +// ============================================================================ +namespace std { + +template +struct hash> { + size_t operator()(const extra2d::IntrusivePtr& val) const noexcept { + return hash{}(val.get()); + } +}; + +} // namespace std diff --git a/include/core/ref_counted.h b/include/core/ref_counted.h new file mode 100644 index 0000000..ed6f5e5 --- /dev/null +++ b/include/core/ref_counted.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +namespace extra2d { + +// ============================================================================ +// 侵入式引用计数基类 +// 参考 Cocos2d-x 的 RefCounted 设计 +// ============================================================================ +class RefCounted { +public: + virtual ~RefCounted() = default; + + // 增加引用计数 + void addRef() { + ++_referenceCount; + } + + // 减少引用计数,当计数为0时删除对象 + void release() { + if (--_referenceCount == 0) { + delete this; + } + } + + // 获取当前引用计数 + uint32_t getRefCount() const { + return _referenceCount.load(); + } + +protected: + // 构造函数,初始引用计数为1 + RefCounted() : _referenceCount(1) {} + +private: + std::atomic _referenceCount; +}; + +} // namespace extra2d diff --git a/include/core/types.h b/include/core/types.h index 5e5b619..7698202 100644 --- a/include/core/types.h +++ b/include/core/types.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -9,15 +10,12 @@ namespace extra2d { // --------------------------------------------------------------------------- // 智能指针别名 // --------------------------------------------------------------------------- -template using Ptr = std::shared_ptr; - template using UniquePtr = std::unique_ptr; -template using WeakPtr = std::weak_ptr; - -/// 创建 shared_ptr 的便捷函数 -template inline Ptr shared(Args &&...args) { - return std::make_shared(std::forward(args)...); +/// 创建 IntrusivePtr 的便捷函数 +template +inline IntrusivePtr makeRef(Args &&...args) { + return makePtr(std::forward(args)...); } /// 创建 unique_ptr 的便捷函数 diff --git a/include/graphics/font.h b/include/graphics/font.h index ad3c547..0f4aa18 100644 --- a/include/graphics/font.h +++ b/include/graphics/font.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include namespace extra2d { @@ -23,7 +23,7 @@ struct Glyph { // ============================================================================ // 字体图集接口 // ============================================================================ -class FontAtlas { +class FontAtlas : public RefCounted { public: virtual ~FontAtlas() = default; diff --git a/include/graphics/opengl/gl_renderer.h b/include/graphics/opengl/gl_renderer.h index 536512f..c0826b5 100644 --- a/include/graphics/opengl/gl_renderer.h +++ b/include/graphics/opengl/gl_renderer.h @@ -37,9 +37,9 @@ public: void popTransform() override; glm::mat4 getCurrentTransform() const override; - Ptr createTexture(int width, int height, const uint8_t *pixels, + IntrusivePtr createTexture(int width, int height, const uint8_t *pixels, int channels) override; - Ptr loadTexture(const std::string &filepath) override; + IntrusivePtr loadTexture(const std::string &filepath) override; void beginSpriteBatch() override; void drawSprite(const Texture &texture, const Rect &destRect, @@ -66,7 +66,7 @@ public: void fillPolygon(const std::vector &points, const Color &color) override; - Ptr createFontAtlas(const std::string &filepath, int fontSize, + IntrusivePtr createFontAtlas(const std::string &filepath, int fontSize, bool useSDF = false) override; void drawText(const FontAtlas &font, const std::string &text, const Vec2 &position, const Color &color) override; diff --git a/include/graphics/opengl/gl_texture.h b/include/graphics/opengl/gl_texture.h index 570823c..117f183 100644 --- a/include/graphics/opengl/gl_texture.h +++ b/include/graphics/opengl/gl_texture.h @@ -35,7 +35,7 @@ public: void setWrap(bool repeat) override; // 从参数创建纹理的工厂方法 - static Ptr create(int width, int height, PixelFormat format); + static IntrusivePtr create(int width, int height, PixelFormat format); // 加载压缩纹理(KTX/DDS 格式) bool loadCompressed(const std::string &filepath); diff --git a/include/graphics/texture.h b/include/graphics/texture.h index 41768be..a2233ca 100644 --- a/include/graphics/texture.h +++ b/include/graphics/texture.h @@ -1,7 +1,7 @@ #pragma once +#include #include -#include namespace extra2d { @@ -33,7 +33,7 @@ enum class PixelFormat { // ============================================================================ // 纹理接口 // ============================================================================ -class Texture { +class Texture : public RefCounted { public: virtual ~Texture() = default; diff --git a/include/graphics/texture_atlas.h b/include/graphics/texture_atlas.h index 1111015..51ecc78 100644 --- a/include/graphics/texture_atlas.h +++ b/include/graphics/texture_atlas.h @@ -49,7 +49,7 @@ public: const uint8_t *pixels, Rect &outUvRect); // 获取图集纹理 - Ptr getTexture() const { return texture_; } + IntrusivePtr getTexture() const { return texture_; } // 获取条目 const AtlasEntry *getEntry(const std::string &name) const; @@ -66,7 +66,7 @@ public: private: int width_, height_; - Ptr texture_; + IntrusivePtr texture_; std::unordered_map entries_; // 矩形打包数据 diff --git a/include/renderer/camera.h b/include/renderer/camera.h index 0bd3a54..6ed242b 100644 --- a/include/renderer/camera.h +++ b/include/renderer/camera.h @@ -2,8 +2,8 @@ #include #include +#include #include -#include #include #include @@ -12,7 +12,7 @@ namespace extra2d { // ============================================================================ // 2D 正交相机 // ============================================================================ -class Camera { +class Camera : public RefCounted { public: Camera(); Camera(float left, float right, float bottom, float top); diff --git a/include/renderer/render_target.h b/include/renderer/render_target.h index 88b15f0..ef0ce30 100644 --- a/include/renderer/render_target.h +++ b/include/renderer/render_target.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include @@ -25,7 +25,7 @@ struct RenderTargetConfig { // ============================================================================ // 渲染目标 - 基于FBO的离屏渲染 // ============================================================================ -class RenderTarget { +class RenderTarget : public RefCounted { public: RenderTarget(); ~RenderTarget(); @@ -55,7 +55,7 @@ public: /** * @brief 从现有纹理创建渲染目标 */ - bool createFromTexture(Ptr texture, bool hasDepth = false); + bool createFromTexture(IntrusivePtr texture, bool hasDepth = false); /** * @brief 销毁渲染目标 @@ -109,12 +109,12 @@ public: /** * @brief 获取颜色纹理 */ - Ptr getColorTexture() const { return colorTexture_; } + IntrusivePtr getColorTexture() const { return colorTexture_; } /** * @brief 获取深度纹理(如果有) */ - Ptr getDepthTexture() const { return depthTexture_; } + IntrusivePtr getDepthTexture() const { return depthTexture_; } // ------------------------------------------------------------------------ // 视口和裁剪 @@ -169,7 +169,7 @@ public: /** * @brief 创建渲染目标的静态工厂方法 */ - static Ptr createFromConfig(const RenderTargetConfig &config); + static IntrusivePtr createFromConfig(const RenderTargetConfig &config); /** * @brief 获取当前绑定的渲染目标ID @@ -190,8 +190,8 @@ protected: GLuint fbo_ = 0; // 帧缓冲对象 GLuint rbo_ = 0; // 渲染缓冲对象(深度/模板) - Ptr colorTexture_; // 颜色纹理 - Ptr depthTexture_; // 深度纹理(可选) + IntrusivePtr colorTexture_; // 颜色纹理 + IntrusivePtr depthTexture_; // 深度纹理(可选) int width_ = 0; int height_ = 0; @@ -293,7 +293,7 @@ public: /** * @brief 创建新的渲染目标 */ - Ptr createRenderTarget(const RenderTargetConfig &config); + IntrusivePtr createRenderTarget(const RenderTargetConfig &config); /** * @brief 获取默认渲染目标 @@ -318,8 +318,8 @@ private: RenderTargetManager(const RenderTargetManager &) = delete; RenderTargetManager &operator=(const RenderTargetManager &) = delete; - Ptr defaultRenderTarget_; - std::vector> renderTargets_; + IntrusivePtr defaultRenderTarget_; + std::vector> renderTargets_; bool initialized_ = false; }; diff --git a/include/renderer/renderer.h b/include/renderer/renderer.h index f0b28e0..10d6d27 100644 --- a/include/renderer/renderer.h +++ b/include/renderer/renderer.h @@ -73,9 +73,9 @@ public: // ------------------------------------------------------------------------ // 纹理 // ------------------------------------------------------------------------ - virtual Ptr createTexture(int width, int height, + virtual IntrusivePtr createTexture(int width, int height, const uint8_t *pixels, int channels) = 0; - virtual Ptr loadTexture(const std::string &filepath) = 0; + virtual IntrusivePtr loadTexture(const std::string &filepath) = 0; // ------------------------------------------------------------------------ // 精灵批渲染 @@ -112,7 +112,7 @@ public: // ------------------------------------------------------------------------ // 文字渲染 // ------------------------------------------------------------------------ - virtual Ptr createFontAtlas(const std::string &filepath, + virtual IntrusivePtr createFontAtlas(const std::string &filepath, int fontSize, bool useSDF = false) = 0; virtual void drawText(const FontAtlas &font, const std::string &text, const Vec2 &position, const Color &color) = 0; diff --git a/include/resource/resource_manager.h b/include/resource/resource_manager.h index 1015ad9..a15cc0f 100644 --- a/include/resource/resource_manager.h +++ b/include/resource/resource_manager.h @@ -39,14 +39,14 @@ enum class TextureFormat { // 纹理LRU缓存项 // ============================================================================ struct TextureCacheEntry { - Ptr texture; + IntrusivePtr texture; size_t size = 0; // 纹理大小(字节) float lastAccessTime = 0.0f; // 最后访问时间 uint32_t accessCount = 0; // 访问次数 }; // 异步加载回调类型 -using TextureLoadCallback = std::function)>; +using TextureLoadCallback = std::function)>; class ResourceManager { public: @@ -60,13 +60,13 @@ public: // ------------------------------------------------------------------------ /// 加载纹理(带缓存) - Ptr loadTexture(const std::string &filepath); + IntrusivePtr loadTexture(const std::string &filepath); /// 加载纹理(指定是否异步) - Ptr loadTexture(const std::string &filepath, bool async); + IntrusivePtr loadTexture(const std::string &filepath, bool async); /// 加载纹理(完整参数:异步 + 压缩格式) - Ptr loadTexture(const std::string &filepath, bool async, + IntrusivePtr loadTexture(const std::string &filepath, bool async, TextureFormat format); /// 异步加载纹理(带回调) @@ -78,10 +78,10 @@ public: TextureLoadCallback callback); /// 加载纹理并生成Alpha遮罩(用于不规则形状图片) - Ptr loadTextureWithAlphaMask(const std::string &filepath); + IntrusivePtr loadTextureWithAlphaMask(const std::string &filepath); /// 通过key获取已缓存的纹理 - Ptr getTexture(const std::string &key) const; + IntrusivePtr getTexture(const std::string &key) const; /// 检查纹理是否已缓存 bool hasTexture(const std::string &key) const; @@ -107,11 +107,11 @@ public: // ------------------------------------------------------------------------ /// 加载字体图集(带缓存) - Ptr loadFont(const std::string &filepath, int fontSize, + IntrusivePtr loadFont(const std::string &filepath, int fontSize, bool useSDF = false); /// 通过key获取已缓存的字体图集 - Ptr getFont(const std::string &key) const; + IntrusivePtr getFont(const std::string &key) const; /// 检查字体是否已缓存 bool hasFont(const std::string &key) const; @@ -124,11 +124,11 @@ public: // ------------------------------------------------------------------------ /// 加载音效(带缓存) - Ptr loadSound(const std::string &filepath); - Ptr loadSound(const std::string &name, const std::string &filepath); + IntrusivePtr loadSound(const std::string &filepath); + IntrusivePtr loadSound(const std::string &name, const std::string &filepath); /// 通过key获取已缓存的音效 - Ptr getSound(const std::string &key) const; + IntrusivePtr getSound(const std::string &key) const; /// 检查音效是否已缓存 bool hasSound(const std::string &key) const; @@ -255,7 +255,7 @@ private: bool useSDF) const; // 内部加载实现 - Ptr loadTextureInternal(const std::string &filepath, + IntrusivePtr loadTextureInternal(const std::string &filepath, TextureFormat format); // 选择最佳纹理格式 @@ -273,9 +273,9 @@ private: mutable std::mutex textFileMutex_; mutable std::mutex jsonFileMutex_; - // 资源缓存 - 使用弱指针实现自动清理 - std::unordered_map> fontCache_; - std::unordered_map> soundCache_; + // 资源缓存 - 使用 IntrusivePtr 强引用 + std::unordered_map> fontCache_; + std::unordered_map> soundCache_; // 文本文件缓存 - 使用强引用(字符串值类型) std::unordered_map textFileCache_; @@ -318,7 +318,7 @@ private: std::string filepath; TextureFormat format; TextureLoadCallback callback; - std::promise> promise; + std::promise> promise; }; std::queue asyncTaskQueue_; diff --git a/include/scene/node.h b/include/scene/node.h index 31693b1..9630ab5 100644 --- a/include/scene/node.h +++ b/include/scene/node.h @@ -1,14 +1,11 @@ #pragma once -#include #include #include #include #include #include -#include #include -#include #include #include @@ -22,7 +19,7 @@ struct RenderCommand; // ============================================================================ // 节点基类 - 场景图的基础 // ============================================================================ -class Node : public std::enable_shared_from_this { +class Node : public RefCounted { public: Node(); virtual ~Node(); @@ -30,23 +27,23 @@ public: // ------------------------------------------------------------------------ // 层级管理 // ------------------------------------------------------------------------ - void addChild(Ptr child); + void addChild(IntrusivePtr child); /** * @brief 批量添加子节点 * @param children 子节点列表 */ - void addChildren(std::vector> &&children); + void addChildren(std::vector> &&children); - void removeChild(Ptr child); + void removeChild(IntrusivePtr child); void removeChildByName(const std::string &name); void removeFromParent(); void removeAllChildren(); - Ptr parent() const { return parent_.lock(); } - const std::vector> &children() const { return children_; } - Ptr childByName(const std::string &name) const; - Ptr childByTag(int tag) const; + Node* parent() const { return parent_; } + const std::vector> &children() const { return children_; } + IntrusivePtr childByName(const std::string &name) const; + IntrusivePtr childByTag(int tag) const; // ------------------------------------------------------------------------ // 变换属性 @@ -195,17 +192,17 @@ private: // 2. 字符串和容器(24-32字节) std::string name_; // 32 bytes - std::vector> children_; // 24 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 + Node* parent_ = nullptr; // 8 bytes // 7. 变换属性(按访问频率分组) Vec2 position_ = Vec2::Zero(); // 8 bytes @@ -237,8 +234,6 @@ private: bool childrenOrderDirty_ = false; // 1 byte bool visible_ = true; // 1 byte bool running_ = false; // 1 byte - - }; } // namespace extra2d diff --git a/include/scene/scene.h b/include/scene/scene.h index e529eb5..cae5261 100644 --- a/include/scene/scene.h +++ b/include/scene/scene.h @@ -27,8 +27,8 @@ public: // ------------------------------------------------------------------------ // 摄像机 // ------------------------------------------------------------------------ - void setCamera(Ptr camera); - Ptr getCamera() const { return camera_; } + void setCamera(IntrusivePtr camera); + IntrusivePtr getCamera() const { return camera_; } Camera *getActiveCamera() const { return camera_ ? camera_.get() : defaultCamera_.get(); @@ -63,7 +63,7 @@ public: // ------------------------------------------------------------------------ // 静态创建方法 // ------------------------------------------------------------------------ - static Ptr create(); + static IntrusivePtr create(); protected: void onEnter() override; @@ -75,8 +75,8 @@ private: Color backgroundColor_ = Colors::Black; Size viewportSize_ = Size::Zero(); - Ptr camera_; - Ptr defaultCamera_; + IntrusivePtr camera_; + IntrusivePtr defaultCamera_; bool paused_ = false; }; diff --git a/include/scene/scene_manager.h b/include/scene/scene_manager.h index 76d17cc..e66f0c6 100644 --- a/include/scene/scene_manager.h +++ b/include/scene/scene_manager.h @@ -29,13 +29,13 @@ public: // ------------------------------------------------------------------------ // 运行第一个场景 - void runWithScene(Ptr scene); + void runWithScene(IntrusivePtr scene); // 替换当前场景 - void replaceScene(Ptr scene); + void replaceScene(IntrusivePtr scene); // 压入新场景(当前场景暂停) - void pushScene(Ptr scene); + void pushScene(IntrusivePtr scene); // 弹出当前场景(恢复上一个场景) void popScene(); @@ -49,12 +49,12 @@ public: // ------------------------------------------------------------------------ // 获取场景 // ------------------------------------------------------------------------ - Ptr getCurrentScene() const; - Ptr getPreviousScene() const; - Ptr getRootScene() const; + IntrusivePtr getCurrentScene() const; + IntrusivePtr getPreviousScene() const; + IntrusivePtr getRootScene() const; // 通过名称获取场景 - Ptr getSceneByName(const std::string &name) const; + IntrusivePtr getSceneByName(const std::string &name) const; // ------------------------------------------------------------------------ // 查询 @@ -83,17 +83,17 @@ public: SceneManager &operator=(const SceneManager &) = delete; // 场景切换(供 Application 使用) - void enterScene(Ptr scene); + void enterScene(IntrusivePtr scene); private: void doSceneSwitch(); void dispatchPointerEvents(Scene &scene); - std::stack> sceneStack_; - std::unordered_map> namedScenes_; + std::stack> sceneStack_; + std::unordered_map> namedScenes_; // Next scene to switch to (queued during transition) - Ptr nextScene_; + IntrusivePtr nextScene_; bool sendCleanupToScene_ = false; Node *hoverTarget_ = nullptr; diff --git a/include/scene/shape.h b/include/scene/shape.h index 4f56957..3740e67 100644 --- a/include/scene/shape.h +++ b/include/scene/shape.h @@ -23,40 +23,40 @@ public: // ------------------------------------------------------------------------ // 静态创建方法 // ------------------------------------------------------------------------ - static Ptr create(); + static IntrusivePtr create(); // 点 - static Ptr createPoint(const Vec2 &pos, const Color &color); + static IntrusivePtr createPoint(const Vec2 &pos, const Color &color); // 线 - static Ptr createLine(const Vec2 &start, const Vec2 &end, + static IntrusivePtr createLine(const Vec2 &start, const Vec2 &end, const Color &color, float width = 1.0f); // 矩形 - static Ptr createRect(const Rect &rect, const Color &color, + static IntrusivePtr createRect(const Rect &rect, const Color &color, float width = 1.0f); - static Ptr createFilledRect(const Rect &rect, const Color &color); + static IntrusivePtr createFilledRect(const Rect &rect, const Color &color); // 圆形 - static Ptr createCircle(const Vec2 ¢er, float radius, + static IntrusivePtr 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 IntrusivePtr createFilledCircle(const Vec2 ¢er, float radius, const Color &color, int segments = 32); // 三角形 - static Ptr createTriangle(const Vec2 &p1, const Vec2 &p2, + static IntrusivePtr 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, + static IntrusivePtr createFilledTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Color &color); // 多边形 - static Ptr createPolygon(const std::vector &points, + static IntrusivePtr createPolygon(const std::vector &points, const Color &color, float width = 1.0f); - static Ptr createFilledPolygon(const std::vector &points, + static IntrusivePtr createFilledPolygon(const std::vector &points, const Color &color); // ------------------------------------------------------------------------ diff --git a/include/scene/sprite.h b/include/scene/sprite.h index 0b3e0d5..3b38ade 100644 --- a/include/scene/sprite.h +++ b/include/scene/sprite.h @@ -11,12 +11,12 @@ namespace extra2d { class Sprite : public Node { public: Sprite(); - explicit Sprite(Ptr texture); + explicit Sprite(IntrusivePtr texture); ~Sprite() override = default; // 纹理 - void setTexture(Ptr texture); - Ptr getTexture() const { return texture_; } + void setTexture(IntrusivePtr texture); + IntrusivePtr getTexture() const { return texture_; } // 纹理矩形 (用于图集) void setTextureRect(const Rect &rect); @@ -33,9 +33,9 @@ public: bool flipY() const { return flipY_; } // 静态创建方法 - static Ptr create(); - static Ptr create(Ptr texture); - static Ptr create(Ptr texture, const Rect &rect); + static IntrusivePtr create(); + static IntrusivePtr create(IntrusivePtr texture); + static IntrusivePtr create(IntrusivePtr texture, const Rect &rect); Rect boundingBox() const override; @@ -45,7 +45,7 @@ protected: int zOrder) override; private: - Ptr texture_; + IntrusivePtr texture_; Rect textureRect_; Color color_ = Colors::White; bool flipX_ = false; diff --git a/src/app/application.cpp b/src/app/application.cpp index 4143d26..4b6d1ca 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -362,7 +362,7 @@ EventDispatcher &Application::eventDispatcher() { return *eventDispatcher_; } Camera &Application::camera() { return *camera_; } -void Application::enterScene(Ptr scene) { +void Application::enterScene(IntrusivePtr scene) { if (sceneManager_ && scene) { scene->setViewportSize(static_cast(window_->width()), static_cast(window_->height())); diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index ac368d4..b2b9228 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -54,11 +54,11 @@ void AudioEngine::shutdown() { E2D_LOG_INFO("AudioEngine shutdown"); } -std::shared_ptr AudioEngine::loadSound(const std::string &filePath) { +IntrusivePtr AudioEngine::loadSound(const std::string &filePath) { return loadSound(filePath, filePath); } -std::shared_ptr AudioEngine::loadSound(const std::string &name, +IntrusivePtr AudioEngine::loadSound(const std::string &name, const std::string &filePath) { if (!initialized_) { E2D_LOG_ERROR("AudioEngine not initialized"); @@ -77,14 +77,14 @@ std::shared_ptr AudioEngine::loadSound(const std::string &name, return nullptr; } - auto sound = std::shared_ptr(new Sound(name, filePath, chunk)); + auto sound = IntrusivePtr(new Sound(name, filePath, chunk)); sounds_[name] = sound; E2D_LOG_DEBUG("Loaded sound: {}", filePath); return sound; } -std::shared_ptr AudioEngine::getSound(const std::string &name) { +IntrusivePtr AudioEngine::getSound(const std::string &name) { auto it = sounds_.find(name); if (it != sounds_.end()) { return it->second; diff --git a/src/graphics/opengl/gl_renderer.cpp b/src/graphics/opengl/gl_renderer.cpp index 372b720..04004fb 100644 --- a/src/graphics/opengl/gl_renderer.cpp +++ b/src/graphics/opengl/gl_renderer.cpp @@ -256,13 +256,13 @@ glm::mat4 GLRenderer::getCurrentTransform() const { return transformStack_.back(); } -Ptr GLRenderer::createTexture(int width, int height, +IntrusivePtr GLRenderer::createTexture(int width, int height, const uint8_t *pixels, int channels) { - return shared(width, height, pixels, channels); + return makeRef(width, height, pixels, channels); } -Ptr GLRenderer::loadTexture(const std::string &filepath) { - return shared(filepath); +IntrusivePtr GLRenderer::loadTexture(const std::string &filepath) { + return makeRef(filepath); } void GLRenderer::beginSpriteBatch() { spriteBatch_.begin(viewProjection_); } @@ -476,9 +476,9 @@ void GLRenderer::fillPolygon(const std::vector &points, } } -Ptr GLRenderer::createFontAtlas(const std::string &filepath, +IntrusivePtr GLRenderer::createFontAtlas(const std::string &filepath, int fontSize, bool useSDF) { - return shared(filepath, fontSize, useSDF); + return makeRef(filepath, fontSize, useSDF); } void GLRenderer::drawText(const FontAtlas &font, const std::string &text, diff --git a/src/graphics/opengl/gl_texture.cpp b/src/graphics/opengl/gl_texture.cpp index 71709d7..45be138 100644 --- a/src/graphics/opengl/gl_texture.cpp +++ b/src/graphics/opengl/gl_texture.cpp @@ -438,7 +438,7 @@ void GLTexture::generateAlphaMask() { PixelFormat GLTexture::getFormat() const { return format_; } -Ptr GLTexture::create(int width, int height, PixelFormat format) { +IntrusivePtr GLTexture::create(int width, int height, PixelFormat format) { int channels = 4; switch (format) { case PixelFormat::R8: @@ -457,7 +457,7 @@ Ptr GLTexture::create(int width, int height, PixelFormat format) { channels = 4; break; } - return shared(width, height, nullptr, channels); + return makeRef(width, height, nullptr, channels); } } // namespace extra2d diff --git a/src/graphics/texture_atlas.cpp b/src/graphics/texture_atlas.cpp index 2e53d87..5af8a7f 100644 --- a/src/graphics/texture_atlas.cpp +++ b/src/graphics/texture_atlas.cpp @@ -14,7 +14,7 @@ TextureAtlasPage::TextureAtlasPage(int width, int height) : width_(width), height_(height), isFull_(false), usedArea_(0) { // 创建空白纹理 std::vector emptyData(width * height * 4, 0); - texture_ = shared(width, height, emptyData.data(), 4); + texture_ = makeRef(width, height, emptyData.data(), 4); // 初始化矩形打包根节点 root_ = std::make_unique(0, 0, width, height); diff --git a/src/renderer/render_target.cpp b/src/renderer/render_target.cpp index e2ddad7..6bb6624 100644 --- a/src/renderer/render_target.cpp +++ b/src/renderer/render_target.cpp @@ -73,7 +73,7 @@ bool RenderTarget::create(const RenderTargetConfig &config) { return true; } -bool RenderTarget::createFromTexture(Ptr texture, bool hasDepth) { +bool RenderTarget::createFromTexture(IntrusivePtr texture, bool hasDepth) { if (!texture || !texture->isValid()) { E2D_ERROR("无效的颜色纹理"); return false; @@ -296,9 +296,9 @@ bool RenderTarget::saveToFile(const std::string &filepath) { return true; } -Ptr +IntrusivePtr RenderTarget::createFromConfig(const RenderTargetConfig &config) { - auto rt = std::make_shared(); + auto rt = makeRef(); if (rt->create(config)) { return rt; } @@ -556,7 +556,7 @@ void RenderTargetManager::shutdown() { E2D_INFO("渲染目标管理器已关闭"); } -Ptr +IntrusivePtr RenderTargetManager::createRenderTarget(const RenderTargetConfig &config) { if (!initialized_) { E2D_ERROR("渲染目标管理器未初始化"); diff --git a/src/resource/resource_manager.cpp b/src/resource/resource_manager.cpp index 4411252..5a782fb 100644 --- a/src/resource/resource_manager.cpp +++ b/src/resource/resource_manager.cpp @@ -22,7 +22,7 @@ static bool fileExists(const std::string &path) { // 辅助函数:检查是否是 romfs 路径 static bool isRomfsPath(const std::string &path) { - return path.find("romfs:/") == 0 || path.find("romfs:\\") == 0; + return path.find("romfs:/") == 0 || path.find("romfs:") == 0; } // 辅助函数:获取可执行文件所在目录(Windows 平台) @@ -169,16 +169,16 @@ void ResourceManager::asyncLoadLoop() { // 纹理资源 - 同步加载 // ============================================================================ -Ptr ResourceManager::loadTexture(const std::string &filepath) { +IntrusivePtr ResourceManager::loadTexture(const std::string &filepath) { return loadTexture(filepath, false, TextureFormat::Auto); } -Ptr ResourceManager::loadTexture(const std::string &filepath, +IntrusivePtr ResourceManager::loadTexture(const std::string &filepath, bool async) { return loadTexture(filepath, async, TextureFormat::Auto); } -Ptr ResourceManager::loadTexture(const std::string &filepath, +IntrusivePtr ResourceManager::loadTexture(const std::string &filepath, bool async, TextureFormat format) { if (async) { // 异步加载:返回空指针,实际纹理通过回调获取 @@ -235,7 +235,7 @@ void ResourceManager::loadTextureAsync(const std::string &filepath, E2D_LOG_DEBUG("ResourceManager: queued async texture load: {}", filepath); } -Ptr ResourceManager::loadTextureInternal(const std::string &filepath, +IntrusivePtr ResourceManager::loadTextureInternal(const std::string &filepath, TextureFormat format) { std::lock_guard lock(textureMutex_); @@ -262,7 +262,7 @@ Ptr ResourceManager::loadTextureInternal(const std::string &filepath, // 创建新纹理 try { - auto texture = shared(fullPath); + auto texture = makeRef(fullPath); if (!texture->isValid()) { E2D_LOG_ERROR("ResourceManager: failed to load texture: {}", filepath); return nullptr; @@ -338,7 +338,7 @@ std::vector ResourceManager::compressTexture(const uint8_t *data, return result; } -Ptr +IntrusivePtr ResourceManager::loadTextureWithAlphaMask(const std::string &filepath) { // 先加载纹理 auto texture = loadTexture(filepath); @@ -389,7 +389,7 @@ bool ResourceManager::hasAlphaMask(const std::string &textureKey) const { return false; } -Ptr ResourceManager::getTexture(const std::string &key) const { +IntrusivePtr ResourceManager::getTexture(const std::string &key) const { std::lock_guard lock(textureMutex_); auto it = textureCache_.find(key); @@ -439,7 +439,7 @@ std::string ResourceManager::makeFontKey(const std::string &filepath, return filepath + "#" + std::to_string(fontSize) + (useSDF ? "#sdf" : ""); } -Ptr ResourceManager::loadFont(const std::string &filepath, +IntrusivePtr ResourceManager::loadFont(const std::string &filepath, int fontSize, bool useSDF) { std::lock_guard lock(fontMutex_); @@ -448,12 +448,8 @@ Ptr ResourceManager::loadFont(const std::string &filepath, // 检查缓存 auto it = fontCache_.find(key); if (it != fontCache_.end()) { - if (auto font = it->second.lock()) { - E2D_LOG_TRACE("ResourceManager: font cache hit: {}", key); - return font; - } - // 弱引用已失效,移除 - fontCache_.erase(it); + E2D_LOG_TRACE("ResourceManager: font cache hit: {}", key); + return it->second; } // 解析资源路径(优先尝试 romfs:/ 前缀) @@ -465,7 +461,7 @@ Ptr ResourceManager::loadFont(const std::string &filepath, // 创建新字体图集 try { - auto font = shared(fullPath, fontSize, useSDF); + auto font = makeRef(fullPath, fontSize, useSDF); if (!font->getTexture() || !font->getTexture()->isValid()) { E2D_LOG_ERROR("ResourceManager: failed to load font: {}", filepath); return nullptr; @@ -482,24 +478,19 @@ Ptr ResourceManager::loadFont(const std::string &filepath, } } -Ptr ResourceManager::getFont(const std::string &key) const { +IntrusivePtr ResourceManager::getFont(const std::string &key) const { std::lock_guard lock(fontMutex_); auto it = fontCache_.find(key); if (it != fontCache_.end()) { - return it->second.lock(); + return it->second; } return nullptr; } bool ResourceManager::hasFont(const std::string &key) const { std::lock_guard lock(fontMutex_); - - auto it = fontCache_.find(key); - if (it != fontCache_.end()) { - return !it->second.expired(); - } - return false; + return fontCache_.find(key) != fontCache_.end(); } void ResourceManager::unloadFont(const std::string &key) { @@ -512,23 +503,19 @@ void ResourceManager::unloadFont(const std::string &key) { // 音效资源 // ============================================================================ -Ptr ResourceManager::loadSound(const std::string &filepath) { +IntrusivePtr ResourceManager::loadSound(const std::string &filepath) { return loadSound(filepath, filepath); } -Ptr ResourceManager::loadSound(const std::string &name, +IntrusivePtr ResourceManager::loadSound(const std::string &name, const std::string &filepath) { std::lock_guard lock(soundMutex_); // 检查缓存 auto it = soundCache_.find(name); if (it != soundCache_.end()) { - if (auto sound = it->second.lock()) { - E2D_LOG_TRACE("ResourceManager: sound cache hit: {}", name); - return sound; - } - // 弱引用已失效,移除 - soundCache_.erase(it); + E2D_LOG_TRACE("ResourceManager: sound cache hit: {}", name); + return it->second; } // 解析资源路径(优先尝试 romfs:/ 前缀) @@ -551,24 +538,19 @@ Ptr ResourceManager::loadSound(const std::string &name, return sound; } -Ptr ResourceManager::getSound(const std::string &key) const { +IntrusivePtr ResourceManager::getSound(const std::string &key) const { std::lock_guard lock(soundMutex_); auto it = soundCache_.find(key); if (it != soundCache_.end()) { - return it->second.lock(); + return it->second; } return nullptr; } bool ResourceManager::hasSound(const std::string &key) const { std::lock_guard lock(soundMutex_); - - auto it = soundCache_.find(key); - if (it != soundCache_.end()) { - return !it->second.expired(); - } - return false; + return soundCache_.find(key) != soundCache_.end(); } void ResourceManager::unloadSound(const std::string &key) { @@ -586,31 +568,8 @@ void ResourceManager::unloadSound(const std::string &key) { void ResourceManager::purgeUnused() { // 纹理缓存使用LRU策略,不需要清理失效引用 - // 字体缓存 - { - std::lock_guard lock(fontMutex_); - for (auto it = fontCache_.begin(); it != fontCache_.end();) { - if (it->second.expired()) { - E2D_LOG_TRACE("ResourceManager: purging unused font: {}", it->first); - it = fontCache_.erase(it); - } else { - ++it; - } - } - } - - // 音效缓存 - { - std::lock_guard lock(soundMutex_); - for (auto it = soundCache_.begin(); it != soundCache_.end();) { - if (it->second.expired()) { - E2D_LOG_TRACE("ResourceManager: purging unused sound: {}", it->first); - it = soundCache_.erase(it); - } else { - ++it; - } - } - } + // 字体和音效缓存使用 IntrusivePtr 强引用,不需要清理失效引用 + // 当外部没有引用时,缓存会自动释放 } void ResourceManager::clearTextureCache() { diff --git a/src/scene/node.cpp b/src/scene/node.cpp index 2664de4..0d94531 100644 --- a/src/scene/node.cpp +++ b/src/scene/node.cpp @@ -11,22 +11,22 @@ Node::Node() = default; Node::~Node() { removeAllChildren(); } -void Node::addChild(Ptr child) { +void Node::addChild(IntrusivePtr child) { if (!child || child.get() == this) { return; } child->removeFromParent(); - child->parent_ = weak_from_this(); + child->parent_ = this; children_.push_back(child); childrenOrderDirty_ = true; // 更新索引 if (!child->name().empty()) { - nameIndex_[child->name()] = child; + nameIndex_[child->name()] = child.get(); } if (child->tag() != -1) { - tagIndex_[child->tag()] = child; + tagIndex_[child->tag()] = child.get(); } if (running_) { @@ -37,7 +37,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()) { @@ -50,15 +50,15 @@ void Node::addChildren(std::vector> &&children) { } child->removeFromParent(); - child->parent_ = weak_from_this(); + child->parent_ = this; children_.push_back(child); // 更新索引 if (!child->name().empty()) { - nameIndex_[child->name()] = child; + nameIndex_[child->name()] = child.get(); } if (child->tag() != -1) { - tagIndex_[child->tag()] = child; + tagIndex_[child->tag()] = child.get(); } if (running_) { @@ -74,7 +74,7 @@ void Node::addChildren(std::vector> &&children) { } } -void Node::removeChild(Ptr child) { +void Node::removeChild(IntrusivePtr child) { if (!child) return; @@ -94,7 +94,7 @@ void Node::removeChild(Ptr child) { if ((*it)->tag() != -1) { tagIndex_.erase((*it)->tag()); } - (*it)->parent_.reset(); + (*it)->parent_ = nullptr; children_.erase(it); } } @@ -107,18 +107,9 @@ void Node::removeChildByName(const std::string &name) { } void Node::removeFromParent() { - auto p = parent_.lock(); + auto p = parent_; if (p) { - // 安全获取 shared_ptr,避免在对象未由 shared_ptr 管理时崩溃 - Ptr self; - try { - self = shared_from_this(); - } catch (const std::bad_weak_ptr &) { - // 对象不是由 shared_ptr 管理的,直接重置父节点引用 - parent_.reset(); - return; - } - p->removeChild(self); + p->removeChild(IntrusivePtr(this)); } } @@ -128,27 +119,27 @@ void Node::removeAllChildren() { child->onDetachFromScene(); child->onExit(); } - child->parent_.reset(); + child->parent_ = nullptr; } children_.clear(); nameIndex_.clear(); tagIndex_.clear(); } -Ptr Node::childByName(const std::string &name) const { +IntrusivePtr Node::childByName(const std::string &name) const { // 使用哈希索引,O(1) 查找 auto it = nameIndex_.find(name); if (it != nameIndex_.end()) { - return it->second.lock(); + return IntrusivePtr(it->second); } return nullptr; } -Ptr Node::childByTag(int tag) const { +IntrusivePtr Node::childByTag(int tag) const { // 使用哈希索引,O(1) 查找 auto it = tagIndex_.find(tag); if (it != tagIndex_.end()) { - return it->second.lock(); + return IntrusivePtr(it->second); } return nullptr; } @@ -261,8 +252,7 @@ glm::mat4 Node::getWorldTransform() const { const Node *current = this; while (current && chainCount < nodeChainCache.size()) { nodeChainCache[chainCount++] = current; - auto p = current->parent_.lock(); - current = p.get(); + current = current->parent_; } // 从根节点开始计算 @@ -297,7 +287,7 @@ void Node::batchUpdateTransforms() { // 如果世界变换脏了,需要重新计算 if (worldTransformDirty_) { - auto parent = parent_.lock(); + auto parent = parent_; if (parent) { // 使用父节点的世界变换(确保父节点已经更新) worldTransform_ = parent->getWorldTransform() * localTransform_; @@ -403,7 +393,7 @@ void Node::sortChildren() { } else { // 大数组使用标准排序 std::sort(children_.begin(), children_.end(), - [](const Ptr &a, const Ptr &b) { + [](const IntrusivePtr &a, const IntrusivePtr &b) { return a->zOrder() < b->zOrder(); }); } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 3522e41..4948ea2 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -5,9 +5,9 @@ namespace extra2d { -Scene::Scene() { defaultCamera_ = shared(); } +Scene::Scene() { defaultCamera_ = makeRef(); } -void Scene::setCamera(Ptr camera) { camera_ = camera; } +void Scene::setCamera(IntrusivePtr camera) { camera_ = camera; } void Scene::setViewportSize(float width, float height) { viewportSize_ = Size(width, height); @@ -68,6 +68,6 @@ void Scene::collectRenderCommands(std::vector &commands, Node::collectRenderCommands(commands, parentZOrder); } -Ptr Scene::create() { return shared(); } +IntrusivePtr Scene::create() { return makeRef(); } } // namespace extra2d diff --git a/src/scene/scene_manager.cpp b/src/scene/scene_manager.cpp index 50aa811..9a469d0 100644 --- a/src/scene/scene_manager.cpp +++ b/src/scene/scene_manager.cpp @@ -11,14 +11,14 @@ namespace extra2d { namespace { -Node *hitTestTopmost(const Ptr &node, const Vec2 &worldPos) { +Node *hitTestTopmost(const IntrusivePtr &node, const Vec2 &worldPos) { if (!node || !node->visible()) { return nullptr; } - std::vector> children = node->children(); + std::vector> children = node->children(); std::stable_sort(children.begin(), children.end(), - [](const Ptr &a, const Ptr &b) { + [](const IntrusivePtr &a, const IntrusivePtr &b) { return a->zOrder() < b->zOrder(); }); @@ -54,7 +54,7 @@ SceneManager &SceneManager::getInstance() { return instance; } -void SceneManager::runWithScene(Ptr scene) { +void SceneManager::runWithScene(IntrusivePtr scene) { if (!scene) { return; } @@ -69,7 +69,7 @@ void SceneManager::runWithScene(Ptr scene) { sceneStack_.push(scene); } -void SceneManager::replaceScene(Ptr scene) { +void SceneManager::replaceScene(IntrusivePtr scene) { if (!scene) { return; } @@ -91,7 +91,7 @@ void SceneManager::replaceScene(Ptr scene) { sceneStack_.push(scene); } -void SceneManager::enterScene(Ptr scene) { +void SceneManager::enterScene(IntrusivePtr scene) { if (!scene) { return; } @@ -103,7 +103,7 @@ void SceneManager::enterScene(Ptr scene) { } } -void SceneManager::pushScene(Ptr scene) { +void SceneManager::pushScene(IntrusivePtr scene) { if (!scene) { return; } @@ -154,8 +154,8 @@ void SceneManager::popToRootScene() { void SceneManager::popToScene(const std::string &name) { // Find target scene in stack - std::stack> tempStack; - Ptr target = nullptr; + std::stack> tempStack; + IntrusivePtr target = nullptr; while (!sceneStack_.empty()) { auto scene = sceneStack_.top(); @@ -173,14 +173,14 @@ void SceneManager::popToScene(const std::string &name) { } } -Ptr SceneManager::getCurrentScene() const { +IntrusivePtr SceneManager::getCurrentScene() const { if (sceneStack_.empty()) { return nullptr; } return sceneStack_.top(); } -Ptr SceneManager::getPreviousScene() const { +IntrusivePtr SceneManager::getPreviousScene() const { if (sceneStack_.size() < 2) { return nullptr; } @@ -191,14 +191,14 @@ Ptr SceneManager::getPreviousScene() const { return tempStack.top(); } -Ptr SceneManager::getRootScene() const { +IntrusivePtr SceneManager::getRootScene() const { if (sceneStack_.empty()) { return nullptr; } // Copy stack to access bottom auto tempStack = sceneStack_; - Ptr root; + IntrusivePtr root; while (!tempStack.empty()) { root = tempStack.top(); tempStack.pop(); @@ -206,7 +206,7 @@ Ptr SceneManager::getRootScene() const { return root; } -Ptr SceneManager::getSceneByName(const std::string &name) const { +IntrusivePtr SceneManager::getSceneByName(const std::string &name) const { auto it = namedScenes_.find(name); if (it != namedScenes_.end()) { return it->second; @@ -285,7 +285,7 @@ void SceneManager::dispatchPointerEvents(Scene &scene) { worldPos = camera->screenToWorld(screenPos); } - Ptr root = scene.shared_from_this(); + IntrusivePtr root = IntrusivePtr(&scene); Node *newHover = hitTestTopmost(root, worldPos); if (newHover != hoverTarget_) { diff --git a/src/scene/shape_node.cpp b/src/scene/shape_node.cpp index f85d784..8a8929e 100644 --- a/src/scene/shape_node.cpp +++ b/src/scene/shape_node.cpp @@ -9,19 +9,19 @@ namespace extra2d { ShapeNode::ShapeNode() = default; -Ptr ShapeNode::create() { return shared(); } +IntrusivePtr ShapeNode::create() { return makeRef(); } -Ptr ShapeNode::createPoint(const Vec2 &pos, const Color &color) { - auto node = shared(); +IntrusivePtr ShapeNode::createPoint(const Vec2 &pos, const Color &color) { + auto node = makeRef(); node->shapeType_ = ShapeType::Point; node->color_ = color; node->points_ = {pos}; return node; } -Ptr ShapeNode::createLine(const Vec2 &start, const Vec2 &end, +IntrusivePtr ShapeNode::createLine(const Vec2 &start, const Vec2 &end, const Color &color, float width) { - auto node = shared(); + auto node = makeRef(); node->shapeType_ = ShapeType::Line; node->color_ = color; node->lineWidth_ = width; @@ -29,9 +29,9 @@ Ptr ShapeNode::createLine(const Vec2 &start, const Vec2 &end, return node; } -Ptr ShapeNode::createRect(const Rect &rect, const Color &color, +IntrusivePtr ShapeNode::createRect(const Rect &rect, const Color &color, float width) { - auto node = shared(); + auto node = makeRef(); node->shapeType_ = ShapeType::Rect; node->color_ = color; node->lineWidth_ = width; @@ -42,17 +42,17 @@ Ptr ShapeNode::createRect(const Rect &rect, const Color &color, return node; } -Ptr ShapeNode::createFilledRect(const Rect &rect, +IntrusivePtr ShapeNode::createFilledRect(const Rect &rect, const Color &color) { auto node = createRect(rect, color, 0); node->filled_ = true; return node; } -Ptr ShapeNode::createCircle(const Vec2 ¢er, float radius, +IntrusivePtr ShapeNode::createCircle(const Vec2 ¢er, float radius, const Color &color, int segments, float width) { - auto node = shared(); + auto node = makeRef(); node->shapeType_ = ShapeType::Circle; node->color_ = color; node->lineWidth_ = width; @@ -64,17 +64,17 @@ Ptr ShapeNode::createCircle(const Vec2 ¢er, float radius, return node; } -Ptr ShapeNode::createFilledCircle(const Vec2 ¢er, float radius, +IntrusivePtr ShapeNode::createFilledCircle(const Vec2 ¢er, float radius, const Color &color, int segments) { auto node = createCircle(center, radius, color, segments, 0); node->filled_ = true; return node; } -Ptr ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2, - const Vec2 &p3, const Color &color, - float width) { - auto node = shared(); +IntrusivePtr ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2, + const Vec2 &p3, const Color &color, + float width) { + auto node = makeRef(); node->shapeType_ = ShapeType::Triangle; node->color_ = color; node->lineWidth_ = width; @@ -83,17 +83,17 @@ Ptr ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2, return node; } -Ptr ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2, - const Vec2 &p3, - const Color &color) { +IntrusivePtr ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2, + const Vec2 &p3, + const Color &color) { auto node = createTriangle(p1, p2, p3, color, 0); node->filled_ = true; return node; } -Ptr ShapeNode::createPolygon(const std::vector &points, - const Color &color, float width) { - auto node = shared(); +IntrusivePtr ShapeNode::createPolygon(const std::vector &points, + const Color &color, float width) { + auto node = makeRef(); node->shapeType_ = ShapeType::Polygon; node->color_ = color; node->lineWidth_ = width; @@ -102,8 +102,8 @@ Ptr ShapeNode::createPolygon(const std::vector &points, return node; } -Ptr ShapeNode::createFilledPolygon(const std::vector &points, - const Color &color) { +IntrusivePtr ShapeNode::createFilledPolygon(const std::vector &points, + const Color &color) { auto node = createPolygon(points, color, 0); node->filled_ = true; return node; diff --git a/src/scene/sprite.cpp b/src/scene/sprite.cpp index 04c84bf..fa2372e 100644 --- a/src/scene/sprite.cpp +++ b/src/scene/sprite.cpp @@ -9,9 +9,9 @@ namespace extra2d { Sprite::Sprite() = default; -Sprite::Sprite(Ptr texture) { setTexture(texture); } +Sprite::Sprite(IntrusivePtr texture) { setTexture(texture); } -void Sprite::setTexture(Ptr texture) { +void Sprite::setTexture(IntrusivePtr texture) { texture_ = texture; if (texture_) { textureRect_ = Rect(0, 0, static_cast(texture_->width()), @@ -27,14 +27,14 @@ void Sprite::setFlipX(bool flip) { flipX_ = flip; } void Sprite::setFlipY(bool flip) { flipY_ = flip; } -Ptr Sprite::create() { return shared(); } +IntrusivePtr Sprite::create() { return makeRef(); } -Ptr Sprite::create(Ptr texture) { - return shared(texture); +IntrusivePtr Sprite::create(IntrusivePtr texture) { + return makeRef(texture); } -Ptr Sprite::create(Ptr texture, const Rect &rect) { - auto sprite = shared(texture); +IntrusivePtr Sprite::create(IntrusivePtr texture, const Rect &rect) { + auto sprite = makeRef(texture); sprite->setTextureRect(rect); return sprite; }