refactor: 将 makePtr 和 makeUnique 重命名为 shared 和 unique

统一智能指针创建函数的命名风格,使用更直观的 shared 和 unique 替代 makePtr 和 makeUnique。
修改涉及核心类型定义、场景系统、资源管理、图形渲染等多个模块,确保代码风格一致性。
同时更新了相关文档和示例代码中的调用方式。
This commit is contained in:
ChestnutYueyue 2026-02-23 22:56:31 +08:00
parent 6fbebafef3
commit c61edbb9dd
22 changed files with 275 additions and 235 deletions

View File

@ -17,13 +17,13 @@ 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) {
template <typename T, typename... Args> inline Ptr<T> shared(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
/// 创建 unique_ptr 的便捷函数
template <typename T, typename... Args>
inline UniquePtr<T> makeUnique(Args &&...args) {
inline UniquePtr<T> unique(Args &&...args) {
return std::make_unique<T>(std::forward<Args>(args)...);
}

View File

@ -34,7 +34,7 @@ bool Application::init(const AppConfig &config) {
config_ = config;
window_ = makeUnique<Window>();
window_ = unique<Window>();
WindowConfig winConfig;
winConfig.title = config.title;
winConfig.width = config.width;
@ -47,15 +47,15 @@ bool Application::init(const AppConfig &config) {
return false;
}
renderer_ = makeUnique<Renderer>();
renderer_ = unique<Renderer>();
if (!renderer_->init(window_.get())) {
E2D_LOG_ERROR("Failed to initialize renderer");
window_->destroy();
return false;
}
eventQueue_ = makeUnique<EventQueue>();
eventDispatcher_ = makeUnique<EventDispatcher>();
eventQueue_ = unique<EventQueue>();
eventDispatcher_ = unique<EventDispatcher>();
AudioEngine::getInstance().initialize();
@ -106,9 +106,7 @@ void Application::run() {
}
}
void Application::quit() {
running_ = false;
}
void Application::quit() { running_ = false; }
void Application::pause() {
if (!paused_) {
@ -173,9 +171,9 @@ void Application::render() {
}
renderer_->beginFrame(Color::Black);
// 渲染内容可以在这里添加
renderer_->endFrame();
window_->swapBuffers();
}

View File

@ -210,11 +210,11 @@ glm::mat4 GLRenderer::getCurrentTransform() const {
Ptr<Texture> GLRenderer::createTexture(int width, int height,
const uint8_t *pixels, int channels) {
return makePtr<GLTexture>(width, height, pixels, channels);
return shared<GLTexture>(width, height, pixels, channels);
}
Ptr<Texture> GLRenderer::loadTexture(const std::string &filepath) {
return makePtr<GLTexture>(filepath);
return shared<GLTexture>(filepath);
}
void GLRenderer::beginSpriteBatch() { spriteBatch_.begin(viewProjection_); }
@ -430,7 +430,7 @@ void GLRenderer::fillPolygon(const std::vector<Vec2> &points,
Ptr<FontAtlas> GLRenderer::createFontAtlas(const std::string &filepath,
int fontSize, bool useSDF) {
return makePtr<GLFontAtlas>(filepath, fontSize, useSDF);
return shared<GLFontAtlas>(filepath, fontSize, useSDF);
}
void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
@ -446,7 +446,7 @@ void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
// 收集所有字符数据用于批处理
std::vector<GLSpriteBatch::SpriteData> sprites;
sprites.reserve(text.size()); // 预分配空间
sprites.reserve(text.size()); // 预分配空间
for (char32_t codepoint : utf8ToUtf32(text)) {
if (codepoint == '\n') {
@ -477,7 +477,7 @@ void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
data.rotation = 0.0f;
data.anchor = glm::vec2(0.0f, 0.0f);
data.isSDF = font.isSDF();
sprites.push_back(data);
}
}

View File

@ -1,6 +1,7 @@
#include <extra2d/graphics/opengl/gl_texture.h>
#include <extra2d/graphics/gpu_context.h>
#include <extra2d/graphics/opengl/gl_texture.h>
#include <extra2d/graphics/vram_manager.h>
#define STB_IMAGE_IMPLEMENTATION
#include <cstring>
#include <extra2d/utils/logger.h>
@ -455,7 +456,7 @@ Ptr<Texture> GLTexture::create(int width, int height, PixelFormat format) {
channels = 4;
break;
}
return makePtr<GLTexture>(width, height, nullptr, channels);
return shared<GLTexture>(width, height, nullptr, channels);
}
} // namespace extra2d

View File

@ -1,7 +1,8 @@
#include <extra2d/graphics/texture_atlas.h>
#include <extra2d/utils/logger.h>
#include <algorithm>
#include <cstring>
#include <extra2d/graphics/texture_atlas.h>
#include <extra2d/utils/logger.h>
namespace extra2d {
@ -13,124 +14,134 @@ TextureAtlasPage::TextureAtlasPage(int width, int height)
: width_(width), height_(height), isFull_(false), usedArea_(0) {
// 创建空白纹理
std::vector<uint8_t> emptyData(width * height * 4, 0);
texture_ = makePtr<GLTexture>(width, height, emptyData.data(), 4);
texture_ = shared<GLTexture>(width, height, emptyData.data(), 4);
// 初始化矩形打包根节点
root_ = std::make_unique<PackNode>(0, 0, width, height);
E2D_LOG_INFO("Created texture atlas page: {}x{}", width, height);
}
TextureAtlasPage::~TextureAtlasPage() = default;
bool TextureAtlasPage::tryAddTexture(const std::string& name, int texWidth, int texHeight,
const uint8_t* pixels, Rect& outUvRect) {
bool TextureAtlasPage::tryAddTexture(const std::string &name, int texWidth,
int texHeight, const uint8_t *pixels,
Rect &outUvRect) {
if (isFull_) {
return false;
}
// 添加边距
int paddedWidth = texWidth + 2 * PADDING;
int paddedHeight = texHeight + 2 * PADDING;
// 如果纹理太大,无法放入
if (paddedWidth > width_ || paddedHeight > height_) {
return false;
}
// 尝试插入
PackNode* node = insert(root_.get(), paddedWidth, paddedHeight);
PackNode *node = insert(root_.get(), paddedWidth, paddedHeight);
if (node == nullptr) {
// 无法放入,标记为满
isFull_ = true;
return false;
}
// 写入像素数据(跳过边距区域)
writePixels(node->x + PADDING, node->y + PADDING, texWidth, texHeight, pixels);
writePixels(node->x + PADDING, node->y + PADDING, texWidth, texHeight,
pixels);
// 创建条目
AtlasEntry entry;
entry.name = name;
entry.originalSize = Vec2(static_cast<float>(texWidth), static_cast<float>(texHeight));
entry.originalSize =
Vec2(static_cast<float>(texWidth), static_cast<float>(texHeight));
entry.padding = PADDING;
// 计算 UV 坐标(考虑边距)
float u1 = static_cast<float>(node->x + PADDING) / width_;
float v1 = static_cast<float>(node->y + PADDING) / height_;
float u2 = static_cast<float>(node->x + PADDING + texWidth) / width_;
float v2 = static_cast<float>(node->y + PADDING + texHeight) / height_;
entry.uvRect = Rect(u1, v1, u2 - u1, v2 - v1);
outUvRect = entry.uvRect;
entries_[name] = std::move(entry);
usedArea_ += paddedWidth * paddedHeight;
E2D_LOG_DEBUG("Added texture '{}' to atlas: {}x{} at ({}, {})",
name, texWidth, texHeight, node->x, node->y);
E2D_LOG_DEBUG("Added texture '{}' to atlas: {}x{} at ({}, {})", name,
texWidth, texHeight, node->x, node->y);
return true;
}
TextureAtlasPage::PackNode* TextureAtlasPage::insert(PackNode* node, int width, int height) {
TextureAtlasPage::PackNode *TextureAtlasPage::insert(PackNode *node, int width,
int height) {
if (node == nullptr) {
return nullptr;
}
// 如果节点已被使用,尝试子节点
if (node->used) {
PackNode* result = insert(node->left.get(), width, height);
PackNode *result = insert(node->left.get(), width, height);
if (result != nullptr) {
return result;
}
return insert(node->right.get(), width, height);
}
// 检查是否适合
if (width > node->width || height > node->height) {
return nullptr;
}
// 如果刚好合适,使用此节点
if (width == node->width && height == node->height) {
node->used = true;
return node;
}
// 需要分割节点
int dw = node->width - width;
int dh = node->height - height;
if (dw > dh) {
// 水平分割
node->left = std::make_unique<PackNode>(node->x, node->y, width, node->height);
node->right = std::make_unique<PackNode>(node->x + width, node->y, dw, node->height);
node->left =
std::make_unique<PackNode>(node->x, node->y, width, node->height);
node->right =
std::make_unique<PackNode>(node->x + width, node->y, dw, node->height);
} else {
// 垂直分割
node->left = std::make_unique<PackNode>(node->x, node->y, node->width, height);
node->right = std::make_unique<PackNode>(node->x, node->y + height, node->width, dh);
node->left =
std::make_unique<PackNode>(node->x, node->y, node->width, height);
node->right =
std::make_unique<PackNode>(node->x, node->y + height, node->width, dh);
}
// 递归插入到左子节点
return insert(node->left.get(), width, height);
}
void TextureAtlasPage::writePixels(int x, int y, int w, int h, const uint8_t* pixels) {
void TextureAtlasPage::writePixels(int x, int y, int w, int h,
const uint8_t *pixels) {
if (texture_ == nullptr || pixels == nullptr) {
return;
}
// 使用 glTexSubImage2D 更新纹理数据
GLuint texID = static_cast<GLuint>(
reinterpret_cast<uintptr_t>(texture_->getNativeHandle()));
glBindTexture(GL_TEXTURE_2D, texID);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE,
pixels);
glBindTexture(GL_TEXTURE_2D, 0);
}
const AtlasEntry* TextureAtlasPage::getEntry(const std::string& name) const {
const AtlasEntry *TextureAtlasPage::getEntry(const std::string &name) const {
auto it = entries_.find(name);
if (it != entries_.end()) {
return &it->second;
@ -147,11 +158,8 @@ float TextureAtlasPage::getUsageRatio() const {
// ============================================================================
TextureAtlas::TextureAtlas()
: pageSize_(TextureAtlasPage::DEFAULT_SIZE),
sizeThreshold_(256),
enabled_(true),
initialized_(false) {
}
: pageSize_(TextureAtlasPage::DEFAULT_SIZE), sizeThreshold_(256),
enabled_(true), initialized_(false) {}
TextureAtlas::~TextureAtlas() = default;
@ -161,33 +169,33 @@ void TextureAtlas::init(int pageSize) {
E2D_LOG_INFO("TextureAtlas initialized with page size: {}", pageSize);
}
bool TextureAtlas::addTexture(const std::string& name, int width, int height,
const uint8_t* pixels) {
bool TextureAtlas::addTexture(const std::string &name, int width, int height,
const uint8_t *pixels) {
if (!enabled_ || !initialized_) {
return false;
}
// 检查是否已存在
if (contains(name)) {
return true;
}
// 检查纹理大小
if (width > sizeThreshold_ || height > sizeThreshold_) {
E2D_LOG_DEBUG("Texture '{}' too large for atlas ({}x{} > {}), skipping",
E2D_LOG_DEBUG("Texture '{}' too large for atlas ({}x{} > {}), skipping",
name, width, height, sizeThreshold_);
return false;
}
// 尝试添加到现有页面
Rect uvRect;
for (auto& page : pages_) {
for (auto &page : pages_) {
if (page->tryAddTexture(name, width, height, pixels, uvRect)) {
entryToPage_[name] = page.get();
return true;
}
}
// 创建新页面
auto newPage = std::make_unique<TextureAtlasPage>(pageSize_, pageSize_);
if (newPage->tryAddTexture(name, width, height, pixels, uvRect)) {
@ -195,16 +203,16 @@ bool TextureAtlas::addTexture(const std::string& name, int width, int height,
pages_.push_back(std::move(newPage));
return true;
}
E2D_LOG_WARN("Failed to add texture '{}' to atlas", name);
return false;
}
bool TextureAtlas::contains(const std::string& name) const {
bool TextureAtlas::contains(const std::string &name) const {
return entryToPage_.find(name) != entryToPage_.end();
}
const Texture* TextureAtlas::getAtlasTexture(const std::string& name) const {
const Texture *TextureAtlas::getAtlasTexture(const std::string &name) const {
auto it = entryToPage_.find(name);
if (it != entryToPage_.end()) {
return it->second->getTexture().get();
@ -212,10 +220,10 @@ const Texture* TextureAtlas::getAtlasTexture(const std::string& name) const {
return nullptr;
}
Rect TextureAtlas::getUVRect(const std::string& name) const {
Rect TextureAtlas::getUVRect(const std::string &name) const {
auto it = entryToPage_.find(name);
if (it != entryToPage_.end()) {
const AtlasEntry* entry = it->second->getEntry(name);
const AtlasEntry *entry = it->second->getEntry(name);
if (entry != nullptr) {
return entry->uvRect;
}
@ -223,10 +231,10 @@ Rect TextureAtlas::getUVRect(const std::string& name) const {
return Rect(0, 0, 1, 1); // 默认 UV
}
Vec2 TextureAtlas::getOriginalSize(const std::string& name) const {
Vec2 TextureAtlas::getOriginalSize(const std::string &name) const {
auto it = entryToPage_.find(name);
if (it != entryToPage_.end()) {
const AtlasEntry* entry = it->second->getEntry(name);
const AtlasEntry *entry = it->second->getEntry(name);
if (entry != nullptr) {
return entry->originalSize;
}
@ -238,9 +246,9 @@ float TextureAtlas::getTotalUsageRatio() const {
if (pages_.empty()) {
return 0.0f;
}
float total = 0.0f;
for (const auto& page : pages_) {
for (const auto &page : pages_) {
total += page->getUsageRatio();
}
return total / pages_.size();
@ -256,7 +264,7 @@ void TextureAtlas::clear() {
// TextureAtlasManager 单例实现
// ============================================================================
TextureAtlasManager& TextureAtlasManager::getInstance() {
TextureAtlasManager &TextureAtlasManager::getInstance() {
static TextureAtlasManager instance;
return instance;
}

View File

@ -41,7 +41,8 @@ static std::string getExecutableDirectory() {
}
#endif
// 解析资源路径(优先尝试 romfs:/ 前缀,然后 sdmc:/,最后尝试相对于可执行文件的路径)
// 解析资源路径(优先尝试 romfs:/ 前缀,然后
// sdmc:/,最后尝试相对于可执行文件的路径)
static std::string resolveResourcePath(const std::string &filepath) {
// 如果已经是 romfs 或 sdmc 路径,直接返回
if (isRomfsPath(filepath) || filepath.find("sdmc:/") == 0) {
@ -81,9 +82,7 @@ static std::string resolveResourcePath(const std::string &filepath) {
ResourceManager::ResourceManager() = default;
ResourceManager::~ResourceManager() {
shutdownAsyncLoader();
}
ResourceManager::~ResourceManager() { shutdownAsyncLoader(); }
ResourceManager &ResourceManager::getInstance() {
static ResourceManager instance;
@ -98,9 +97,10 @@ void ResourceManager::initAsyncLoader() {
if (asyncRunning_) {
return;
}
asyncRunning_ = true;
asyncThread_ = std::make_unique<std::thread>(&ResourceManager::asyncLoadLoop, this);
asyncThread_ =
std::make_unique<std::thread>(&ResourceManager::asyncLoadLoop, this);
E2D_LOG_INFO("ResourceManager: async loader initialized");
}
@ -108,14 +108,14 @@ void ResourceManager::shutdownAsyncLoader() {
if (!asyncRunning_) {
return;
}
asyncRunning_ = false;
asyncCondition_.notify_all();
if (asyncThread_ && asyncThread_->joinable()) {
asyncThread_->join();
}
E2D_LOG_INFO("ResourceManager: async loader shutdown");
}
@ -132,34 +132,35 @@ bool ResourceManager::hasPendingAsyncLoads() const {
void ResourceManager::asyncLoadLoop() {
while (asyncRunning_) {
AsyncLoadTask task;
{
std::unique_lock<std::mutex> lock(asyncQueueMutex_);
asyncCondition_.wait(lock, [this] { return !asyncTaskQueue_.empty() || !asyncRunning_; });
asyncCondition_.wait(
lock, [this] { return !asyncTaskQueue_.empty() || !asyncRunning_; });
if (!asyncRunning_) {
break;
}
if (asyncTaskQueue_.empty()) {
continue;
}
task = std::move(asyncTaskQueue_.front());
asyncTaskQueue_.pop();
}
// 执行加载
auto texture = loadTextureInternal(task.filepath, task.format);
// 回调
if (task.callback) {
task.callback(texture);
}
// 设置 promise
task.promise.set_value(texture);
pendingAsyncLoads_--;
}
}
@ -172,25 +173,30 @@ Ptr<Texture> ResourceManager::loadTexture(const std::string &filepath) {
return loadTexture(filepath, false, TextureFormat::Auto);
}
Ptr<Texture> ResourceManager::loadTexture(const std::string &filepath, bool async) {
Ptr<Texture> ResourceManager::loadTexture(const std::string &filepath,
bool async) {
return loadTexture(filepath, async, TextureFormat::Auto);
}
Ptr<Texture> ResourceManager::loadTexture(const std::string &filepath, bool async, TextureFormat format) {
Ptr<Texture> ResourceManager::loadTexture(const std::string &filepath,
bool async, TextureFormat format) {
if (async) {
// 异步加载:返回空指针,实际纹理通过回调获取
loadTextureAsync(filepath, format, nullptr);
return nullptr;
}
return loadTextureInternal(filepath, format);
}
void ResourceManager::loadTextureAsync(const std::string &filepath, TextureLoadCallback callback) {
void ResourceManager::loadTextureAsync(const std::string &filepath,
TextureLoadCallback callback) {
loadTextureAsync(filepath, TextureFormat::Auto, callback);
}
void ResourceManager::loadTextureAsync(const std::string &filepath, TextureFormat format, TextureLoadCallback callback) {
void ResourceManager::loadTextureAsync(const std::string &filepath,
TextureFormat format,
TextureLoadCallback callback) {
// 确保异步加载系统已启动
if (!asyncRunning_) {
initAsyncLoader();
@ -229,7 +235,8 @@ void ResourceManager::loadTextureAsync(const std::string &filepath, TextureForma
E2D_LOG_DEBUG("ResourceManager: queued async texture load: {}", filepath);
}
Ptr<Texture> ResourceManager::loadTextureInternal(const std::string &filepath, TextureFormat format) {
Ptr<Texture> ResourceManager::loadTextureInternal(const std::string &filepath,
TextureFormat format) {
std::lock_guard<std::mutex> lock(textureMutex_);
// 检查缓存
@ -255,7 +262,7 @@ Ptr<Texture> ResourceManager::loadTextureInternal(const std::string &filepath, T
// 创建新纹理
try {
auto texture = makePtr<GLTexture>(fullPath);
auto texture = shared<GLTexture>(fullPath);
if (!texture->isValid()) {
E2D_LOG_ERROR("ResourceManager: failed to load texture: {}", filepath);
return nullptr;
@ -273,7 +280,8 @@ Ptr<Texture> ResourceManager::loadTextureInternal(const std::string &filepath, T
evictTexturesIfNeeded();
// 计算纹理大小
size_t textureSize = calculateTextureSize(texture->getWidth(), texture->getHeight(), texture->getFormat());
size_t textureSize = calculateTextureSize(
texture->getWidth(), texture->getHeight(), texture->getFormat());
// 分配LRU节点
uint32_t lruIndex = allocateLRUNode(filepath);
@ -292,7 +300,8 @@ Ptr<Texture> ResourceManager::loadTextureInternal(const std::string &filepath, T
// 添加到LRU链表头部
moveToFront(lruIndex);
E2D_LOG_DEBUG("ResourceManager: loaded texture: {} ({} KB)", filepath, textureSize / 1024);
E2D_LOG_DEBUG("ResourceManager: loaded texture: {} ({} KB)", filepath,
textureSize / 1024);
return texture;
} catch (...) {
E2D_LOG_ERROR("ResourceManager: exception loading texture: {}", filepath);
@ -304,24 +313,26 @@ TextureFormat ResourceManager::selectBestFormat(TextureFormat requested) const {
if (requested != TextureFormat::Auto) {
return requested;
}
// 自动选择最佳格式
// 检查支持的扩展
// 这里简化处理,实际应该查询 OpenGL 扩展
// 桌面平台优先 DXT
// 移动平台优先 ETC2 或 ASTC
// 默认返回 RGBA8
return TextureFormat::RGBA8;
}
std::vector<uint8_t> ResourceManager::compressTexture(const uint8_t* data, int width, int height,
int channels, TextureFormat format) {
std::vector<uint8_t> ResourceManager::compressTexture(const uint8_t *data,
int width, int height,
int channels,
TextureFormat format) {
// 纹理压缩实现
// 这里需要根据格式使用相应的压缩库
// 如squish (DXT), etcpack (ETC2), astc-encoder (ASTC)
// 目前返回原始数据
std::vector<uint8_t> result(data, data + width * height * channels);
return result;
@ -383,9 +394,9 @@ Ptr<Texture> ResourceManager::getTexture(const std::string &key) const {
auto it = textureCache_.find(key);
if (it != textureCache_.end()) {
const_cast<ResourceManager*>(this)->touchTexture(key);
const_cast<ResourceManager*>(this)->textureHitCount_++;
const_cast<uint32_t&>(it->second.accessCount)++;
const_cast<ResourceManager *>(this)->touchTexture(key);
const_cast<ResourceManager *>(this)->textureHitCount_++;
const_cast<uint32_t &>(it->second.accessCount)++;
return it->second.texture;
}
return nullptr;
@ -402,8 +413,9 @@ void ResourceManager::unloadTexture(const std::string &key) {
auto it = textureCache_.find(key);
if (it != textureCache_.end()) {
// 从LRU链表中移除
auto nodeIt = std::find_if(lruNodes_.begin(), lruNodes_.end(),
[&key](const LRUNode &node) { return node.valid && node.key == key; });
auto nodeIt = std::find_if(
lruNodes_.begin(), lruNodes_.end(),
[&key](const LRUNode &node) { return node.valid && node.key == key; });
if (nodeIt != lruNodes_.end()) {
removeFromList(static_cast<uint32_t>(nodeIt - lruNodes_.begin()) + 1);
freeLRUNode(static_cast<uint32_t>(nodeIt - lruNodes_.begin()) + 1);
@ -453,7 +465,7 @@ Ptr<FontAtlas> ResourceManager::loadFont(const std::string &filepath,
// 创建新字体图集
try {
auto font = makePtr<GLFontAtlas>(fullPath, fontSize, useSDF);
auto font = shared<GLFontAtlas>(fullPath, fontSize, useSDF);
if (!font->getTexture() || !font->getTexture()->isValid()) {
E2D_LOG_ERROR("ResourceManager: failed to load font: {}", filepath);
return nullptr;
@ -648,7 +660,8 @@ size_t ResourceManager::getTextureCacheSize() const {
// LRU 缓存管理
// ============================================================================
void ResourceManager::setTextureCache(size_t maxCacheSize, size_t maxTextureCount,
void ResourceManager::setTextureCache(size_t maxCacheSize,
size_t maxTextureCount,
float unloadInterval) {
std::lock_guard<std::mutex> lock(textureMutex_);
maxCacheSize_ = maxCacheSize;
@ -694,7 +707,8 @@ void ResourceManager::update(float dt) {
size_t targetSize = static_cast<size_t>(maxCacheSize_ * 0.5f);
while (totalTextureSize_ > targetSize && lruTail_ != 0) {
std::string key = evictLRU();
if (key.empty()) break;
if (key.empty())
break;
auto it = textureCache_.find(key);
if (it != textureCache_.end()) {
@ -703,7 +717,8 @@ void ResourceManager::update(float dt) {
E2D_LOG_DEBUG("ResourceManager: auto-evicted texture: {}", key);
}
}
E2D_LOG_INFO("ResourceManager: texture cache trimmed to {} MB", totalTextureSize_ / (1024 * 1024));
E2D_LOG_INFO("ResourceManager: texture cache trimmed to {} MB",
totalTextureSize_ / (1024 * 1024));
}
}
}
@ -733,7 +748,8 @@ uint32_t ResourceManager::allocateLRUNode(const std::string &key) {
}
void ResourceManager::freeLRUNode(uint32_t index) {
if (index == 0 || index > lruNodes_.size()) return;
if (index == 0 || index > lruNodes_.size())
return;
LRUNode &node = lruNodes_[index - 1];
node.valid = false;
@ -744,7 +760,8 @@ void ResourceManager::freeLRUNode(uint32_t index) {
}
void ResourceManager::moveToFront(uint32_t index) {
if (index == 0 || index > lruNodes_.size() || index == lruHead_) return;
if (index == 0 || index > lruNodes_.size() || index == lruHead_)
return;
removeFromList(index);
@ -763,7 +780,8 @@ void ResourceManager::moveToFront(uint32_t index) {
}
void ResourceManager::removeFromList(uint32_t index) {
if (index == 0 || index > lruNodes_.size()) return;
if (index == 0 || index > lruNodes_.size())
return;
LRUNode &node = lruNodes_[index - 1];
@ -781,7 +799,8 @@ void ResourceManager::removeFromList(uint32_t index) {
}
std::string ResourceManager::evictLRU() {
if (lruTail_ == 0) return "";
if (lruTail_ == 0)
return "";
uint32_t index = lruTail_;
std::string key = lruNodes_[index - 1].key;
@ -794,8 +813,9 @@ std::string ResourceManager::evictLRU() {
void ResourceManager::touchTexture(const std::string &key) {
// 查找对应的LRU节点
auto nodeIt = std::find_if(lruNodes_.begin(), lruNodes_.end(),
[&key](const LRUNode &node) { return node.valid && node.key == key; });
auto nodeIt = std::find_if(
lruNodes_.begin(), lruNodes_.end(),
[&key](const LRUNode &node) { return node.valid && node.key == key; });
if (nodeIt != lruNodes_.end()) {
uint32_t index = static_cast<uint32_t>(nodeIt - lruNodes_.begin()) + 1;
moveToFront(index);
@ -813,7 +833,8 @@ void ResourceManager::evictTexturesIfNeeded() {
textureCache_.size() >= maxTextureCount_) &&
lruTail_ != 0) {
std::string key = evictLRU();
if (key.empty()) break;
if (key.empty())
break;
auto it = textureCache_.find(key);
if (it != textureCache_.end()) {
@ -824,24 +845,25 @@ void ResourceManager::evictTexturesIfNeeded() {
}
}
size_t ResourceManager::calculateTextureSize(int width, int height, PixelFormat format) const {
size_t ResourceManager::calculateTextureSize(int width, int height,
PixelFormat format) const {
int bytesPerPixel = 4;
switch (format) {
case PixelFormat::R8:
bytesPerPixel = 1;
break;
case PixelFormat::RG8:
bytesPerPixel = 2;
break;
case PixelFormat::RGB8:
bytesPerPixel = 3;
break;
case PixelFormat::RGBA8:
bytesPerPixel = 4;
break;
default:
bytesPerPixel = 4;
break;
case PixelFormat::R8:
bytesPerPixel = 1;
break;
case PixelFormat::RG8:
bytesPerPixel = 2;
break;
case PixelFormat::RGB8:
bytesPerPixel = 3;
break;
case PixelFormat::RGBA8:
bytesPerPixel = 4;
break;
default:
bytesPerPixel = 4;
break;
}
return static_cast<size_t>(width * height * bytesPerPixel);
}
@ -864,7 +886,8 @@ std::string ResourceManager::loadTextFile(const std::string &filepath) {
return loadTextFile(filepath, "UTF-8");
}
std::string ResourceManager::loadTextFile(const std::string &filepath, const std::string &encoding) {
std::string ResourceManager::loadTextFile(const std::string &filepath,
const std::string &encoding) {
(void)encoding; // 目前只支持 UTF-8
std::lock_guard<std::mutex> lock(textFileMutex_);
@ -888,13 +911,15 @@ std::string ResourceManager::loadTextFile(const std::string &filepath, const std
#ifdef _WIN32
errno_t err = fopen_s(&file, resolvedPath.c_str(), "rb");
if (err != 0 || !file) {
E2D_LOG_ERROR("ResourceManager: failed to open text file: {}", resolvedPath);
E2D_LOG_ERROR("ResourceManager: failed to open text file: {}",
resolvedPath);
return "";
}
#else
file = fopen(resolvedPath.c_str(), "rb");
if (!file) {
E2D_LOG_ERROR("ResourceManager: failed to open text file: {}", resolvedPath);
E2D_LOG_ERROR("ResourceManager: failed to open text file: {}",
resolvedPath);
return "";
}
#endif
@ -917,13 +942,15 @@ std::string ResourceManager::loadTextFile(const std::string &filepath, const std
fclose(file);
if (readSize != static_cast<size_t>(fileSize)) {
E2D_LOG_ERROR("ResourceManager: failed to read text file: {}", resolvedPath);
E2D_LOG_ERROR("ResourceManager: failed to read text file: {}",
resolvedPath);
return "";
}
// 缓存内容
textFileCache_[filepath] = content;
E2D_LOG_DEBUG("ResourceManager: loaded text file: {} ({} bytes)", filepath, content.size());
E2D_LOG_DEBUG("ResourceManager: loaded text file: {} ({} bytes)", filepath,
content.size());
return content;
}
@ -989,13 +1016,15 @@ std::string ResourceManager::loadJsonFile(const std::string &filepath) {
#ifdef _WIN32
errno_t err = fopen_s(&file, resolvedPath.c_str(), "rb");
if (err != 0 || !file) {
E2D_LOG_ERROR("ResourceManager: failed to open JSON file: {}", resolvedPath);
E2D_LOG_ERROR("ResourceManager: failed to open JSON file: {}",
resolvedPath);
return "";
}
#else
file = fopen(resolvedPath.c_str(), "rb");
if (!file) {
E2D_LOG_ERROR("ResourceManager: failed to open JSON file: {}", resolvedPath);
E2D_LOG_ERROR("ResourceManager: failed to open JSON file: {}",
resolvedPath);
return "";
}
#endif
@ -1018,7 +1047,8 @@ std::string ResourceManager::loadJsonFile(const std::string &filepath) {
fclose(file);
if (readSize != static_cast<size_t>(fileSize)) {
E2D_LOG_ERROR("ResourceManager: failed to read JSON file: {}", resolvedPath);
E2D_LOG_ERROR("ResourceManager: failed to read JSON file: {}",
resolvedPath);
return "";
}
@ -1032,7 +1062,8 @@ std::string ResourceManager::loadJsonFile(const std::string &filepath) {
// 缓存内容
jsonFileCache_[filepath] = content;
E2D_LOG_DEBUG("ResourceManager: loaded JSON file: {} ({} bytes)", filepath, content.size());
E2D_LOG_DEBUG("ResourceManager: loaded JSON file: {} ({} bytes)", filepath,
content.size());
return content;
}

View File

@ -5,7 +5,7 @@
namespace extra2d {
Scene::Scene() { defaultCamera_ = makePtr<Camera>(); }
Scene::Scene() { defaultCamera_ = shared<Camera>(); }
void Scene::setCamera(Ptr<Camera> camera) { camera_ = camera; }
@ -126,6 +126,6 @@ void Scene::collectRenderCommands(std::vector<RenderCommand> &commands,
Node::collectRenderCommands(commands, parentZOrder);
}
Ptr<Scene> Scene::create() { return makePtr<Scene>(); }
Ptr<Scene> Scene::create() { return shared<Scene>(); }
} // namespace extra2d

View File

@ -9,10 +9,10 @@ namespace extra2d {
ShapeNode::ShapeNode() = default;
Ptr<ShapeNode> ShapeNode::create() { return makePtr<ShapeNode>(); }
Ptr<ShapeNode> ShapeNode::create() { return shared<ShapeNode>(); }
Ptr<ShapeNode> ShapeNode::createPoint(const Vec2 &pos, const Color &color) {
auto node = makePtr<ShapeNode>();
auto node = shared<ShapeNode>();
node->shapeType_ = ShapeType::Point;
node->color_ = color;
node->points_ = {pos};
@ -21,7 +21,7 @@ Ptr<ShapeNode> ShapeNode::createPoint(const Vec2 &pos, const Color &color) {
Ptr<ShapeNode> ShapeNode::createLine(const Vec2 &start, const Vec2 &end,
const Color &color, float width) {
auto node = makePtr<ShapeNode>();
auto node = shared<ShapeNode>();
node->shapeType_ = ShapeType::Line;
node->color_ = color;
node->lineWidth_ = width;
@ -31,7 +31,7 @@ Ptr<ShapeNode> ShapeNode::createLine(const Vec2 &start, const Vec2 &end,
Ptr<ShapeNode> ShapeNode::createRect(const Rect &rect, const Color &color,
float width) {
auto node = makePtr<ShapeNode>();
auto node = shared<ShapeNode>();
node->shapeType_ = ShapeType::Rect;
node->color_ = color;
node->lineWidth_ = width;
@ -52,7 +52,7 @@ Ptr<ShapeNode> ShapeNode::createFilledRect(const Rect &rect,
Ptr<ShapeNode> ShapeNode::createCircle(const Vec2 &center, float radius,
const Color &color, int segments,
float width) {
auto node = makePtr<ShapeNode>();
auto node = shared<ShapeNode>();
node->shapeType_ = ShapeType::Circle;
node->color_ = color;
node->lineWidth_ = width;
@ -74,7 +74,7 @@ Ptr<ShapeNode> ShapeNode::createFilledCircle(const Vec2 &center, float radius,
Ptr<ShapeNode> ShapeNode::createTriangle(const Vec2 &p1, const Vec2 &p2,
const Vec2 &p3, const Color &color,
float width) {
auto node = makePtr<ShapeNode>();
auto node = shared<ShapeNode>();
node->shapeType_ = ShapeType::Triangle;
node->color_ = color;
node->lineWidth_ = width;
@ -93,7 +93,7 @@ Ptr<ShapeNode> ShapeNode::createFilledTriangle(const Vec2 &p1, const Vec2 &p2,
Ptr<ShapeNode> ShapeNode::createPolygon(const std::vector<Vec2> &points,
const Color &color, float width) {
auto node = makePtr<ShapeNode>();
auto node = shared<ShapeNode>();
node->shapeType_ = ShapeType::Polygon;
node->color_ = color;
node->lineWidth_ = width;
@ -262,16 +262,16 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
case ShapeType::Point:
if (!points_.empty()) {
cmd.type = RenderCommandType::FilledCircle;
cmd.data =
CircleCommandData{points_[0] + offset, lineWidth_ * 0.5f, color_, 8, 0.0f, true};
cmd.data = CircleCommandData{
points_[0] + offset, lineWidth_ * 0.5f, color_, 8, 0.0f, true};
}
break;
case ShapeType::Line:
if (points_.size() >= 2) {
cmd.type = RenderCommandType::Line;
cmd.data = LineCommandData{points_[0] + offset, points_[1] + offset, color_,
lineWidth_};
cmd.data = LineCommandData{points_[0] + offset, points_[1] + offset,
color_, lineWidth_};
}
break;
@ -281,14 +281,14 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
cmd.type = RenderCommandType::FilledRect;
Rect rect(points_[0].x, points_[0].y, points_[2].x - points_[0].x,
points_[2].y - points_[0].y);
cmd.data =
RectCommandData{Rect(rect.origin + offset, rect.size), color_, 0.0f, true};
cmd.data = RectCommandData{Rect(rect.origin + offset, rect.size),
color_, 0.0f, true};
} else {
cmd.type = RenderCommandType::Rect;
Rect rect(points_[0].x, points_[0].y, points_[2].x - points_[0].x,
points_[2].y - points_[0].y);
cmd.data =
RectCommandData{Rect(rect.origin + offset, rect.size), color_, lineWidth_, false};
cmd.data = RectCommandData{Rect(rect.origin + offset, rect.size),
color_, lineWidth_, false};
}
}
break;
@ -298,12 +298,12 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
float radius = points_[1].x;
if (filled_) {
cmd.type = RenderCommandType::FilledCircle;
cmd.data =
CircleCommandData{points_[0] + offset, radius, color_, segments_, 0.0f, true};
cmd.data = CircleCommandData{points_[0] + offset, radius, color_,
segments_, 0.0f, true};
} else {
cmd.type = RenderCommandType::Circle;
cmd.data = CircleCommandData{points_[0] + offset, radius, color_, segments_,
lineWidth_, false};
cmd.data = CircleCommandData{points_[0] + offset, radius, color_,
segments_, lineWidth_, false};
}
}
break;
@ -336,7 +336,8 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
cmd.data = PolygonCommandData{transformedPoints, color_, 0.0f, true};
} else {
cmd.type = RenderCommandType::Polygon;
cmd.data = PolygonCommandData{transformedPoints, color_, lineWidth_, false};
cmd.data =
PolygonCommandData{transformedPoints, color_, lineWidth_, false};
}
}
break;

View File

@ -31,14 +31,14 @@ void Sprite::setFlipX(bool flip) { flipX_ = flip; }
void Sprite::setFlipY(bool flip) { flipY_ = flip; }
Ptr<Sprite> Sprite::create() { return makePtr<Sprite>(); }
Ptr<Sprite> Sprite::create() { return shared<Sprite>(); }
Ptr<Sprite> Sprite::create(Ptr<Texture> texture) {
return makePtr<Sprite>(texture);
return shared<Sprite>(texture);
}
Ptr<Sprite> Sprite::create(Ptr<Texture> texture, const Rect &rect) {
auto sprite = makePtr<Sprite>(texture);
auto sprite = shared<Sprite>(texture);
sprite->setTextureRect(rect);
return sprite;
}

View File

@ -15,7 +15,7 @@ public:
CSimpleIniA ini;
};
DataStore::DataStore() : impl_(makeUnique<Impl>()) {}
DataStore::DataStore() : impl_(unique<Impl>()) {}
DataStore::~DataStore() {
// 如果在事务中,尝试提交
@ -203,9 +203,7 @@ std::string DataStore::getSaveDataPath(const std::string &path) const {
return path;
}
UserId DataStore::getCurrentUserId() {
return UserId();
}
UserId DataStore::getCurrentUserId() { return UserId(); }
#endif
@ -402,7 +400,8 @@ std::vector<std::string> DataStore::getAllSections() const {
return sections;
}
std::vector<std::string> DataStore::getAllKeys(const std::string &section) const {
std::vector<std::string>
DataStore::getAllKeys(const std::string &section) const {
std::vector<std::string> keys;
CSimpleIniA::TNamesDepend keyList;
impl_->ini.GetAllKeys(section.c_str(), keyList);

View File

@ -1,6 +1,7 @@
#include <extra2d/window/window.h>
#include <extra2d/platform/input.h>
#include <extra2d/utils/logger.h>
#include <extra2d/window/window.h>
#include <SDL.h>
#include <glad/glad.h>
@ -8,10 +9,8 @@
namespace extra2d {
Window::Window()
: sdlWindow_(nullptr), glContext_(nullptr),
width_(1280), height_(720), vsync_(true), shouldClose_(false),
fullscreen_(true) {
}
: sdlWindow_(nullptr), glContext_(nullptr), width_(1280), height_(720),
vsync_(true), shouldClose_(false), fullscreen_(true) {}
Window::~Window() { destroy(); }
@ -31,7 +30,7 @@ bool Window::create(const WindowConfig &config) {
return false;
}
input_ = makeUnique<Input>();
input_ = unique<Input>();
input_->init();
E2D_LOG_INFO("Window created: {}x{}", width_, height_);
@ -57,7 +56,7 @@ bool Window::initSDL(const WindowConfig &config) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Uint32 windowFlags = SDL_WINDOW_OPENGL;
if (config.fullscreen) {
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
} else {
@ -71,7 +70,7 @@ bool Window::initSDL(const WindowConfig &config) {
config.centerWindow ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED,
config.centerWindow ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED,
width_, height_, windowFlags);
if (!sdlWindow_) {
E2D_LOG_ERROR("SDL_CreateWindow failed: {}", SDL_GetError());
SDL_Quit();
@ -97,7 +96,8 @@ bool Window::initSDL(const WindowConfig &config) {
return false;
}
if (gladLoadGLES2Loader(reinterpret_cast<GLADloadproc>(SDL_GL_GetProcAddress)) == 0) {
if (gladLoadGLES2Loader(
reinterpret_cast<GLADloadproc>(SDL_GL_GetProcAddress)) == 0) {
E2D_LOG_ERROR("gladLoadGLES2Loader failed");
SDL_GL_DeleteContext(glContext_);
glContext_ = nullptr;
@ -110,8 +110,10 @@ bool Window::initSDL(const WindowConfig &config) {
SDL_GL_SetSwapInterval(vsync_ ? 1 : 0);
E2D_LOG_INFO("SDL2 + OpenGL ES 3.0 initialized successfully");
E2D_LOG_INFO("OpenGL Version: {}", reinterpret_cast<const char*>(glGetString(GL_VERSION)));
E2D_LOG_INFO("OpenGL Renderer: {}", reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
E2D_LOG_INFO("OpenGL Version: {}",
reinterpret_cast<const char *>(glGetString(GL_VERSION)));
E2D_LOG_INFO("OpenGL Renderer: {}",
reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
return true;
}

View File

@ -105,7 +105,7 @@ int main(int argc, char **argv)
}
// 进入 Hello World 场景
app.enterScene(makePtr<HelloWorldScene>());
app.enterScene(shared<HelloWorldScene>());
// 运行应用
app.run();

View File

@ -96,7 +96,7 @@ void BaseScene::updateViewport() {
setViewportSize(GAME_WIDTH, GAME_HEIGHT);
// 创建并设置相机
auto camera = extra2d::makePtr<extra2d::Camera>();
auto camera = extra2d::shared<extra2d::Camera>();
camera->setViewport(0.0f, GAME_WIDTH, GAME_HEIGHT, 0.0f);
setCamera(camera);
}
@ -146,7 +146,7 @@ void GameScene::onEnter() {
float screenHeight = GAME_HEIGHT; // 512.0f
// 所有坐标都基于逻辑分辨率
auto bird = extra2d::makePtr<Bird>();
auto bird = extra2d::shared<Bird>();
bird->setPosition(extra2d::Vec2(screenWidth / 2.0f - 50.0f, screenHeight / 2.0f));
addChild(bird);
}
@ -246,17 +246,17 @@ public:
auto& scenes = app.scenes();
// 运行第一个场景
scenes.runWithScene(makePtr<GameScene>());
scenes.runWithScene(shared<GameScene>());
// 替换当前场景(无过渡)
scenes.replaceScene(makePtr<GameScene>());
scenes.replaceScene(shared<GameScene>());
// 替换当前场景(有过渡效果)
scenes.replaceScene(makePtr<GameScene>(), TransitionType::Fade, 0.5f);
scenes.replaceScene(shared<GameScene>(), TransitionType::Fade, 0.5f);
// 推入场景(保留当前场景)
scenes.pushScene(makePtr<NewScene>());
scenes.pushScene(makePtr<NewScene>(), TransitionType::SlideLeft, 0.5f);
scenes.pushScene(shared<NewScene>());
scenes.pushScene(shared<NewScene>(), TransitionType::SlideLeft, 0.5f);
// 弹出场景(返回上一个场景)
scenes.popScene();
@ -319,7 +319,7 @@ scenes.end();
## 场景生命周期
```
创建场景 (makePtr<Scene>)
创建场景 (shared<Scene>)
进入场景 (runWithScene/replaceScene/pushScene)
@ -452,7 +452,7 @@ private:
switch (selectedIndex_) {
case 0:
scenes.replaceScene(makePtr<GameScene>(),
scenes.replaceScene(shared<GameScene>(),
TransitionType::Fade, 0.25f);
break;
case 1:

View File

@ -170,7 +170,7 @@ panel->setPosition(Vec2(0, 256)); // 相对于父节点的中心
addChild(panel);
// 添加子节点到 panel
auto scoreNumber = makePtr<Number>();
auto scoreNumber = shared<Number>();
scoreNumber->setPosition(Vec2(95.0f, 10.0f)); // 相对于 panel 中心
panel->addChild(scoreNumber);
@ -384,7 +384,7 @@ parent->reorderChild(child, newZOrder);
class Player : public Node {
public:
static Ptr<Player> create(Ptr<Texture> texture) {
auto player = makePtr<Player>();
auto player = shared<Player>();
if (player->init(texture)) {
return player;
}
@ -454,7 +454,7 @@ void GameOverLayer::onEnter() {
initButtons();
// 创建向上移动的动画
auto moveAction = extra2d::makePtr<extra2d::MoveBy>(
auto moveAction = extra2d::shared<extra2d::MoveBy>(
1.0f, extra2d::Vec2(0.0f, -screenHeight)
);
runAction(moveAction);
@ -474,7 +474,7 @@ void GameOverLayer::initPanel(int score, float screenHeight) {
addChild(panel);
// 显示本局得分(相对于 panel 的本地坐标)
auto scoreNumber = extra2d::makePtr<Number>();
auto scoreNumber = extra2d::shared<Number>();
scoreNumber->setLittleNumber(score);
scoreNumber->setPosition(extra2d::Vec2(95.0f, 10.0f));
panel->addChild(scoreNumber);
@ -483,7 +483,7 @@ void GameOverLayer::initPanel(int score, float screenHeight) {
static int bestScore = 0;
if (score > bestScore) bestScore = score;
auto bestNumber = extra2d::makePtr<Number>();
auto bestNumber = extra2d::shared<Number>();
bestNumber->setLittleNumber(bestScore);
bestNumber->setPosition(extra2d::Vec2(95.0f, 50.0f));
panel->addChild(bestNumber);
@ -591,16 +591,16 @@ Extra2D 提供了丰富的动作类:
```cpp
// 移动动画
auto moveAction = makePtr<MoveBy>(1.0f, Vec2(0.0f, -100.0f));
auto moveAction = shared<MoveBy>(1.0f, Vec2(0.0f, -100.0f));
node->runAction(moveAction);
// 缩放动画
auto scaleAction = makePtr<ScaleTo>(0.5f, 2.0f);
auto scaleAction = shared<ScaleTo>(0.5f, 2.0f);
node->runAction(scaleAction);
// 淡入淡出
auto fadeOut = makePtr<FadeOut>(0.3f);
auto fadeIn = makePtr<FadeIn>(0.3f);
auto fadeOut = shared<FadeOut>(0.3f);
auto fadeIn = shared<FadeIn>(0.3f);
node->runAction(fadeOut);
```
@ -614,7 +614,7 @@ void GameOverLayer::onEnter() {
Node::onEnter();
// 创建向上移动的动画
auto moveAction = extra2d::makePtr<extra2d::MoveBy>(
auto moveAction = extra2d::shared<extra2d::MoveBy>(
1.0f, extra2d::Vec2(0.0f, -screenHeight));
// 设置动画完成回调
@ -636,7 +636,7 @@ void GameOverLayer::onEnter() {
```cpp
// 顺序执行:先移动,再缩放,最后淡出
auto sequence = makePtr<Sequence>({
auto sequence = shared<Sequence>({
new MoveTo(1.0f, Vec2(100, 100)),
new ScaleTo(0.5f, 2.0f),
new FadeOut(0.3f)
@ -644,21 +644,21 @@ auto sequence = makePtr<Sequence>({
node->runAction(sequence);
// 并行执行:同时移动和旋转
auto spawn = makePtr<Spawn>({
auto spawn = shared<Spawn>({
new MoveTo(1.0f, Vec2(100, 100)),
new RotateBy(1.0f, 360.0f)
});
node->runAction(spawn);
// 循环执行
auto loop = makePtr<Loop(new RotateBy(1.0f, 360.0f), 5); // 旋转5次
auto loop = shared<Loop(new RotateBy(1.0f, 360.0f), 5); // 旋转5次
node->runAction(loop);
```
### 动画进度回调
```cpp
auto action = makePtr<MoveTo>(2.0f, Vec2(100, 100));
auto action = shared<MoveTo>(2.0f, Vec2(100, 100));
action->setProgressCallback([](float progress) {
// progress: 0.0 - 1.0
E2D_LOG_INFO("动画进度: {}%", progress * 100);

View File

@ -332,7 +332,7 @@ ResLoader::getKeyFrame(const std::string &name) {
}
const ImageInfo &info = it->second;
return extra2d::makePtr<extra2d::SpriteFrame>(
return extra2d::shared<extra2d::SpriteFrame>(
atlasTexture_, extra2d::Rect(info.x, info.y, info.width, info.height));
}

View File

@ -165,7 +165,7 @@ void GameOverLayer::onUpdate(float dt) {
if (input.isButtonPressed(extra2d::GamepadButton::A)) {
ResLoader::playMusic(MusicType::Click);
auto &app = extra2d::Application::instance();
app.scenes().replaceScene(extra2d::makePtr<GameScene>(),
app.scenes().replaceScene(extra2d::shared<GameScene>(),
extra2d::TransitionType::Fade, 0.5f);
}
@ -173,7 +173,7 @@ void GameOverLayer::onUpdate(float dt) {
if (input.isButtonPressed(extra2d::GamepadButton::B)) {
ResLoader::playMusic(MusicType::Click);
auto &app = extra2d::Application::instance();
app.scenes().replaceScene(extra2d::makePtr<StartScene>(),
app.scenes().replaceScene(extra2d::shared<StartScene>(),
extra2d::TransitionType::Fade, 0.5f);
}
}
@ -221,7 +221,7 @@ void GameOverLayer::onUpdate(float dt) {
if (input.isButtonPressed(extra2d::GamepadButton::A)) {
ResLoader::playMusic(MusicType::Click);
auto &app = extra2d::Application::instance();
app.scenes().replaceScene(extra2d::makePtr<GameScene>(),
app.scenes().replaceScene(extra2d::shared<GameScene>(),
extra2d::TransitionType::Fade, 0.5f);
}
@ -229,7 +229,7 @@ void GameOverLayer::onUpdate(float dt) {
if (input.isButtonPressed(extra2d::GamepadButton::B)) {
ResLoader::playMusic(MusicType::Click);
auto &app = extra2d::Application::instance();
app.scenes().replaceScene(extra2d::makePtr<StartScene>(),
app.scenes().replaceScene(extra2d::shared<StartScene>(),
extra2d::TransitionType::Fade, 0.5f);
}
}

View File

@ -85,7 +85,7 @@ public:
}
void createBox(float x, float y) {
auto box = makePtr<CollidableBox>(50.0f, 50.0f, Color(0.3f, 0.7f, 1.0f, 0.8f));
auto box = shared<CollidableBox>(50.0f, 50.0f, Color(0.3f, 0.7f, 1.0f, 0.8f));
box->setPosition(Vec2(x, y));
addChild(box); // 通过 addChild 管理节点生命周期
}

View File

@ -231,7 +231,7 @@ void GameOverLayer::onEnter() {
initButtons();
// 创建动画
auto moveAction = extra2d::makePtr<extra2d::MoveBy>(
auto moveAction = extra2d::shared<extra2d::MoveBy>(
1.0f, extra2d::Vec2(0.0f, -screenHeight));
// 动画完成后启用按钮

View File

@ -173,7 +173,7 @@ void Bird::jump() {
restartBtn_->setOnClick([]() {
ResLoader::playMusic(MusicType::Click); // 播放点击音效
auto &app = extra2d::Application::instance();
app.scenes().replaceScene(extra2d::makePtr<GameScene>(),
app.scenes().replaceScene(extra2d::shared<GameScene>(),
extra2d::TransitionType::Fade, 0.5f);
});
```

View File

@ -67,7 +67,7 @@ public:
// 创建移动的中心方块
centerBox_ =
makePtr<CollisionBox>(80.0f, 80.0f, Color(0.2f, 0.6f, 1.0f, 0.8f));
shared<CollisionBox>(80.0f, 80.0f, Color(0.2f, 0.6f, 1.0f, 0.8f));
centerBox_->setPosition(Vec2(centerX, centerY));
addChild(centerBox_);
@ -149,7 +149,8 @@ private:
addChild(fpsText_);
// 创建退出提示文本
float screenHeight = static_cast<float>(Application::instance().getConfig().height);
float screenHeight =
static_cast<float>(Application::instance().getConfig().height);
exitHintText_ = Text::create("按 + 键退出", infoFont_);
exitHintText_->setPosition(50.0f, screenHeight - 50.0f);
exitHintText_->setTextColor(Color(0.8f, 0.8f, 0.8f, 1.0f));
@ -182,7 +183,7 @@ private:
};
for (const auto &[pos, color] : positions) {
auto box = makePtr<CollisionBox>(70.0f, 70.0f, color);
auto box = shared<CollisionBox>(70.0f, 70.0f, color);
box->setPosition(pos);
addChild(box);
boxes_.push_back(box);
@ -238,8 +239,7 @@ private:
// 程序入口
// ============================================================================
int main(int argc, char **argv)
{
int main(int argc, char **argv) {
// 初始化日志系统
Logger::init();
Logger::setLevel(LogLevel::Debug);
@ -266,7 +266,7 @@ int main(int argc, char **argv)
}
// 进入场景
app.enterScene(makePtr<CollisionDemoScene>());
app.enterScene(shared<CollisionDemoScene>());
E2D_LOG_INFO("开始主循环...");

View File

@ -115,7 +115,7 @@ int main(int argc, char **argv) {
}
// 进入 Hello World 场景
app.enterScene(makePtr<HelloWorldScene>());
app.enterScene(shared<HelloWorldScene>());
E2D_LOG_INFO("开始主循环...");

View File

@ -321,7 +321,7 @@ int main(int argc, char **argv) {{
}}
// 进入主场景
app.enterScene(makePtr<MainScene>());
app.enterScene(shared<MainScene>());
E2D_LOG_INFO("开始主循环...");