feat(actor): 为Actor添加UUID支持和对象注册功能

添加UUID类用于生成唯一标识符
实现ObjectRegistry用于管理Actor对象
在Actor构造和析构时自动注册/注销对象
修改窗口默认分辨率为1280x720
This commit is contained in:
2026-03-29 10:27:30 +08:00
parent 51be8a6128
commit 890211431e
8 changed files with 204 additions and 5 deletions

View File

@@ -3,6 +3,7 @@
#include <frostbite2D/base/RefObject.h>
#include <frostbite2D/types/type_alias.h>
#include <frostbite2D/types/type_math.h>
#include <frostbite2D/types/uuid.h>
#include <frostbite2D/utils/intrusive_list.hpp>
#include <frostbite2D/event/event.h>
#include <frostbite2D/event/key_event.h>
@@ -43,6 +44,9 @@ public:
const std::string& GetName() const { return name_; }
void SetName(const std::string& name) { name_ = name; }
const UUID& GetUUID() const { return uuid_; }
std::string GetUUIDString() const { return uuid_.toString(); }
const Vec2& GetPosition() const { return position_; }
void SetPosition(const Vec2& pos);
void SetPosition(float x, float y);
@@ -129,6 +133,7 @@ private:
Scene* scene_;
ActorList children_;
UUID uuid_;
std::string name_;
Vec2 position_;
float rotation_;

View File

@@ -0,0 +1,37 @@
#pragma once
#include <frostbite2D/types/type_alias.h>
#include <memory>
#include <map>
namespace frostbite2D {
class Actor;
class UUID;
class ObjectRegistry {
public:
static ObjectRegistry& get();
ObjectRegistry(const ObjectRegistry&) = delete;
ObjectRegistry& operator=(const ObjectRegistry&) = delete;
void registerObject(const UUID& uuid, Actor* actor);
void unregisterObject(const UUID& uuid);
Actor* getObject(const UUID& uuid);
Actor* getObject(const std::string& uuidStr);
bool hasObject(const UUID& uuid) const;
bool hasObject(const std::string& uuidStr) const;
void clear();
private:
ObjectRegistry() = default;
~ObjectRegistry() = default;
std::map<std::string, Actor*> registry_;
};
} // namespace frostbite2D

View File

@@ -0,0 +1,36 @@
#pragma once
#include <array>
#include <cstdint>
#include <cstdlib>
#include <string>
namespace frostbite2D {
class UUID {
public:
static UUID generate();
static UUID fromString(const std::string& str);
std::string toString() const;
UUID() = default;
bool operator==(const UUID& other) const { return data_ == other.data_; }
bool operator!=(const UUID& other) const { return data_ != other.data_; }
bool isValid() const {
for (auto byte : data_) {
if (byte != 0) return true;
}
return false;
}
const std::array<uint8_t, 16>& data() const { return data_; }
private:
explicit UUID(const std::array<uint8_t, 16>& data) : data_(data) {}
std::array<uint8_t, 16> data_{};
};
} // namespace frostbite2D

View File

