refactor(core): 替换 Ptr 为 PooledPtr 并引入对象池机制

重构智能指针系统,将原有的 std::shared_ptr 替换为自定义的 PooledPtr:
1. 新增 ObjectPool 和 PooledPtr 实现对象池功能,提升内存分配性能
2. 区分 Ptr<T> (PooledPtr) 和 SharedPtr<T> (std::shared_ptr) 使用场景
3. 修改所有继承自 enable_shared_from_this 的类使用 SharedPtr
4. 更新相关接口和实现以适配新的智能指针类型
5. 添加 SDL2 的 Wayland 支持配置

同时优化了智能指针相关的类型定义和内存管理机制,提升系统整体性能。对于需要共享所有权的场景使用 SharedPtr,其他场景使用更高效的 PooledPtr。
This commit is contained in:
ChestnutYueyue 2026-02-15 15:01:22 +08:00
parent 0700bad5d9
commit 3962de715f
29 changed files with 924 additions and 205 deletions

View File

@ -131,7 +131,7 @@ public:
* @brief
* @param scene
*/
void enterScene(Ptr<class Scene> scene);
void enterScene(SharedPtr<class Scene> scene);
/**
* @brief

View File

@ -0,0 +1,675 @@
#pragma once
#include <extra2d/core/types.h>
#include <atomic>
#include <condition_variable>
#include <deque>
#include <functional>
#include <memory>
#include <mutex>
#include <type_traits>
#include <unordered_map>
#include <vector>
namespace extra2d {
// ============================================================================
// IPoolable - 可池化对象接口
// 实现此接口的对象在归还对象池时会自动调用 reset() 方法
// ============================================================================
class IPoolable {
public:
/**
* @brief
*/
virtual ~IPoolable() = default;
/**
* @brief
* 便
*/
virtual void reset() = 0;
};
// ============================================================================
// is_poolable_v - 类型特征,检测类型是否实现 IPoolable 接口
// ============================================================================
template <typename T>
struct is_poolable : std::is_base_of<IPoolable, T> {};
template <typename T>
inline constexpr bool is_poolable_v = is_poolable<T>::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<int32> 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<T> - 线程安全的通用对象池模板
// ============================================================================
template <typename T>
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<std::mutex> 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 <typename... Args>
std::pair<T*, ControlBlock*> acquire(Args&&... args) {
std::lock_guard<std::mutex> 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>(args)...);
} else {
// 创建新对象
obj = new T(std::forward<Args>(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<T*>(cb->object);
std::lock_guard<std::mutex> lock(mutex_);
// 如果对象实现了 IPoolable调用 reset()
if constexpr (is_poolable_v<T>) {
static_cast<IPoolable*>(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<std::mutex> 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<std::mutex> lock(mutex_);
clearUnsafe();
}
/**
* @brief
* @param keepCount
* @return
*/
size_t shrink(size_t keepCount = 0) {
std::lock_guard<std::mutex> 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<std::mutex> lock(mutex_);
return stats_;
}
/**
* @brief
* @return
*/
size_t activeCount() const {
std::lock_guard<std::mutex> lock(mutex_);
return stats_.activeCount;
}
/**
* @brief
* @return
*/
size_t freeCount() const {
std::lock_guard<std::mutex> 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<std::pair<T*, ControlBlock*>> freeList_; // 空闲列表
std::vector<std::pair<T*, ControlBlock*>> allObjects_; // 所有对象(用于析构)
mutable ObjectPoolStats stats_;
};
// ============================================================================
// PooledPtr<T> - 池化智能指针,行为与 shared_ptr 兼容
// ============================================================================
template <typename T>
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 <typename U, typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
PooledPtr(const PooledPtr<U>& other)
: ptr_(other.get()), controlBlock_(other.controlBlock()) {
if (controlBlock_) {
controlBlock_->addRef();
}
}
/**
* @brief PooledPtr
*/
template <typename U, typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
PooledPtr(PooledPtr<U>&& 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<ObjectPool<T>*>(controlBlock_->pool);
if (pool) {
pool->release(controlBlock_);
}
}
}
T* ptr_;
ControlBlock* controlBlock_;
// 允许其他类型的 PooledPtr 访问私有成员
template <typename U>
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 <typename T>
ObjectPool<T>& getPool() {
std::lock_guard<std::mutex> lock(mutex_);
using PoolPtr = UniquePtr<ObjectPool<T>>;
static PoolPtr pool = makeUnique<ObjectPool<T>>();
return *pool;
}
// ========================================================================
// 预分配
// ========================================================================
/**
* @brief
* @param count
*/
template <typename T>
void preallocate(size_t count) {
getPool<T>().preallocate(count);
}
// ========================================================================
// 统计信息
// ========================================================================
/**
* @brief
* @return
*/
template <typename T>
ObjectPoolStats getStats() {
return getPool<T>().getStats();
}
/**
* @brief
* @param keepCount
* @return
*/
template <typename T>
size_t shrink(size_t keepCount = 0) {
return getPool<T>().shrink(keepCount);
}
private:
ObjectPoolManager() = default;
mutable std::mutex mutex_;
};
// ============================================================================
// 辅助函数 - 从对象池创建对象
// ============================================================================
/**
* @brief
* @param args
* @return PooledPtr
*/
template <typename T, typename... Args>
PooledPtr<T> makePooled(Args&&... args) {
auto& pool = ObjectPoolManager::instance().getPool<T>();
auto [ptr, cb] = pool.acquire(std::forward<Args>(args)...);
return PooledPtr<T>(ptr, cb);
}
} // namespace extra2d

View File

@ -5,6 +5,15 @@
#include <memory>
#include <string>
// 前向声明
namespace extra2d {
template <typename T> class PooledPtr;
template <typename T> class ObjectPool;
struct ControlBlock;
class ObjectPoolManager;
template <typename T, typename... Args> PooledPtr<T> makePooled(Args&&...);
}
namespace extra2d {
// ---------------------------------------------------------------------------
@ -16,18 +25,20 @@ namespace extra2d {
// ---------------------------------------------------------------------------
// 智能指针别名
// ---------------------------------------------------------------------------
template <typename T> using Ptr = std::shared_ptr<T>;
// Ptr<T> 使用对象池支持的智能指针(透明替换原有 shared_ptr
template <typename T> using Ptr = PooledPtr<T>;
// SharedPtr<T> 保留为 std::shared_ptr兼容旧代码
template <typename T> using SharedPtr = std::shared_ptr<T>;
template <typename T> using UniquePtr = std::unique_ptr<T>;
template <typename T> using WeakPtr = std::weak_ptr<T>;
/// 创建 shared_ptr 的便捷函数
template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
/// 创建 Ptr<T> 的便捷函数(使用对象池)
template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args);
/// 创建 shared_ptr 的便捷函数(兼容旧代码)
template <typename T, typename... Args> inline SharedPtr<T> makeShared(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
@ -56,3 +67,15 @@ using uint32 = std::uint32_t;
using uint64 = std::uint64_t;
} // namespace extra2d
// 包含对象池实现(需要完整类型定义)
#include <extra2d/core/object_pool.h>
namespace extra2d {
// makePtr 实现(放在 include 之后,因为需要完整的 PooledPtr 定义)
template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args) {
return makePooled<T>(std::forward<Args>(args)...);
}
} // namespace extra2d

View File

@ -90,7 +90,7 @@ private:
IWindow* window_;
GLSpriteBatch spriteBatch_;
Ptr<IShader> shapeShader_;
SharedPtr<IShader> shapeShader_;
GLuint shapeVao_;
GLuint shapeVbo_;

View File

@ -174,7 +174,7 @@ public:
* @param fragSource
* @return Shader实例
*/
Ptr<IShader> createFromSource(
SharedPtr<IShader> createFromSource(
const std::string& name,
const std::string& vertSource,
const std::string& fragSource) override;
@ -185,7 +185,7 @@ public:
* @param binary
* @return Shader实例
*/
Ptr<IShader> createFromBinary(
SharedPtr<IShader> createFromBinary(
const std::string& name,
const std::vector<uint8_t>& binary) override;

View File

@ -150,7 +150,7 @@ public:
/**
* @brief
*/
static Ptr<RenderTarget> createFromConfig(const RenderTargetConfig &config);
static SharedPtr<RenderTarget> createFromConfig(const RenderTargetConfig &config);
/**
* @brief ID
@ -274,7 +274,7 @@ public:
/**
* @brief
*/
Ptr<RenderTarget> createRenderTarget(const RenderTargetConfig &config);
SharedPtr<RenderTarget> createRenderTarget(const RenderTargetConfig &config);
/**
* @brief
@ -299,8 +299,8 @@ private:
RenderTargetMgr(const RenderTargetMgr &) = delete;
RenderTargetMgr &operator=(const RenderTargetMgr &) = delete;
Ptr<RenderTarget> defaultRenderTarget_;
std::vector<Ptr<RenderTarget>> renderTargets_;
SharedPtr<RenderTarget> defaultRenderTarget_;
std::vector<SharedPtr<RenderTarget>> renderTargets_;
bool initialized_ = false;
};

View File

@ -54,7 +54,7 @@ public:
* @param name Shader名称
* @return nullptr
*/
Ptr<ShaderCacheEntry> loadCache(const std::string& name);
SharedPtr<ShaderCacheEntry> loadCache(const std::string& name);
/**
* @brief

View File

@ -124,7 +124,7 @@ public:
* @param fragSource
* @return Shader实例
*/
virtual Ptr<IShader> createFromSource(
virtual SharedPtr<IShader> 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<IShader> createFromBinary(
virtual SharedPtr<IShader> createFromBinary(
const std::string& name,
const std::vector<uint8_t>& binary) = 0;

View File

@ -13,7 +13,7 @@ namespace extra2d {
// ============================================================================
// Shader重载回调
// ============================================================================
using ShaderReloadCallback = std::function<void(Ptr<IShader> newShader)>;
using ShaderReloadCallback = std::function<void(SharedPtr<IShader> newShader)>;
// ============================================================================
// Shader管理器 - 统一入口
@ -37,7 +37,7 @@ public:
* @param appName
* @return truefalse
*/
bool init(Ptr<IShaderFactory> factory, const std::string& appName = "extra2d");
bool init(SharedPtr<IShaderFactory> factory, const std::string& appName = "extra2d");
/**
* @brief Shader系统
@ -48,7 +48,7 @@ public:
*/
bool init(const std::string& shaderDir,
const std::string& cacheDir,
Ptr<IShaderFactory> factory);
SharedPtr<IShaderFactory> factory);
/**
* @brief Shader系统
@ -79,7 +79,7 @@ public:
* @param fragPath
* @return Shader实例
*/
Ptr<IShader> loadFromFiles(const std::string& name,
SharedPtr<IShader> loadFromFiles(const std::string& name,
const std::string& vertPath,
const std::string& fragPath);
@ -88,7 +88,7 @@ public:
* @param path Shader文件路径
* @return Shader实例
*/
Ptr<IShader> loadFromCombinedFile(const std::string& path);
SharedPtr<IShader> loadFromCombinedFile(const std::string& path);
/**
* @brief Shader
@ -97,7 +97,7 @@ public:
* @param fragSource
* @return Shader实例
*/
Ptr<IShader> loadFromSource(const std::string& name,
SharedPtr<IShader> 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<IShader> get(const std::string& name) const;
SharedPtr<IShader> get(const std::string& name) const;
/**
* @brief Shader是否存在
@ -170,7 +170,7 @@ public:
* @param name Shader名称
* @return Shader实例
*/
Ptr<IShader> getBuiltin(const std::string& name);
SharedPtr<IShader> getBuiltin(const std::string& name);
/**
* @brief Shader
@ -202,11 +202,11 @@ private:
std::string shaderDir_;
std::string cacheDir_;
Ptr<IShaderFactory> factory_;
SharedPtr<IShaderFactory> factory_;
ShaderLoader loader_;
struct ShaderInfo {
Ptr<IShader> shader;
SharedPtr<IShader> shader;
ShaderMetadata metadata;
ShaderReloadCallback reloadCallback;
std::string vertSource;
@ -227,7 +227,7 @@ private:
* @param fragSource
* @return Shader实例
*/
Ptr<IShader> loadFromCache(const std::string& name,
SharedPtr<IShader> loadFromCache(const std::string& name,
const std::string& sourceHash,
const std::string& vertSource,
const std::string& fragSource);

View File

@ -46,49 +46,49 @@ public:
* @param params
* @return
*/
static Ptr<IShader> Water(const WaterParams& params = {});
static SharedPtr<IShader> Water(const WaterParams& params = {});
/**
* @brief
* @param params
* @return
*/
static Ptr<IShader> Outline(const OutlineParams& params = {});
static SharedPtr<IShader> Outline(const OutlineParams& params = {});
/**
* @brief
* @param params
* @return
*/
static Ptr<IShader> Distortion(const DistortionParams& params = {});
static SharedPtr<IShader> Distortion(const DistortionParams& params = {});
/**
* @brief
* @param params
* @return
*/
static Ptr<IShader> Pixelate(const PixelateParams& params = {});
static SharedPtr<IShader> Pixelate(const PixelateParams& params = {});
/**
* @brief
* @param params
* @return
*/
static Ptr<IShader> Invert(const InvertParams& params = {});
static SharedPtr<IShader> Invert(const InvertParams& params = {});
/**
* @brief
* @param params
* @return
*/
static Ptr<IShader> Grayscale(const GrayscaleParams& params = {});
static SharedPtr<IShader> Grayscale(const GrayscaleParams& params = {});
/**
* @brief
* @param params
* @return
*/
static Ptr<IShader> Blur(const BlurParams& params = {});
static SharedPtr<IShader> Blur(const BlurParams& params = {});
/**
* @brief +
@ -96,7 +96,7 @@ public:
* @param outlineParams
* @return
*/
static Ptr<IShader> GrayscaleOutline(const GrayscaleParams& grayParams,
static SharedPtr<IShader> GrayscaleOutline(const GrayscaleParams& grayParams,
const OutlineParams& outlineParams);
/**
@ -105,8 +105,8 @@ public:
* @param invParams
* @return
*/
static Ptr<IShader> PixelateInvert(const PixelateParams& pixParams,
static SharedPtr<IShader> PixelateInvert(const PixelateParams& pixParams,
const InvertParams& invParams);
};
} // namespace extra2d
}

View File

@ -18,6 +18,7 @@ struct RenderCommand;
// ============================================================================
// 节点基类 - 场景图的基础
// 注意Node 使用 SharedPtr 而非 Ptr因为需要 enable_shared_from_this 支持
// ============================================================================
class Node : public std::enable_shared_from_this<Node> {
public:
@ -27,23 +28,23 @@ public:
// ------------------------------------------------------------------------
// 层级管理
// ------------------------------------------------------------------------
void addChild(Ptr<Node> child);
void addChild(SharedPtr<Node> child);
/**
* @brief
* @param children
*/
void addChildren(std::vector<Ptr<Node>> &&children);
void addChildren(std::vector<SharedPtr<Node>> &&children);
void removeChild(Ptr<Node> child);
void removeChild(SharedPtr<Node> child);
void removeChildByName(const std::string &name);
void detach();
void clearChildren();
Ptr<Node> getParent() const { return parent_.lock(); }
const std::vector<Ptr<Node>> &getChildren() const { return children_; }
Ptr<Node> findChild(const std::string &name) const;
Ptr<Node> findChildByTag(int tag) const;
SharedPtr<Node> getParent() const { return parent_.lock(); }
const std::vector<SharedPtr<Node>> &getChildren() const { return children_; }
SharedPtr<Node> findChild(const std::string &name) const;
SharedPtr<Node> 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<Ptr<Node>> children_; // 24 bytes
std::string name_; // 32 bytes
std::vector<SharedPtr<Node>> children_; // 24 bytes
// 3. 子节点索引(加速查找)
std::unordered_map<std::string, WeakPtr<Node>> nameIndex_; // 56 bytes
std::unordered_map<int, WeakPtr<Node>> tagIndex_; // 56 bytes
std::unordered_map<std::string, std::weak_ptr<Node>> nameIndex_; // 56 bytes
std::unordered_map<int, std::weak_ptr<Node>> tagIndex_; // 56 bytes
// 4. 事件分发器
EventDispatcher eventDispatcher_; // 大小取决于实现
// 5. 父节点引用
WeakPtr<Node> parent_; // 16 bytes
std::weak_ptr<Node> parent_; // 16 bytes
// 7. 变换属性(按访问频率分组)
Vec2 position_ = Vec2::Zero(); // 8 bytes

View File

@ -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> camera);
Ptr<Camera> getCamera() const { return camera_; }
void setCamera(SharedPtr<Camera> camera);
SharedPtr<Camera> getCamera() const { return camera_; }
Camera *getActiveCamera() const {
return camera_ ? camera_.get() : defaultCamera_.get();
@ -63,7 +64,7 @@ public:
// ------------------------------------------------------------------------
// 静态创建方法
// ------------------------------------------------------------------------
static Ptr<Scene> create();
static SharedPtr<Scene> create();
protected:
void onEnter() override;
@ -80,8 +81,8 @@ private:
Color backgroundColor_ = Colors::Black;
Size viewportSize_ = Size::Zero();
Ptr<Camera> camera_;
Ptr<Camera> defaultCamera_;
SharedPtr<Camera> camera_;
SharedPtr<Camera> defaultCamera_;
bool paused_ = false;
};

View File

@ -22,17 +22,17 @@ public:
static SceneManager &get();
void runWithScene(Ptr<Scene> scene);
void replaceScene(Ptr<Scene> scene);
void pushScene(Ptr<Scene> scene);
void runWithScene(SharedPtr<Scene> scene);
void replaceScene(SharedPtr<Scene> scene);
void pushScene(SharedPtr<Scene> scene);
void popScene();
void popToRootScene();
void popToScene(const std::string &name);
Ptr<Scene> getCurrentScene() const;
Ptr<Scene> getPreviousScene() const;
Ptr<Scene> getRootScene() const;
Ptr<Scene> getSceneByName(const std::string &name) const;
SharedPtr<Scene> getCurrentScene() const;
SharedPtr<Scene> getPreviousScene() const;
SharedPtr<Scene> getRootScene() const;
SharedPtr<Scene> 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> scene);
void enterScene(SharedPtr<Scene> scene);
private:
void doSceneSwitch();
void dispatchPointerEvents(Scene &scene);
std::stack<Ptr<Scene>> sceneStack_;
std::unordered_map<std::string, Ptr<Scene>> namedScenes_;
std::stack<SharedPtr<Scene>> sceneStack_;
std::unordered_map<std::string, SharedPtr<Scene>> namedScenes_;
bool isTransitioning_ = false;
TransitionCallback transitionCallback_;
Ptr<Scene> nextScene_;
SharedPtr<Scene> nextScene_;
bool sendCleanupToScene_ = false;
Node *hoverTarget_ = nullptr;

View File

@ -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<ShapeNode> create();
static SharedPtr<ShapeNode> create();
// 点
static Ptr<ShapeNode> createPoint(const Vec2 &pos, const Color &color);
static SharedPtr<ShapeNode> createPoint(const Vec2 &pos, const Color &color);
// 线
static Ptr<ShapeNode> createLine(const Vec2 &start, const Vec2 &end,
const Color &color, float width = 1.0f);
static SharedPtr<ShapeNode> createLine(const Vec2 &start, const Vec2 &end,
const Color &color,
float width = 1.0f);
// 矩形
static Ptr<ShapeNode> createRect(const Rect &rect, const Color &color,
float width = 1.0f);
static Ptr<ShapeNode> createFilledRect(const Rect &rect, const Color &color);
static SharedPtr<ShapeNode> createRect(const Rect &rect, const Color &color,
float width = 1.0f);
static SharedPtr<ShapeNode> createFilledRect(const Rect &rect,
const Color &color);
// 圆形
static Ptr<ShapeNode> createCircle(const Vec2 &center, float radius,
const Color &color, int segments = 32,
float width = 1.0f);
static Ptr<ShapeNode> createFilledCircle(const Vec2 &center, float radius,
static SharedPtr<ShapeNode> createCircle(const Vec2 &center, float radius,
const Color &color,
int segments = 32);
int segments = 32,
float width = 1.0f);
static SharedPtr<ShapeNode> createFilledCircle(const Vec2 &center,
float radius,
const Color &color,
int segments = 32);
// 三角形
static Ptr<ShapeNode> createTriangle(const Vec2 &p1, const Vec2 &p2,
const Vec2 &p3, const Color &color,
float width = 1.0f);
static Ptr<ShapeNode> createFilledTriangle(const Vec2 &p1, const Vec2 &p2,
const Vec2 &p3,
const Color &color);
static SharedPtr<ShapeNode> createTriangle(const Vec2 &p1, const Vec2 &p2,
const Vec2 &p3, const Color &color,
float width = 1.0f);
static SharedPtr<ShapeNode> createFilledTriangle(const Vec2 &p1,
const Vec2 &p2,
const Vec2 &p3,
const Color &color);
// 多边形
static Ptr<ShapeNode> createPolygon(const std::vector<Vec2> &points,
const Color &color, float width = 1.0f);
static Ptr<ShapeNode> createFilledPolygon(const std::vector<Vec2> &points,
const Color &color);
static SharedPtr<ShapeNode> createPolygon(const std::vector<Vec2> &points,
const Color &color,
float width = 1.0f);
static SharedPtr<ShapeNode>
createFilledPolygon(const std::vector<Vec2> &points, const Color &color);
// ------------------------------------------------------------------------
// 属性设置

View File

@ -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<Sprite> create();
static Ptr<Sprite> create(Ptr<Texture> texture);
static Ptr<Sprite> create(Ptr<Texture> texture, const Rect &rect);
static SharedPtr<Sprite> create();
static SharedPtr<Sprite> create(Ptr<Texture> texture);
static SharedPtr<Sprite> create(Ptr<Texture> texture, const Rect &rect);
Rect getBounds() const override;
@ -52,4 +53,4 @@ private:
bool flipY_ = false;
};
} // namespace extra2d
}

View File

@ -13,17 +13,17 @@ class ISceneService : public IService {
public:
virtual ~ISceneService() = default;
virtual void runWithScene(Ptr<Scene> scene) = 0;
virtual void replaceScene(Ptr<Scene> scene) = 0;
virtual void pushScene(Ptr<Scene> scene) = 0;
virtual void runWithScene(SharedPtr<Scene> scene) = 0;
virtual void replaceScene(SharedPtr<Scene> scene) = 0;
virtual void pushScene(SharedPtr<Scene> scene) = 0;
virtual void popScene() = 0;
virtual void popToRootScene() = 0;
virtual void popToScene(const std::string& name) = 0;
virtual Ptr<Scene> getCurrentScene() const = 0;
virtual Ptr<Scene> getPreviousScene() const = 0;
virtual Ptr<Scene> getRootScene() const = 0;
virtual Ptr<Scene> getSceneByName(const std::string& name) const = 0;
virtual SharedPtr<Scene> getCurrentScene() const = 0;
virtual SharedPtr<Scene> getPreviousScene() const = 0;
virtual SharedPtr<Scene> getRootScene() const = 0;
virtual SharedPtr<Scene> 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> scene) = 0;
virtual void enterScene(SharedPtr<Scene> scene) = 0;
};
/**
@ -55,17 +55,17 @@ public:
void shutdown() override;
void update(float deltaTime) override;
void runWithScene(Ptr<Scene> scene) override;
void replaceScene(Ptr<Scene> scene) override;
void pushScene(Ptr<Scene> scene) override;
void runWithScene(SharedPtr<Scene> scene) override;
void replaceScene(SharedPtr<Scene> scene) override;
void pushScene(SharedPtr<Scene> scene) override;
void popScene() override;
void popToRootScene() override;
void popToScene(const std::string& name) override;
Ptr<Scene> getCurrentScene() const override;
Ptr<Scene> getPreviousScene() const override;
Ptr<Scene> getRootScene() const override;
Ptr<Scene> getSceneByName(const std::string& name) const override;
SharedPtr<Scene> getCurrentScene() const override;
SharedPtr<Scene> getPreviousScene() const override;
SharedPtr<Scene> getRootScene() const override;
SharedPtr<Scene> 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> scene) override;
void enterScene(SharedPtr<Scene> scene) override;
SceneManager& getManager() { return manager_; }
const SceneManager& getManager() const { return manager_; }

View File

@ -383,7 +383,7 @@ SharedPtr<ICameraService> Application::camera() {
return ServiceLocator::instance().getService<ICameraService>();
}
void Application::enterScene(Ptr<Scene> scene) {
void Application::enterScene(SharedPtr<Scene> scene) {
auto sceneService = ServiceLocator::instance().getService<ISceneService>();
if (sceneService && scene) {
scene->setViewportSize(static_cast<float>(window_->width()),

View File

@ -269,7 +269,7 @@ GLint GLShaderNew::getUniformLocation(const std::string& name) {
* @param fragSource
* @return Shader实例
*/
Ptr<IShader> GLShaderFactory::createFromSource(
SharedPtr<IShader> GLShaderFactory::createFromSource(
const std::string& name,
const std::string& vertSource,
const std::string& fragSource) {
@ -291,7 +291,7 @@ Ptr<IShader> GLShaderFactory::createFromSource(
* @param binary
* @return Shader实例
*/
Ptr<IShader> GLShaderFactory::createFromBinary(
SharedPtr<IShader> GLShaderFactory::createFromBinary(
const std::string& name,
const std::vector<uint8_t>& binary) {

View File

@ -383,9 +383,9 @@ bool RenderTarget::saveToFile(const std::string &filepath) {
*
*
*/
Ptr<RenderTarget>
SharedPtr<RenderTarget>
RenderTarget::createFromConfig(const RenderTargetConfig &config) {
auto rt = std::make_shared<RenderTarget>();
auto rt = makeShared<RenderTarget>();
if (rt->create(config)) {
return rt;
}
@ -741,7 +741,7 @@ void RenderTargetMgr::shutdown() {
*
*
*/
Ptr<RenderTarget>
SharedPtr<RenderTarget>
RenderTargetMgr::createRenderTarget(const RenderTargetConfig &config) {
if (!initialized_) {
E2D_ERROR("渲染目标管理器未初始化");

View File

@ -74,7 +74,7 @@ bool ShaderCache::hasValidCache(const std::string& name, const std::string& sour
* @param name Shader名称
* @return nullptr
*/
Ptr<ShaderCacheEntry> ShaderCache::loadCache(const std::string& name) {
SharedPtr<ShaderCacheEntry> ShaderCache::loadCache(const std::string& name) {
auto it = cacheMap_.find(name);
if (it == cacheMap_.end()) {
return nullptr;

View File

@ -19,7 +19,7 @@ ShaderManager& ShaderManager::getInstance() {
* @param appName
* @return truefalse
*/
bool ShaderManager::init(Ptr<IShaderFactory> factory, const std::string& appName) {
bool ShaderManager::init(SharedPtr<IShaderFactory> 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<IShaderFactory> factory, const std::string& appName
*/
bool ShaderManager::init(const std::string& shaderDir,
const std::string& cacheDir,
Ptr<IShaderFactory> factory) {
SharedPtr<IShaderFactory> factory) {
if (initialized_) {
E2D_LOG_WARN("ShaderManager already initialized");
return true;
@ -112,7 +112,7 @@ void ShaderManager::shutdown() {
* @param fragPath
* @return Shader实例
*/
Ptr<IShader> ShaderManager::loadFromFiles(const std::string& name,
SharedPtr<IShader> ShaderManager::loadFromFiles(const std::string& name,
const std::string& vertPath,
const std::string& fragPath) {
if (!initialized_) {
@ -132,7 +132,7 @@ Ptr<IShader> ShaderManager::loadFromFiles(const std::string& name,
}
std::string sourceHash = ShaderCache::computeHash(result.vertSource, result.fragSource);
Ptr<IShader> shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource);
SharedPtr<IShader> shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource);
if (!shader) {
shader = factory_->createFromSource(name, result.vertSource, result.fragSource);
@ -181,7 +181,7 @@ Ptr<IShader> ShaderManager::loadFromFiles(const std::string& name,
* @param path Shader文件路径
* @return Shader实例
*/
Ptr<IShader> ShaderManager::loadFromCombinedFile(const std::string& path) {
SharedPtr<IShader> ShaderManager::loadFromCombinedFile(const std::string& path) {
if (!initialized_) {
E2D_LOG_ERROR("ShaderManager not initialized");
return nullptr;
@ -202,7 +202,7 @@ Ptr<IShader> ShaderManager::loadFromCombinedFile(const std::string& path) {
}
std::string sourceHash = ShaderCache::computeHash(result.vertSource, result.fragSource);
Ptr<IShader> shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource);
SharedPtr<IShader> shader = loadFromCache(name, sourceHash, result.vertSource, result.fragSource);
if (!shader) {
shader = factory_->createFromSource(name, result.vertSource, result.fragSource);
@ -250,7 +250,7 @@ Ptr<IShader> ShaderManager::loadFromCombinedFile(const std::string& path) {
* @param fragSource
* @return Shader实例
*/
Ptr<IShader> ShaderManager::loadFromSource(const std::string& name,
SharedPtr<IShader> ShaderManager::loadFromSource(const std::string& name,
const std::string& vertSource,
const std::string& fragSource) {
if (!initialized_) {
@ -263,7 +263,7 @@ Ptr<IShader> ShaderManager::loadFromSource(const std::string& name,
return it->second.shader;
}
Ptr<IShader> shader = factory_->createFromSource(name, vertSource, fragSource);
SharedPtr<IShader> 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<IShader> ShaderManager::loadFromSource(const std::string& name,
* @param name Shader名称
* @return Shader实例nullptr
*/
Ptr<IShader> ShaderManager::get(const std::string& name) const {
SharedPtr<IShader> 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<IShader> newShader = factory_->createFromSource(name, vertSource, fragSource);
SharedPtr<IShader> 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<IShader> ShaderManager::getBuiltin(const std::string& name) {
Ptr<IShader> shader = get(name);
SharedPtr<IShader> ShaderManager::getBuiltin(const std::string& name) {
SharedPtr<IShader> shader = get(name);
if (shader) {
return shader;
}
@ -487,7 +487,7 @@ bool ShaderManager::loadBuiltinShaders() {
* @param fragSource
* @return Shader实例
*/
Ptr<IShader> ShaderManager::loadFromCache(const std::string& name,
SharedPtr<IShader> ShaderManager::loadFromCache(const std::string& name,
const std::string& sourceHash,
const std::string& vertSource,
const std::string& fragSource) {
@ -499,12 +499,12 @@ Ptr<IShader> ShaderManager::loadFromCache(const std::string& name,
return nullptr;
}
Ptr<ShaderCacheEntry> entry = ShaderCache::getInstance().loadCache(name);
SharedPtr<ShaderCacheEntry> entry = ShaderCache::getInstance().loadCache(name);
if (!entry || entry->binary.empty()) {
return nullptr;
}
Ptr<IShader> shader = factory_->createFromBinary(name, entry->binary);
SharedPtr<IShader> shader = factory_->createFromBinary(name, entry->binary);
if (shader) {
E2D_LOG_DEBUG("Shader loaded from cache: {}", name);
}

View File

@ -9,8 +9,8 @@ namespace extra2d {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Water(const WaterParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("water");
SharedPtr<IShader> ShaderPreset::Water(const WaterParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("water");
if (!shader) {
E2D_LOG_ERROR("Failed to get water shader");
return nullptr;
@ -28,8 +28,8 @@ Ptr<IShader> ShaderPreset::Water(const WaterParams &params) {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Outline(const OutlineParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("outline");
SharedPtr<IShader> ShaderPreset::Outline(const OutlineParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("outline");
if (!shader) {
E2D_LOG_ERROR("Failed to get outline shader");
return nullptr;
@ -47,8 +47,8 @@ Ptr<IShader> ShaderPreset::Outline(const OutlineParams &params) {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Distortion(const DistortionParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("distortion");
SharedPtr<IShader> ShaderPreset::Distortion(const DistortionParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("distortion");
if (!shader) {
E2D_LOG_ERROR("Failed to get distortion shader");
return nullptr;
@ -65,8 +65,8 @@ Ptr<IShader> ShaderPreset::Distortion(const DistortionParams &params) {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Pixelate(const PixelateParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("pixelate");
SharedPtr<IShader> ShaderPreset::Pixelate(const PixelateParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("pixelate");
if (!shader) {
E2D_LOG_ERROR("Failed to get pixelate shader");
return nullptr;
@ -82,8 +82,8 @@ Ptr<IShader> ShaderPreset::Pixelate(const PixelateParams &params) {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Invert(const InvertParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("invert");
SharedPtr<IShader> ShaderPreset::Invert(const InvertParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("invert");
if (!shader) {
E2D_LOG_ERROR("Failed to get invert shader");
return nullptr;
@ -99,8 +99,8 @@ Ptr<IShader> ShaderPreset::Invert(const InvertParams &params) {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Grayscale(const GrayscaleParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("grayscale");
SharedPtr<IShader> ShaderPreset::Grayscale(const GrayscaleParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("grayscale");
if (!shader) {
E2D_LOG_ERROR("Failed to get grayscale shader");
return nullptr;
@ -116,8 +116,8 @@ Ptr<IShader> ShaderPreset::Grayscale(const GrayscaleParams &params) {
* @param params
* @return
*/
Ptr<IShader> ShaderPreset::Blur(const BlurParams &params) {
Ptr<IShader> shader = ShaderManager::getInstance().get("blur");
SharedPtr<IShader> ShaderPreset::Blur(const BlurParams &params) {
SharedPtr<IShader> shader = ShaderManager::getInstance().get("blur");
if (!shader) {
E2D_LOG_ERROR("Failed to get blur shader");
return nullptr;
@ -134,13 +134,13 @@ Ptr<IShader> ShaderPreset::Blur(const BlurParams &params) {
* @param outlineParams
* @return
*/
Ptr<IShader>
SharedPtr<IShader>
ShaderPreset::GrayscaleOutline(const GrayscaleParams &grayParams,
const OutlineParams &outlineParams) {
std::string shaderDir = ShaderManager::getInstance().getShaderDir();
std::string shaderPath = shaderDir + "effects/grayscale_outline.shader";
Ptr<IShader> shader =
SharedPtr<IShader> 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<IShader> ShaderPreset::PixelateInvert(const PixelateParams &pixParams,
SharedPtr<IShader> ShaderPreset::PixelateInvert(const PixelateParams &pixParams,
const InvertParams &invParams) {
std::string shaderDir = ShaderManager::getInstance().getShaderDir();
std::string shaderPath = shaderDir + "effects/pixelate_invert.shader";
Ptr<IShader> shader =
SharedPtr<IShader> shader =
ShaderManager::getInstance().loadFromCombinedFile(shaderPath);
if (!shader) {
E2D_LOG_ERROR("Failed to load pixelate_invert shader from: {}", shaderPath);

View File

@ -27,7 +27,7 @@ Node::~Node() { clearChildren(); }
*
*
*/
void Node::addChild(Ptr<Node> child) {
void Node::addChild(SharedPtr<Node> child) {
if (!child || child.get() == this) {
return;
}
@ -59,7 +59,7 @@ void Node::addChild(Ptr<Node> child) {
*
*
*/
void Node::addChildren(std::vector<Ptr<Node>> &&children) {
void Node::addChildren(std::vector<SharedPtr<Node>> &&children) {
// 预留空间,避免多次扩容
size_t newSize = children_.size() + children.size();
if (newSize > children_.capacity()) {
@ -102,7 +102,7 @@ void Node::addChildren(std::vector<Ptr<Node>> &&children) {
*
* 退
*/
void Node::removeChild(Ptr<Node> child) {
void Node::removeChild(SharedPtr<Node> child) {
if (!child)
return;
@ -146,7 +146,7 @@ void Node::detach() {
auto p = parent_.lock();
if (p) {
// 安全获取 shared_ptr避免在对象未由 shared_ptr 管理时崩溃
Ptr<Node> self;
SharedPtr<Node> self;
try {
self = shared_from_this();
} catch (const std::bad_weak_ptr &) {
@ -183,7 +183,7 @@ void Node::clearChildren() {
*
* 使O(1)
*/
Ptr<Node> Node::findChild(const std::string &name) const {
SharedPtr<Node> Node::findChild(const std::string &name) const {
// 使用哈希索引O(1) 查找
auto it = nameIndex_.find(name);
if (it != nameIndex_.end()) {
@ -199,7 +199,7 @@ Ptr<Node> Node::findChild(const std::string &name) const {
*
* 使O(1)
*/
Ptr<Node> Node::findChildByTag(int tag) const {
SharedPtr<Node> 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<Node> &a, const Ptr<Node> &b) {
[](const SharedPtr<Node> &a, const SharedPtr<Node> &b) {
return a->getZOrder() < b->getZOrder();
});
}

View File

@ -10,13 +10,13 @@ namespace extra2d {
*
*
*/
Scene::Scene() { defaultCamera_ = makePtr<Camera>(); }
Scene::Scene() { defaultCamera_ = makeShared<Camera>(); }
/**
* @brief
* @param camera
*/
void Scene::setCamera(Ptr<Camera> camera) { camera_ = camera; }
void Scene::setCamera(SharedPtr<Camera> camera) { camera_ = camera; }
/**
* @brief
@ -122,6 +122,6 @@ void Scene::collectRenderCommands(std::vector<RenderCommand> &commands,
* @brief
* @return
*/
Ptr<Scene> Scene::create() { return makePtr<Scene>(); }
SharedPtr<Scene> Scene::create() { return makeShared<Scene>(); }
} // namespace extra2d

View File

@ -16,14 +16,14 @@ namespace {
* @param worldPos
* @return nullptr
*/
Node *hitTestTopmost(const Ptr<Node> &node, const Vec2 &worldPos) {
Node *hitTestTopmost(const SharedPtr<Node> &node, const Vec2 &worldPos) {
if (!node || !node->isVisible()) {
return nullptr;
}
std::vector<Ptr<Node>> children = node->getChildren();
std::vector<SharedPtr<Node>> children = node->getChildren();
std::stable_sort(children.begin(), children.end(),
[](const Ptr<Node> &a, const Ptr<Node> &b) {
[](const SharedPtr<Node> &a, const SharedPtr<Node> &b) {
return a->getZOrder() < b->getZOrder();
});
@ -74,7 +74,7 @@ SceneManager &SceneManager::get() {
*
*
*/
void SceneManager::runWithScene(Ptr<Scene> scene) {
void SceneManager::runWithScene(SharedPtr<Scene> scene) {
if (!scene) {
return;
}
@ -95,7 +95,7 @@ void SceneManager::runWithScene(Ptr<Scene> scene) {
*
*
*/
void SceneManager::replaceScene(Ptr<Scene> scene) {
void SceneManager::replaceScene(SharedPtr<Scene> scene) {
if (!scene || isTransitioning_) {
return;
}
@ -121,7 +121,7 @@ void SceneManager::replaceScene(Ptr<Scene> scene) {
*
*
*/
void SceneManager::enterScene(Ptr<Scene> scene) {
void SceneManager::enterScene(SharedPtr<Scene> scene) {
if (!scene || isTransitioning_) {
return;
}
@ -139,7 +139,7 @@ void SceneManager::enterScene(Ptr<Scene> scene) {
*
*
*/
void SceneManager::pushScene(Ptr<Scene> scene) {
void SceneManager::pushScene(SharedPtr<Scene> scene) {
if (!scene || isTransitioning_) {
return;
}
@ -204,8 +204,8 @@ void SceneManager::popToScene(const std::string &name) {
return;
}
std::stack<Ptr<Scene>> tempStack;
Ptr<Scene> target = nullptr;
std::stack<SharedPtr<Scene>> tempStack;
SharedPtr<Scene> target = nullptr;
while (!sceneStack_.empty()) {
auto scene = sceneStack_.top();
@ -227,7 +227,7 @@ void SceneManager::popToScene(const std::string &name) {
* @brief
* @return nullptr
*/
Ptr<Scene> SceneManager::getCurrentScene() const {
SharedPtr<Scene> SceneManager::getCurrentScene() const {
if (sceneStack_.empty()) {
return nullptr;
}
@ -238,7 +238,7 @@ Ptr<Scene> SceneManager::getCurrentScene() const {
* @brief
* @return nullptr
*/
Ptr<Scene> SceneManager::getPreviousScene() const {
SharedPtr<Scene> SceneManager::getPreviousScene() const {
if (sceneStack_.size() < 2) {
return nullptr;
}
@ -252,13 +252,13 @@ Ptr<Scene> SceneManager::getPreviousScene() const {
* @brief
* @return nullptr
*/
Ptr<Scene> SceneManager::getRootScene() const {
SharedPtr<Scene> SceneManager::getRootScene() const {
if (sceneStack_.empty()) {
return nullptr;
}
auto tempStack = sceneStack_;
Ptr<Scene> root;
SharedPtr<Scene> root;
while (!tempStack.empty()) {
root = tempStack.top();
tempStack.pop();
@ -271,7 +271,7 @@ Ptr<Scene> SceneManager::getRootScene() const {
* @param name
* @return nullptr
*/
Ptr<Scene> SceneManager::getSceneByName(const std::string &name) const {
SharedPtr<Scene> 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<Node> root = scene.shared_from_this();
SharedPtr<Node> root = scene.shared_from_this();
Node *newHover = hitTestTopmost(root, worldPos);
if (newHover != hoverTarget_) {

View File

@ -18,7 +18,7 @@ ShapeNode::ShapeNode() = default;
* @brief
* @return
*/
Ptr<ShapeNode> ShapeNode::create() { return makePtr<ShapeNode>(); }
SharedPtr<ShapeNode> ShapeNode::create() { return makeShared<ShapeNode>(); }
/**
* @brief
@ -26,8 +26,8 @@ Ptr<ShapeNode> ShapeNode::create() { return makePtr<ShapeNode>(); }
* @param color
* @return
*/
Ptr<ShapeNode> ShapeNode::createPoint(const Vec2 &pos, const Color &color) {
auto node = makePtr<ShapeNode>();
SharedPtr<ShapeNode> ShapeNode::createPoint(const Vec2 &pos, const Color &color) {
auto node = makeShared<ShapeNode>();
node->shapeType_ = ShapeType::Point;
node->color_ = color;
node->points_ = {pos};
@ -42,9 +42,9 @@ Ptr<ShapeNode> ShapeNode::createPoint(const Vec2 &pos, const Color &color) {
* @param width 线
* @return 线
*/
Ptr<ShapeNode> ShapeNode::createLine(const Vec2 &start, const Vec2 &end,
SharedPtr<ShapeNode> ShapeNode::createLine(const Vec2 &start, const Vec2 &end,
const Color &color, float width) {
auto node = makePtr<ShapeNode>();
auto node = makeShared<ShapeNode>();
node->shapeType_ = ShapeType::Line;
node->color_ = color;
node->lineWidth_ = width;
@ -59,9 +59,9 @@ Ptr<ShapeNode> ShapeNode::createLine(const Vec2 &start, const Vec2 &end,
* @param width 线
* @return
*/
Ptr<ShapeNode> ShapeNode::createRect(const Rect &rect, const Color &color,
SharedPtr<ShapeNode> ShapeNode::createRect(const Rect &rect, const Color &color,
float width) {
auto node = makePtr<ShapeNode>();
auto node = makeShared<ShapeNode>();
node->shapeType_ = ShapeType::Rect;
node->color_ = color;
node->lineWidth_ = width;
@ -78,7 +78,7 @@ Ptr<ShapeNode> ShapeNode::createRect(const Rect &rect, const Color &color,
* @param color
* @return
*/
Ptr<ShapeNode> ShapeNode::createFilledRect(const Rect &rect,
SharedPtr<ShapeNode> ShapeNode::createFilledRect(const Rect &rect,
const Color &color) {
auto node = createRect(rect, color, 0);
node->filled_ = true;
@ -94,17 +94,16 @@ Ptr<ShapeNode> ShapeNode::createFilledRect(const Rect &rect,
* @param width 线
* @return
*/
Ptr<ShapeNode> ShapeNode::createCircle(const Vec2 &center, float radius,
SharedPtr<ShapeNode> ShapeNode::createCircle(const Vec2 &center, float radius,
const Color &color, int segments,
float width) {
auto node = makePtr<ShapeNode>();
auto node = makeShared<ShapeNode>();
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> ShapeNode::createCircle(const Vec2 &center, float radius,
* @param segments
* @return
*/
Ptr<ShapeNode> ShapeNode::createFilledCircle(const Vec2 &center, float radius,
SharedPtr<ShapeNode> ShapeNode::createFilledCircle(const Vec2 &center, float radius,
const Color &color, int segments) {
auto node = createCircle(center, radius, color, segments, 0);
node->filled_ = true;
@ -133,10 +132,10 @@ Ptr<ShapeNode> ShapeNode::createFilledCircle(const Vec2 &center, float radius,
* @param width 线
* @return
*/
Ptr<ShapeNode> ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2,
SharedPtr<ShapeNode> ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2,
const Vec2 &p3, const Color &color,
float width) {
auto node = makePtr<ShapeNode>();
auto node = makeShared<ShapeNode>();
node->shapeType_ = ShapeType::Triangle;
node->color_ = color;
node->lineWidth_ = width;
@ -153,7 +152,7 @@ Ptr<ShapeNode> ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2,
* @param color
* @return
*/
Ptr<ShapeNode> ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2,
SharedPtr<ShapeNode> 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> ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2,
* @param width 线
* @return
*/
Ptr<ShapeNode> ShapeNode::createPolygon(const std::vector<Vec2> &points,
SharedPtr<ShapeNode> ShapeNode::createPolygon(const std::vector<Vec2> &points,
const Color &color, float width) {
auto node = makePtr<ShapeNode>();
auto node = makeShared<ShapeNode>();
node->shapeType_ = ShapeType::Polygon;
node->color_ = color;
node->lineWidth_ = width;
@ -185,7 +184,7 @@ Ptr<ShapeNode> ShapeNode::createPolygon(const std::vector<Vec2> &points,
* @param color
* @return
*/
Ptr<ShapeNode> ShapeNode::createFilledPolygon(const std::vector<Vec2> &points,
SharedPtr<ShapeNode> ShapeNode::createFilledPolygon(const std::vector<Vec2> &points,
const Color &color) {
auto node = createPolygon(points, color, 0);
node->filled_ = true;
@ -444,4 +443,4 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
commands.push_back(std::move(cmd));
}
} // namespace extra2d
}

View File

@ -68,15 +68,15 @@ void Sprite::setFlipY(bool flip) { flipY_ = flip; }
* @brief
* @return
*/
Ptr<Sprite> Sprite::create() { return makePtr<Sprite>(); }
SharedPtr<Sprite> Sprite::create() { return makeShared<Sprite>(); }
/**
* @brief
* @param texture 使
* @return
*/
Ptr<Sprite> Sprite::create(Ptr<Texture> texture) {
return makePtr<Sprite>(texture);
SharedPtr<Sprite> Sprite::create(Ptr<Texture> texture) {
return makeShared<Sprite>(texture);
}
/**
@ -85,8 +85,8 @@ Ptr<Sprite> Sprite::create(Ptr<Texture> texture) {
* @param rect
* @return
*/
Ptr<Sprite> Sprite::create(Ptr<Texture> texture, const Rect &rect) {
auto sprite = makePtr<Sprite>(texture);
SharedPtr<Sprite> Sprite::create(Ptr<Texture> texture, const Rect &rect) {
auto sprite = makeShared<Sprite>(texture);
sprite->setTextureRect(rect);
return sprite;
}

View File

@ -28,15 +28,15 @@ void SceneService::update(float deltaTime) {
}
}
void SceneService::runWithScene(Ptr<Scene> scene) {
void SceneService::runWithScene(SharedPtr<Scene> scene) {
manager_.runWithScene(scene);
}
void SceneService::replaceScene(Ptr<Scene> scene) {
void SceneService::replaceScene(SharedPtr<Scene> scene) {
manager_.replaceScene(scene);
}
void SceneService::pushScene(Ptr<Scene> scene) {
void SceneService::pushScene(SharedPtr<Scene> scene) {
manager_.pushScene(scene);
}
@ -52,19 +52,19 @@ void SceneService::popToScene(const std::string& name) {
manager_.popToScene(name);
}
Ptr<Scene> SceneService::getCurrentScene() const {
SharedPtr<Scene> SceneService::getCurrentScene() const {
return manager_.getCurrentScene();
}
Ptr<Scene> SceneService::getPreviousScene() const {
SharedPtr<Scene> SceneService::getPreviousScene() const {
return manager_.getPreviousScene();
}
Ptr<Scene> SceneService::getRootScene() const {
SharedPtr<Scene> SceneService::getRootScene() const {
return manager_.getRootScene();
}
Ptr<Scene> SceneService::getSceneByName(const std::string& name) const {
SharedPtr<Scene> 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> scene) {
void SceneService::enterScene(SharedPtr<Scene> scene) {
manager_.enterScene(scene);
}

View File

@ -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
-- ==============================================
-- 加载构建目标
-- ==============================================