@@ -1,4 +1,5 @@
#include <frostbite2D/2d/actor.h>
#include <frostbite2D/base/object_registry.h>
#include <frostbite2D/event/key_event.h>
#include <frostbite2D/event/mouse_event.h>
#include <frostbite2D/event/touch_event.h>
@@ -16,6 +17,8 @@ Actor::Actor()
, zOrder_(0)
, opacity_(1.0f)
, anchor_(Vec2(0.0f, 0.0f)) {
uuid_ = UUID::generate();
ObjectRegistry::get().registerObject(uuid_, this);
}
void Actor::SetOpacity(float opacity) {
@@ -118,6 +121,7 @@ void Actor::updateWorldTransform() const {
}
Actor::~Actor() {
ObjectRegistry::get().unregisterObject(uuid_);
RemoveAllChildren();
}

View File

@@ -0,0 +1,44 @@
#include <frostbite2D/base/object_registry.h>
#include <frostbite2D/2d/actor.h>
#include <frostbite2D/types/uuid.h>
namespace frostbite2D {
ObjectRegistry& ObjectRegistry::get() {
static ObjectRegistry instance;
return instance;
}
void ObjectRegistry::registerObject(const UUID& uuid, Actor* actor) {
registry_[uuid.toString()] = actor;
}
void ObjectRegistry::unregisterObject(const UUID& uuid) {
registry_.erase(uuid.toString());
}
Actor* ObjectRegistry::getObject(const UUID& uuid) {
return getObject(uuid.toString());
}
Actor* ObjectRegistry::getObject(const std::string& uuidStr) {
auto it = registry_.find(uuidStr);
if (it != registry_.end()) {
return it->second;
}
return nullptr;
}
bool ObjectRegistry::hasObject(const UUID& uuid) const {
return hasObject(uuid.toString());
}
bool ObjectRegistry::hasObject(const std::string& uuidStr) const {
return registry_.find(uuidStr) != registry_.end();
}
void ObjectRegistry::clear() {
registry_.clear();
}
} // namespace frostbite2D

View File

@@ -4,6 +4,7 @@
#include <cstdio>
#include <memory>
#include <frostbite2D/audio/audio_system.h>
#include <frostbite2D/base/object_registry.h>
#include <frostbite2D/core/application.h>
#include <frostbite2D/event/event.h>
#include <frostbite2D/event/key_event.h>
@@ -102,6 +103,8 @@ void Application::shutdown() {
sdlQuitCalled = true;
}
ObjectRegistry::get().clear();
initialized_ = false;
running_ = false;
}
@@ -155,12 +158,11 @@ bool Application::initCoreModules() {
// 设置窗口清除颜色和视口
renderer_->setClearColor(0.0f, 0.0f, 0.0f);
renderer_->setViewport(0, 0, config_.windowConfig.width,
config_.windowConfig.height);
renderer_->setViewport(0, 0, window_->width(), window_->height());
// 创建并设置相机
camera_ = new Camera();
camera_->setViewport(config_.windowConfig.width, config_.windowConfig.height);
camera_->setViewport(window_->width(), window_->height());
camera_->setFlipY(true); // 启用 Y 轴翻转,(0,0) 在左上角
renderer_->setCamera(camera_);

View File

@@ -0,0 +1,67 @@
#include <frostbite2D/types/uuid.h>
#include <cstdio>
#include <sstream>
#include <iomanip>
namespace frostbite2D {
UUID UUID::generate() {
std::array<uint8_t, 16> data;
for (int i = 0; i < 16; ++i) {
data[i] = static_cast<uint8_t>(rand() % 256);
}
data[6] = (data[6] & 0x0F) | 0x40;
data[8] = (data[8] & 0x3F) | 0x80;
return UUID(data);
}
UUID UUID::fromString(const std::string& str) {
if (str.length() != 36) {
return UUID{};
}
std::array<uint8_t, 16> data{};
std::stringstream ss(str);
char dash;
for (int i = 0; i < 16; ++i) {
int byte;
ss >> std::hex >> byte;
data[i] = static_cast<uint8_t>(byte);
if (i < 15) {
ss >> dash;
}
}
return UUID(data);
}
std::string UUID::toString() const {
const auto& data = data_;
std::stringstream ss;
ss << std::hex << std::setfill('0')
<< std::setw(2) << static_cast<int>(data[0])
<< std::setw(2) << static_cast<int>(data[1])
<< std::setw(2) << static_cast<int>(data[2])
<< std::setw(2) << static_cast<int>(data[3])
<< '-'
<< std::setw(2) << static_cast<int>(data[4])
<< std::setw(2) << static_cast<int>(data[5])
<< '-'
<< std::setw(2) << static_cast<int>(data[6])
<< std::setw(2) << static_cast<int>(data[7])
<< '-'
<< std::setw(2) << static_cast<int>(data[8])
<< std::setw(2) << static_cast<int>(data[9])
<< '-'
<< std::setw(2) << static_cast<int>(data[10])
<< std::setw(2) << static_cast<int>(data[11])
<< std::setw(2) << static_cast<int>(data[12])
<< std::setw(2) << static_cast<int>(data[13])
<< std::setw(2) << static_cast<int>(data[14])
<< std::setw(2) << static_cast<int>(data[15]);
return ss.str();
}
} // namespace frostbite2D

View File

@@ -32,8 +32,8 @@ int main(int argc, char **argv) {
AppConfig config = AppConfig::createDefault();
config.appName = "Frostbite2D Test App";
config.appVersion = "1.0.0";
config.windowConfig.width = 1920;
config.windowConfig.height = 1080;
config.windowConfig.width = 1280;
config.windowConfig.height = 720;
config.windowConfig.title = "Frostbite2D - Renderer Test";
Application& app = Application::get();
@@ -66,6 +66,10 @@ int main(int argc, char **argv) {
SDL_Log("Animation created successfully");
// ani->SetAnchor(Vec2(0.5f, 0.5f));
ani->SetPosition(640, 360);
auto uuid = ani->GetUUIDString();
SDL_Log("Animation UUID: %s", uuid.c_str());
menuScene->AddChild(ani);
}