Compare commits

...

2 Commits

Author SHA1 Message Date
ChestnutYueyue 4e6db88da5 docs: 删除废弃的资源服务设计文档
该文档已不再使用,其内容已被迁移到新的设计文档中
2026-02-20 19:03:13 +08:00
ChestnutYueyue b41e96d870 refactor(core): 统一命名规范并优化核心模块结构
重构智能指针、基础类型和核心组件的命名,使用更简洁一致的命名风格:
- 将 UniquePtr/SharedPtr 简化为 Unique/Ref
- 基础类型使用 i32/u32/f32 等更短名称
- 方法名统一为小写驼峰,如 getServiceInfo() 改为 info()
- 模块初始化方法 parallel() 替代 allowParallelInit()

新增核心组件:
- 添加 ObjectPool 对象池模板类
- 添加 RingBuffer 环形缓冲区模板类
- 添加编译期类型ID生成机制

优化现有组件:
- 事件队列改用 RingBuffer 实现
- 服务注册表改用数组存储提高缓存友好性
- 模块依赖管理算法优化
- 统一时间相关参数为 f32/f64 类型

移除冗余代码,简化接口设计,提升整体代码一致性和性能
2026-02-20 19:02:21 +08:00
34 changed files with 1381 additions and 1022 deletions

View File

@ -76,8 +76,8 @@ public:
*/ */
void resume(); void resume();
bool isPaused() const { return paused_; } bool paused() const { return paused_; }
bool isRunning() const { return running_; } bool running() const { return running_; }
/** /**
* @brief * @brief
@ -85,9 +85,9 @@ public:
*/ */
GLFWWindow *window(); GLFWWindow *window();
float deltaTime() const { return deltaTime_; } f32 dt() const { return dt_; }
float totalTime() const { return totalTime_; } f32 totalTime() const { return totalTime_; }
int fps() const { return currentFps_; } int fps() const { return fps_; }
private: private:
Application(); Application();
@ -102,12 +102,12 @@ private:
bool paused_ = false; bool paused_ = false;
bool shouldQuit_ = false; bool shouldQuit_ = false;
float deltaTime_ = 0.0f; f32 dt_ = 0.0f;
float totalTime_ = 0.0f; f32 totalTime_ = 0.0f;
double lastFrameTime_ = 0.0; f64 lastFrameTime_ = 0.0;
int frameCount_ = 0; int frameCount_ = 0;
float fpsTimer_ = 0.0f; f32 fpsTimer_ = 0.0f;
int currentFps_ = 0; int fps_ = 0;
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -56,7 +56,7 @@ public:
* @brief * @brief
* @return true * @return true
*/ */
virtual bool allowParallelInit() const { return true; } virtual bool parallel() const { return true; }
/** /**
* @brief Application * @brief Application
@ -77,6 +77,6 @@ protected:
/** /**
* @brief * @brief
*/ */
using ModuleFactory = std::function<UniquePtr<Module>()>; using ModuleFactory = std::function<Unique<Module>()>;
} // namespace extra2d } // namespace extra2d

View File

@ -0,0 +1,64 @@
#pragma once
#include <extra2d/core/types.h>
#include <array>
#include <queue>
namespace extra2d {
/**
* @brief
* @tparam T
* @tparam Size
*/
template <typename T, size_t Size>
class ObjectPool {
public:
ObjectPool() {
for (size_t i = 0; i < Size; ++i) {
available_.push(&pool_[i]);
}
}
/**
* @brief
* @return nullptr
*/
T* acquire() {
if (available_.empty()) {
return nullptr;
}
T* obj = available_.front();
available_.pop();
return obj;
}
/**
* @brief
* @param obj
*/
void release(T* obj) {
if (obj >= pool_.data() && obj < pool_.data() + Size) {
obj->~T();
new (obj) T();
available_.push(obj);
}
}
/**
* @brief
*/
size_t available() const { return available_.size(); }
/**
* @brief
*/
static constexpr size_t capacity() { return Size; }
private:
alignas(alignof(T)) std::array<u8, sizeof(T) * Size> storage_;
T* pool_ = reinterpret_cast<T*>(storage_.data());
std::queue<T*> available_;
};
} // namespace extra2d

View File

@ -2,7 +2,7 @@
#include <extra2d/core/module.h> #include <extra2d/core/module.h>
#include <extra2d/core/types.h> #include <extra2d/core/types.h>
#include <unordered_map> #include <array>
#include <typeindex> #include <typeindex>
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -12,12 +12,32 @@ namespace extra2d {
class Application; class Application;
/**
* @brief ID生成器
*/
using TypeId = size_t;
namespace detail {
inline TypeId nextTypeId() {
static TypeId id = 0;
return ++id;
}
template<typename T>
inline TypeId getTypeId() {
static TypeId id = nextTypeId();
return id;
}
}
/** /**
* @brief * @brief
* *
*/ */
class Registry { class Registry {
public: public:
static constexpr size_t MAX_MODULES = 64;
static Registry& instance(); static Registry& instance();
Registry(const Registry&) = delete; Registry(const Registry&) = delete;
@ -33,16 +53,30 @@ public:
template<typename T, typename... Args> template<typename T, typename... Args>
T* use(Args&&... args) { T* use(Args&&... args) {
static_assert(std::is_base_of_v<Module, T>, "T must derive from Module"); static_assert(std::is_base_of_v<Module, T>, "T must derive from Module");
auto typeIdx = std::type_index(typeid(T)); TypeId typeId = detail::getTypeId<T>();
if (modules_.count(typeIdx)) {
return static_cast<T*>(modules_[typeIdx].get()); // 数组查找O(n) 但 n 很小,缓存友好
for (size_t i = 0; i < moduleCount_; ++i) {
if (modules_[i].id == typeId) {
return static_cast<T*>(modules_[i].module.get());
}
} }
auto module = makeUnique<T>(std::forward<Args>(args)...); // 添加新模块
if (moduleCount_ >= MAX_MODULES) {
return nullptr; // 模块数量超过上限
}
auto module = ptr::makeUnique<T>(std::forward<Args>(args)...);
T* ptr = module.get(); T* ptr = module.get();
module->setApp(app_); module->setApp(app_);
modules_[typeIdx] = std::move(module);
modules_[moduleCount_].id = typeId;
modules_[moduleCount_].module = std::move(module);
modules_[moduleCount_].valid = true;
++moduleCount_;
return ptr; return ptr;
} }
@ -53,10 +87,12 @@ public:
*/ */
template<typename T> template<typename T>
T* get() const { T* get() const {
auto typeIdx = std::type_index(typeid(T)); TypeId typeId = detail::getTypeId<T>();
auto it = modules_.find(typeIdx);
if (it != modules_.end()) { for (size_t i = 0; i < moduleCount_; ++i) {
return static_cast<T*>(it->second.get()); if (modules_[i].id == typeId && modules_[i].valid) {
return static_cast<T*>(modules_[i].module.get());
}
} }
return nullptr; return nullptr;
} }
@ -67,9 +103,12 @@ public:
* @return * @return
*/ */
Module* get(std::type_index typeIdx) const { Module* get(std::type_index typeIdx) const {
auto it = modules_.find(typeIdx); // 这里仍然使用type_index作为后备方案
if (it != modules_.end()) { for (size_t i = 0; i < moduleCount_; ++i) {
return it->second.get(); if (modules_[i].valid &&
std::type_index(typeid(*modules_[i].module)) == typeIdx) {
return modules_[i].module.get();
}
} }
return nullptr; return nullptr;
} }
@ -98,26 +137,33 @@ public:
/** /**
* @brief * @brief
*/ */
size_t size() const { return modules_.size(); } size_t size() const { return moduleCount_; }
private: private:
Registry() = default; Registry() = default;
~Registry() = default; ~Registry() = default;
struct ModuleEntry {
TypeId id = 0;
Unique<Module> module;
bool valid = false;
};
/** /**
* @brief * @brief
* @return * @return
*/ */
std::vector<Module*> topologicalSort(); std::vector<Module*> sort();
/** /**
* @brief * @brief
* *
* @return * @return
*/ */
std::vector<std::vector<Module*>> groupByLevel(); std::vector<std::vector<Module*>> group();
std::unordered_map<std::type_index, UniquePtr<Module>> modules_; std::array<ModuleEntry, MAX_MODULES> modules_;
size_t moduleCount_ = 0;
Application* app_ = nullptr; Application* app_ = nullptr;
}; };

View File

@ -0,0 +1,398 @@
#pragma once
#include <extra2d/core/types.h>
#include <string>
#include <variant>
namespace extra2d {
/**
* @brief
*/
enum class ErrorCode {
None = 0,
Unknown = 1,
InvalidArgument = 2,
OutOfMemory = 3,
FileNotFound = 4,
PermissionDenied = 5,
NotImplemented = 6,
AlreadyExists = 7,
NotInitialized = 8,
AlreadyInitialized = 9,
OperationFailed = 10,
Timeout = 11,
Cancelled = 12,
InvalidState = 13,
ResourceExhausted = 14,
Unavailable = 15,
DataLoss = 16,
Unauthenticated = 17,
PermissionDenied2 = 18,
ResourceNotFound = 19,
Aborted = 20,
OutOfRange = 21,
Unimplemented = 22,
Internal = 23,
DataCorrupted = 24,
RequestTooLarge = 25,
ResourceBusy = 26,
QuotaExceeded = 27,
DeadlineExceeded = 28,
LoadBalancing = 29,
NetworkError = 30,
ProtocolError = 31,
ServiceUnavailable = 32,
GatewayError = 33,
RateLimited = 34,
BadRequest = 35,
Unauthorized = 36,
Forbidden = 37,
NotFound = 38,
MethodNotAllowed = 39,
Conflict = 40,
Gone = 41,
LengthRequired = 42,
PreconditionFailed = 43,
PayloadTooLarge = 44,
UriTooLong = 45,
UnsupportedMediaType = 46,
RangeNotSatisfiable = 47,
ExpectationFailed = 48,
ImATeapot = 49,
MisdirectedRequest = 50,
UnprocessableEntity = 51,
Locked = 52,
FailedDependency = 53,
TooEarly = 54,
UpgradeRequired = 55,
PreconditionRequired = 56,
TooManyRequests = 57,
RequestHeaderFieldsTooLarge = 58,
UnavailableForLegalReasons = 59
};
/**
* @brief
*/
struct Error {
ErrorCode code = ErrorCode::None;
std::string message;
std::string file;
int line = 0;
Error() = default;
Error(ErrorCode c, const std::string& msg) : code(c), message(msg) {}
Error(ErrorCode c, const std::string& msg, const std::string& f, int l)
: code(c), message(msg), file(f), line(l) {}
bool ok() const { return code == ErrorCode::None; }
static Error none() { return Error(); }
static Error unknown(const std::string& msg) { return Error(ErrorCode::Unknown, msg); }
static Error invalidArgument(const std::string& msg) { return Error(ErrorCode::InvalidArgument, msg); }
static Error outOfMemory(const std::string& msg) { return Error(ErrorCode::OutOfMemory, msg); }
static Error fileNotFound(const std::string& msg) { return Error(ErrorCode::FileNotFound, msg); }
static Error permissionDenied(const std::string& msg) { return Error(ErrorCode::PermissionDenied, msg); }
static Error notImplemented(const std::string& msg) { return Error(ErrorCode::NotImplemented, msg); }
static Error alreadyExists(const std::string& msg) { return Error(ErrorCode::AlreadyExists, msg); }
static Error notInitialized(const std::string& msg) { return Error(ErrorCode::NotInitialized, msg); }
static Error alreadyInitialized(const std::string& msg) { return Error(ErrorCode::AlreadyInitialized, msg); }
static Error operationFailed(const std::string& msg) { return Error(ErrorCode::OperationFailed, msg); }
static Error timeout(const std::string& msg) { return Error(ErrorCode::Timeout, msg); }
static Error cancelled(const std::string& msg) { return Error(ErrorCode::Cancelled, msg); }
static Error invalidState(const std::string& msg) { return Error(ErrorCode::InvalidState, msg); }
static Error resourceExhausted(const std::string& msg) { return Error(ErrorCode::ResourceExhausted, msg); }
static Error unavailable(const std::string& msg) { return Error(ErrorCode::Unavailable, msg); }
static Error dataLoss(const std::string& msg) { return Error(ErrorCode::DataLoss, msg); }
static Error unauthenticated(const std::string& msg) { return Error(ErrorCode::Unauthenticated, msg); }
static Error permissionDenied2(const std::string& msg) { return Error(ErrorCode::PermissionDenied2, msg); }
static Error resourceNotFound(const std::string& msg) { return Error(ErrorCode::ResourceNotFound, msg); }
static Error aborted(const std::string& msg) { return Error(ErrorCode::Aborted, msg); }
static Error outOfRange(const std::string& msg) { return Error(ErrorCode::OutOfRange, msg); }
static Error unimplemented(const std::string& msg) { return Error(ErrorCode::Unimplemented, msg); }
static Error internal(const std::string& msg) { return Error(ErrorCode::Internal, msg); }
static Error dataCorrupted(const std::string& msg) { return Error(ErrorCode::DataCorrupted, msg); }
static Error requestTooLarge(const std::string& msg) { return Error(ErrorCode::RequestTooLarge, msg); }
static Error resourceBusy(const std::string& msg) { return Error(ErrorCode::ResourceBusy, msg); }
static Error quotaExceeded(const std::string& msg) { return Error(ErrorCode::QuotaExceeded, msg); }
static Error deadlineExceeded(const std::string& msg) { return Error(ErrorCode::DeadlineExceeded, msg); }
static Error loadBalancing(const std::string& msg) { return Error(ErrorCode::LoadBalancing, msg); }
static Error networkError(const std::string& msg) { return Error(ErrorCode::NetworkError, msg); }
static Error protocolError(const std::string& msg) { return Error(ErrorCode::ProtocolError, msg); }
static Error serviceUnavailable(const std::string& msg) { return Error(ErrorCode::ServiceUnavailable, msg); }
static Error gatewayError(const std::string& msg) { return Error(ErrorCode::GatewayError, msg); }
static Error rateLimited(const std::string& msg) { return Error(ErrorCode::RateLimited, msg); }
static Error badRequest(const std::string& msg) { return Error(ErrorCode::BadRequest, msg); }
static Error unauthorized(const std::string& msg) { return Error(ErrorCode::Unauthorized, msg); }
static Error forbidden(const std::string& msg) { return Error(ErrorCode::Forbidden, msg); }
static Error notFound(const std::string& msg) { return Error(ErrorCode::NotFound, msg); }
static Error methodNotAllowed(const std::string& msg) { return Error(ErrorCode::MethodNotAllowed, msg); }
static Error conflict(const std::string& msg) { return Error(ErrorCode::Conflict, msg); }
static Error gone(const std::string& msg) { return Error(ErrorCode::Gone, msg); }
static Error lengthRequired(const std::string& msg) { return Error(ErrorCode::LengthRequired, msg); }
static Error preconditionFailed(const std::string& msg) { return Error(ErrorCode::PreconditionFailed, msg); }
static Error payloadTooLarge(const std::string& msg) { return Error(ErrorCode::PayloadTooLarge, msg); }
static Error uriTooLong(const std::string& msg) { return Error(ErrorCode::UriTooLong, msg); }
static Error unsupportedMediaType(const std::string& msg) { return Error(ErrorCode::UnsupportedMediaType, msg); }
static Error rangeNotSatisfiable(const std::string& msg) { return Error(ErrorCode::RangeNotSatisfiable, msg); }
static Error expectationFailed(const std::string& msg) { return Error(ErrorCode::ExpectationFailed, msg); }
static Error imATeapot(const std::string& msg) { return Error(ErrorCode::ImATeapot, msg); }
static Error misdirectedRequest(const std::string& msg) { return Error(ErrorCode::MisdirectedRequest, msg); }
static Error unprocessableEntity(const std::string& msg) { return Error(ErrorCode::UnprocessableEntity, msg); }
static Error locked(const std::string& msg) { return Error(ErrorCode::Locked, msg); }
static Error failedDependency(const std::string& msg) { return Error(ErrorCode::FailedDependency, msg); }
static Error tooEarly(const std::string& msg) { return Error(ErrorCode::TooEarly, msg); }
static Error upgradeRequired(const std::string& msg) { return Error(ErrorCode::UpgradeRequired, msg); }
static Error preconditionRequired(const std::string& msg) { return Error(ErrorCode::PreconditionRequired, msg); }
static Error tooManyRequests(const std::string& msg) { return Error(ErrorCode::TooManyRequests, msg); }
static Error requestHeaderFieldsTooLarge(const std::string& msg) { return Error(ErrorCode::RequestHeaderFieldsTooLarge, msg); }
static Error unavailableForLegalReasons(const std::string& msg) { return Error(ErrorCode::UnavailableForLegalReasons, msg); }
};
/**
* @brief Result类型
* @tparam T
* @tparam E Error
*/
template<typename T, typename E = Error>
class Result {
public:
Result() : hasValue_(false) {
new (&storage_.error) E();
}
~Result() {
if (hasValue_) {
storage_.value.~T();
} else {
storage_.error.~E();
}
}
Result(const Result& other) : hasValue_(other.hasValue_) {
if (hasValue_) {
new (&storage_.value) T(other.storage_.value);
} else {
new (&storage_.error) E(other.storage_.error);
}
}
Result(Result&& other) noexcept : hasValue_(other.hasValue_) {
if (hasValue_) {
new (&storage_.value) T(std::move(other.storage_.value));
} else {
new (&storage_.error) E(std::move(other.storage_.error));
}
}
Result& operator=(const Result& other) {
if (this != &other) {
this->~Result();
hasValue_ = other.hasValue_;
if (hasValue_) {
new (&storage_.value) T(other.storage_.value);
} else {
new (&storage_.error) E(other.storage_.error);
}
}
return *this;
}
Result& operator=(Result&& other) noexcept {
if (this != &other) {
this->~Result();
hasValue_ = other.hasValue_;
if (hasValue_) {
new (&storage_.value) T(std::move(other.storage_.value));
} else {
new (&storage_.error) E(std::move(other.storage_.error));
}
}
return *this;
}
static Result<T, E> ok(T value) {
Result<T, E> result;
result.hasValue_ = true;
new (&result.storage_.value) T(std::move(value));
return result;
}
static Result<T, E> err(E error) {
Result<T, E> result;
result.hasValue_ = false;
new (&result.storage_.error) E(std::move(error));
return result;
}
bool ok() const { return hasValue_; }
bool isOk() const { return hasValue_; }
bool isErr() const { return !hasValue_; }
T& value() & {
return storage_.value;
}
const T& value() const & {
return storage_.value;
}
T&& value() && {
return std::move(storage_.value);
}
E& error() & {
return storage_.error;
}
const E& error() const & {
return storage_.error;
}
E&& error() && {
return std::move(storage_.error);
}
T valueOr(T defaultValue) const {
return hasValue_ ? storage_.value : std::move(defaultValue);
}
template<typename F>
Result<T, E> map(F&& f) {
if (hasValue_) {
return Result<T, E>::ok(f(storage_.value));
}
return *this;
}
template<typename F>
Result<T, E> mapErr(F&& f) {
if (!hasValue_) {
return Result<T, E>::err(f(storage_.error));
}
return *this;
}
template<typename F>
auto andThen(F&& f) -> decltype(f(std::declval<T>())) {
if (hasValue_) {
return f(storage_.value);
}
return Result<typename decltype(f(std::declval<T>()))::ValueType, E>::err(storage_.error);
}
template<typename F>
Result<T, E> orElse(F&& f) {
if (!hasValue_) {
return f(storage_.error);
}
return *this;
}
private:
union Storage {
T value;
E error;
Storage() {}
~Storage() {}
} storage_;
bool hasValue_;
};
// 特化void类型
template<typename E>
class Result<void, E> {
public:
Result() : hasValue_(true) {}
~Result() {
if (!hasValue_) {
storage_.error.~E();
}
}
Result(const Result& other) : hasValue_(other.hasValue_) {
if (!hasValue_) {
new (&storage_.error) E(other.storage_.error);
}
}
Result(Result&& other) noexcept : hasValue_(other.hasValue_) {
if (!hasValue_) {
new (&storage_.error) E(std::move(other.storage_.error));
}
}
Result& operator=(const Result& other) {
if (this != &other) {
this->~Result();
hasValue_ = other.hasValue_;
if (!hasValue_) {
new (&storage_.error) E(other.storage_.error);
}
}
return *this;
}
Result& operator=(Result&& other) noexcept {
if (this != &other) {
this->~Result();
hasValue_ = other.hasValue_;
if (!hasValue_) {
new (&storage_.error) E(std::move(other.storage_.error));
}
}
return *this;
}
static Result<void, E> ok() {
return Result<void, E>();
}
static Result<void, E> err(E error) {
Result<void, E> result;
result.hasValue_ = false;
new (&result.storage_.error) E(std::move(error));
return result;
}
bool ok() const { return hasValue_; }
bool isOk() const { return hasValue_; }
bool isErr() const { return !hasValue_; }
E& error() & {
return storage_.error;
}
const E& error() const & {
return storage_.error;
}
E&& error() && {
return std::move(storage_.error);
}
private:
union Storage {
E error;
Storage() {}
~Storage() {}
} storage_;
bool hasValue_;
};
// 便捷宏
#define E2D_TRY(result) \
do { \
auto _res = (result); \
if (!_res.ok()) { \
return Result<decltype(_res)::ValueType, decltype(_res)::ErrorType>::err(_res.error()); \
} \
} while(0)
} // namespace extra2d

View File

@ -0,0 +1,103 @@
#pragma once
#include <extra2d/core/types.h>
#include <atomic>
#include <array>
namespace extra2d {
/**
* @brief
* @tparam T
* @tparam Size 2
*/
template <typename T, size_t Size>
class RingBuffer {
static_assert((Size & (Size - 1)) == 0, "Size must be a power of 2");
public:
RingBuffer() = default;
/**
* @brief
* @param item
* @return truefalse
*/
bool push(const T& item) {
const size_t currentHead = head_.load(std::memory_order_relaxed);
const size_t currentTail = tail_.load(std::memory_order_acquire);
if ((currentHead - currentTail) >= Size) {
return false; // 缓冲区满
}
buffer_[currentHead & mask_] = item;
head_.store(currentHead + 1, std::memory_order_release);
return true;
}
/**
* @brief
* @param item
* @return truefalse
*/
bool push(T&& item) {
const size_t currentHead = head_.load(std::memory_order_relaxed);
const size_t currentTail = tail_.load(std::memory_order_acquire);
if ((currentHead - currentTail) >= Size) {
return false; // 缓冲区满
}
buffer_[currentHead & mask_] = std::move(item);
head_.store(currentHead + 1, std::memory_order_release);
return true;
}
/**
* @brief
* @param item
* @return truefalse
*/
bool pop(T& item) {
const size_t currentTail = tail_.load(std::memory_order_relaxed);
const size_t currentHead = head_.load(std::memory_order_acquire);
if (currentTail == currentHead) {
return false; // 缓冲区空
}
item = std::move(buffer_[currentTail & mask_]);
tail_.store(currentTail + 1, std::memory_order_release);
return true;
}
/**
* @brief
*/
bool empty() const {
return head_.load(std::memory_order_acquire) ==
tail_.load(std::memory_order_acquire);
}
/**
* @brief
*/
size_t size() const {
return head_.load(std::memory_order_acquire) -
tail_.load(std::memory_order_acquire);
}
/**
* @brief
*/
static constexpr size_t capacity() { return Size; }
private:
static constexpr size_t mask_ = Size - 1;
alignas(64) std::array<T, Size> buffer_;
alignas(64) std::atomic<size_t> head_{0};
alignas(64) std::atomic<size_t> tail_{0};
};
} // namespace extra2d

View File

@ -9,7 +9,7 @@ namespace extra2d {
* @brief * @brief
* *
*/ */
enum class ServicePriority : int { enum class ServicePriority : i32 {
Core = 0, Core = 0,
Event = 100, Event = 100,
Timer = 200, Timer = 200,
@ -56,13 +56,13 @@ public:
* @brief * @brief
* @return * @return
*/ */
virtual ServiceInfo getServiceInfo() const = 0; virtual ServiceInfo info() const = 0;
/** /**
* @brief * @brief
* @return true * @return true
*/ */
virtual bool initialize() = 0; virtual bool init() = 0;
/** /**
* @brief * @brief
@ -87,15 +87,15 @@ public:
/** /**
* @brief * @brief
* @param deltaTime * @param dt
*/ */
virtual void update(float deltaTime) { } virtual void update(f32 dt) { }
/** /**
* @brief * @brief
* @return true * @return true
*/ */
virtual bool isInitialized() const { virtual bool initialized() const {
return info_.state == ServiceState::Running || return info_.state == ServiceState::Running ||
info_.state == ServiceState::Paused; info_.state == ServiceState::Paused;
} }
@ -104,13 +104,13 @@ public:
* @brief * @brief
* @return * @return
*/ */
ServiceState getState() const { return info_.state; } ServiceState state() const { return info_.state; }
/** /**
* @brief * @brief
* @return * @return
*/ */
const std::string& getName() const { return info_.name; } const std::string& name() const { return info_.name; }
protected: protected:
ServiceInfo info_; ServiceInfo info_;

View File

@ -6,6 +6,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <shared_mutex>
#include <typeindex> #include <typeindex>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -15,7 +16,7 @@ namespace extra2d {
/** /**
* @brief * @brief
*/ */
template <typename T> using ServiceFactory = std::function<SharedPtr<T>()>; template <typename T> using ServiceFactory = Fn<Ref<T>()>;
/** /**
* @brief * @brief
@ -25,7 +26,7 @@ template <typename T> using ServiceFactory = std::function<SharedPtr<T>()>;
* - * -
* - * -
* - * -
* - 线 * - 线
* - Mock * - Mock
*/ */
class ServiceLocator { class ServiceLocator {
@ -42,39 +43,39 @@ public:
/** /**
* @brief * @brief
* @tparam T * @tparam T
* @param service * @param svc
*/ */
template <typename T> void registerService(SharedPtr<T> service) { template <typename T> void add(Ref<T> svc) {
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::recursive_mutex> lock(mutex_); std::unique_lock<std::shared_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
services_[typeId] = std::static_pointer_cast<IService>(service); services_[typeId] = std::static_pointer_cast<IService>(svc);
orderedServices_.push_back(service); orderedServices_.push_back(svc);
sortServices(); sort();
} }
/** /**
* @brief * @brief
* @tparam T * @tparam T
* @param factory * @param fn
*/ */
template <typename T> void registerFactory(ServiceFactory<T> factory) { template <typename T> void setFactory(ServiceFactory<T> fn) {
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::recursive_mutex> lock(mutex_); std::unique_lock<std::shared_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
factories_[typeId] = [factory]() -> SharedPtr<IService> { factories_[typeId] = [fn]() -> Ref<IService> {
return std::static_pointer_cast<IService>(factory()); return std::static_pointer_cast<IService>(fn());
}; };
// 立即创建服务实例并添加到有序列表 // 立即创建服务实例并添加到有序列表
auto service = factories_[typeId](); auto svc = factories_[typeId]();
services_[typeId] = service; services_[typeId] = svc;
orderedServices_.push_back(service); orderedServices_.push_back(svc);
sortServices(); sort();
} }
/** /**
@ -82,13 +83,15 @@ public:
* @tparam T * @tparam T
* @return nullptr * @return nullptr
*/ */
template <typename T> SharedPtr<T> getService() const { template <typename T> Ref<T> get() const {
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
// 读锁查询
std::shared_lock<std::shared_mutex> lock(mutex_);
auto it = services_.find(typeId); auto it = services_.find(typeId);
if (it != services_.end()) { if (it != services_.end()) {
return std::static_pointer_cast<T>(it->second); return std::static_pointer_cast<T>(it->second);
@ -96,9 +99,9 @@ public:
auto factoryIt = factories_.find(typeId); auto factoryIt = factories_.find(typeId);
if (factoryIt != factories_.end()) { if (factoryIt != factories_.end()) {
auto service = factoryIt->second(); auto svc = factoryIt->second();
services_[typeId] = service; services_[typeId] = svc;
return std::static_pointer_cast<T>(service); return std::static_pointer_cast<T>(svc);
} }
return nullptr; return nullptr;
@ -109,12 +112,14 @@ public:
* @tparam T * @tparam T
* @return nullptr * @return nullptr
*/ */
template <typename T> SharedPtr<T> tryGetService() const { template <typename T> Ref<T> tryGet() const {
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
std::lock_guard<std::recursive_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
// 读锁查询
std::shared_lock<std::shared_mutex> lock(mutex_);
auto it = services_.find(typeId); auto it = services_.find(typeId);
if (it != services_.end()) { if (it != services_.end()) {
return std::static_pointer_cast<T>(it->second); return std::static_pointer_cast<T>(it->second);
@ -127,8 +132,8 @@ public:
* @tparam T * @tparam T
* @return true * @return true
*/ */
template <typename T> bool hasService() const { template <typename T> bool has() const {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
return services_.find(typeId) != services_.end() || return services_.find(typeId) != services_.end() ||
factories_.find(typeId) != factories_.end(); factories_.find(typeId) != factories_.end();
@ -138,17 +143,17 @@ public:
* @brief * @brief
* @tparam T * @tparam T
*/ */
template <typename T> void unregisterService() { template <typename T> void remove() {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::unique_lock<std::shared_mutex> lock(mutex_);
auto typeId = std::type_index(typeid(T)); auto typeId = std::type_index(typeid(T));
auto it = services_.find(typeId); auto it = services_.find(typeId);
if (it != services_.end()) { if (it != services_.end()) {
auto service = it->second; auto svc = it->second;
services_.erase(it); services_.erase(it);
auto orderIt = auto orderIt =
std::find(orderedServices_.begin(), orderedServices_.end(), service); std::find(orderedServices_.begin(), orderedServices_.end(), svc);
if (orderIt != orderedServices_.end()) { if (orderIt != orderedServices_.end()) {
orderedServices_.erase(orderIt); orderedServices_.erase(orderIt);
} }
@ -161,34 +166,34 @@ public:
* @brief * @brief
* @return true * @return true
*/ */
bool initializeAll(); bool init();
/** /**
* @brief * @brief
*/ */
void shutdownAll(); void shutdown();
/** /**
* @brief * @brief
* @param deltaTime * @param dt
*/ */
void updateAll(float deltaTime); void update(f32 dt);
/** /**
* @brief * @brief
*/ */
void pauseAll(); void pause();
/** /**
* @brief * @brief
*/ */
void resumeAll(); void resume();
/** /**
* @brief * @brief
* @return * @return
*/ */
std::vector<SharedPtr<IService>> getAllServices() const; std::vector<Ref<IService>> all() const;
/** /**
* @brief * @brief
@ -208,13 +213,13 @@ private:
/** /**
* @brief * @brief
*/ */
void sortServices(); void sort();
mutable std::unordered_map<std::type_index, SharedPtr<IService>> services_; mutable std::unordered_map<std::type_index, Ref<IService>> services_;
std::unordered_map<std::type_index, std::function<SharedPtr<IService>()>> std::unordered_map<std::type_index, std::function<Ref<IService>()>>
factories_; factories_;
std::vector<SharedPtr<IService>> orderedServices_; std::vector<Ref<IService>> orderedServices_;
mutable std::recursive_mutex mutex_; mutable std::shared_mutex mutex_;
}; };
/** /**
@ -223,13 +228,13 @@ private:
*/ */
template <typename Interface, typename Implementation> class ServiceRegistrar { template <typename Interface, typename Implementation> class ServiceRegistrar {
public: public:
explicit ServiceRegistrar(ServiceFactory<Interface> factory = nullptr) { explicit ServiceRegistrar(ServiceFactory<Interface> fn = nullptr) {
if (factory) { if (fn) {
ServiceLocator::instance().registerFactory<Interface>(factory); ServiceLocator::instance().setFactory<Interface>(fn);
} else { } else {
ServiceLocator::instance().registerFactory<Interface>( ServiceLocator::instance().setFactory<Interface>(
[]() -> SharedPtr<Interface> { []() -> Ref<Interface> {
return makeShared<Implementation>(); return ptr::make<Implementation>();
}); });
} }
} }
@ -251,9 +256,9 @@ template <typename Interface, typename Implementation> struct ServiceAutoReg {
* @return true * @return true
*/ */
static bool doRegister() { static bool doRegister() {
::extra2d::ServiceLocator::instance().registerFactory<Interface>( ::extra2d::ServiceLocator::instance().setFactory<Interface>(
[]() -> ::extra2d::SharedPtr<Interface> { []() -> ::extra2d::Ref<Interface> {
return ::extra2d::makeShared<Implementation>(); return ::extra2d::ptr::make<Implementation>();
}); });
return true; return true;
} }
@ -271,8 +276,8 @@ template <typename Interface> struct ServiceAutoRegFactory {
template <typename Factory> struct Impl { template <typename Factory> struct Impl {
static const bool registered; static const bool registered;
static bool doRegister(Factory factory) { static bool doRegister(Factory fn) {
::extra2d::ServiceLocator::instance().registerFactory<Interface>(factory); ::extra2d::ServiceLocator::instance().setFactory<Interface>(fn);
return true; return true;
} }
}; };

View File

@ -14,7 +14,7 @@ namespace extra2d {
struct ServiceRegistration { struct ServiceRegistration {
std::string name; std::string name;
ServicePriority priority; ServicePriority priority;
std::function<SharedPtr<IService>()> factory; std::function<Ref<IService>()> factory;
bool enabled = true; bool enabled = true;
}; };
@ -41,7 +41,7 @@ public:
* @param priority * @param priority
*/ */
template<typename T, typename Impl> template<typename T, typename Impl>
void registerService(const std::string& name, ServicePriority priority) { void add(const std::string& name, ServicePriority priority) {
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
static_assert(std::is_base_of_v<T, Impl>, static_assert(std::is_base_of_v<T, Impl>,
@ -50,8 +50,8 @@ public:
ServiceRegistration reg; ServiceRegistration reg;
reg.name = name; reg.name = name;
reg.priority = priority; reg.priority = priority;
reg.factory = []() -> SharedPtr<IService> { reg.factory = []() -> Ref<IService> {
return std::static_pointer_cast<IService>(makeShared<Impl>()); return std::static_pointer_cast<IService>(ptr::make<Impl>());
}; };
registrations_.push_back(reg); registrations_.push_back(reg);
} }
@ -64,17 +64,17 @@ public:
* @param factory * @param factory
*/ */
template<typename T> template<typename T>
void registerServiceWithFactory( void addWithFactory(
const std::string& name, const std::string& name,
ServicePriority priority, ServicePriority priority,
std::function<SharedPtr<T>()> factory) { std::function<Ref<T>()> factory) {
static_assert(std::is_base_of_v<IService, T>, static_assert(std::is_base_of_v<IService, T>,
"T must derive from IService"); "T must derive from IService");
ServiceRegistration reg; ServiceRegistration reg;
reg.name = name; reg.name = name;
reg.priority = priority; reg.priority = priority;
reg.factory = [factory]() -> SharedPtr<IService> { reg.factory = [factory]() -> Ref<IService> {
return std::static_pointer_cast<IService>(factory()); return std::static_pointer_cast<IService>(factory());
}; };
registrations_.push_back(reg); registrations_.push_back(reg);
@ -85,19 +85,19 @@ public:
* @param name * @param name
* @param enabled * @param enabled
*/ */
void setServiceEnabled(const std::string& name, bool enabled); void setEnabled(const std::string& name, bool enabled);
/** /**
* @brief * @brief
* ServiceLocator * ServiceLocator
*/ */
void createAllServices(); void createAll();
/** /**
* @brief * @brief
* @return * @return
*/ */
const std::vector<ServiceRegistration>& getRegistrations() const { const std::vector<ServiceRegistration>& all() const {
return registrations_; return registrations_;
} }
@ -123,7 +123,7 @@ template<typename Interface, typename Implementation>
class AutoServiceRegistrar { class AutoServiceRegistrar {
public: public:
AutoServiceRegistrar(const std::string& name, ServicePriority priority) { AutoServiceRegistrar(const std::string& name, ServicePriority priority) {
ServiceRegistry::instance().registerService<Interface, Implementation>( ServiceRegistry::instance().add<Interface, Implementation>(
name, priority); name, priority);
} }
}; };

View File

@ -16,43 +16,46 @@ namespace extra2d {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// 智能指针别名 // 智能指针别名
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename T> using Ptr = std::shared_ptr<T>; template <typename T> using Ref = std::shared_ptr<T>;
template <typename T> using SharedPtr = std::shared_ptr<T>; template <typename T> using Unique = std::unique_ptr<T>;
template <typename T> using Weak = std::weak_ptr<T>;
template <typename T> using UniquePtr = std::unique_ptr<T>; /// 智能指针工厂函数命名空间
namespace ptr {
/// 创建 Ref 的便捷函数
template <typename T, typename... Args> inline Ref<T> make(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
template <typename T> using WeakPtr = std::weak_ptr<T>; /// 创建 Unique 的便捷函数
template <typename T, typename... Args>
/// 创建 shared_ptr 的便捷函数 inline Unique<T> makeUnique(Args &&...args) {
template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args) { return std::make_unique<T>(std::forward<Args>(args)...);
return std::make_shared<T>(std::forward<Args>(args)...); }
}
template <typename T, typename... Args> inline SharedPtr<T> makeShared(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
/// 创建 unique_ptr 的便捷函数
template <typename T, typename... Args>
inline UniquePtr<T> makeUnique(Args &&...args) {
return std::make_unique<T>(std::forward<Args>(args)...);
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// 函数别名 // 函数别名
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename Sig> using Function = std::function<Sig>; template <typename Sig> using Fn = std::function<Sig>;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// 基础类型别名 // 基础类型别名
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
using int8 = std::int8_t; using i8 = int8_t;
using int16 = std::int16_t; using i16 = int16_t;
using int32 = std::int32_t; using i32 = int32_t;
using int64 = std::int64_t; using i64 = int64_t;
using uint8 = std::uint8_t; using u8 = uint8_t;
using uint16 = std::uint16_t; using u16 = uint16_t;
using uint32 = std::uint32_t; using u32 = uint32_t;
using uint64 = std::uint64_t; using u64 = uint64_t;
using f32 = float;
using f64 = double;
// ---------------------------------------------------------------------------
// ID 类型别名
// ---------------------------------------------------------------------------
using ID = u32;
} // namespace extra2d } // namespace extra2d

View File

@ -59,70 +59,70 @@ enum class EventType {
// 键盘事件数据 // 键盘事件数据
// ============================================================================ // ============================================================================
struct KeyEvent { struct KeyEvent {
int keyCode; i32 key;
int scancode; i32 scancode;
int mods; // 修饰键 (Shift, Ctrl, Alt, etc.) i32 mods; // 修饰键 (Shift, Ctrl, Alt, etc.)
}; };
// ============================================================================ // ============================================================================
// 鼠标事件数据 // 鼠标事件数据
// ============================================================================ // ============================================================================
struct MouseButtonEvent { struct MouseButtonEvent {
int button; i32 button;
int mods; i32 mods;
Vec2 position; Vec2 pos;
}; };
struct MouseMoveEvent { struct MouseMoveEvent {
Vec2 position; Vec2 pos;
Vec2 delta; Vec2 delta;
}; };
struct MouseScrollEvent { struct MouseScrollEvent {
Vec2 offset; Vec2 offset;
Vec2 position; Vec2 pos;
}; };
// ============================================================================ // ============================================================================
// 窗口事件数据 // 窗口事件数据
// ============================================================================ // ============================================================================
struct WindowResizeEvent { struct WindowResizeEvent {
int width; i32 w;
int height; i32 h;
}; };
struct WindowMoveEvent { struct WindowMoveEvent {
int x; i32 x;
int y; i32 y;
}; };
// ============================================================================ // ============================================================================
// 游戏手柄事件数据 // 游戏手柄事件数据
// ============================================================================ // ============================================================================
struct GamepadButtonEvent { struct GamepadButtonEvent {
int gamepadId; i32 gamepadId;
int button; i32 button;
}; };
struct GamepadAxisEvent { struct GamepadAxisEvent {
int gamepadId; i32 gamepadId;
int axis; i32 axis;
float value; f32 value;
}; };
// ============================================================================ // ============================================================================
// 触摸事件数据 // 触摸事件数据
// ============================================================================ // ============================================================================
struct TouchEvent { struct TouchEvent {
int touchId; i32 touchId;
Vec2 position; Vec2 pos;
}; };
// ============================================================================ // ============================================================================
// 自定义事件数据 // 自定义事件数据
// ============================================================================ // ============================================================================
struct CustomEvent { struct CustomEvent {
uint32_t id; u32 id;
void *data; void *data;
}; };
@ -131,7 +131,7 @@ struct CustomEvent {
// ============================================================================ // ============================================================================
struct Event { struct Event {
EventType type = EventType::None; EventType type = EventType::None;
double timestamp = 0.0; f64 timestamp = 0.0;
bool handled = false; bool handled = false;
// 事件数据联合体 // 事件数据联合体
@ -141,32 +141,32 @@ struct Event {
data; data;
// 便捷访问方法 // 便捷访问方法
bool isWindowEvent() const { bool window() const {
return type == EventType::WindowClose || type == EventType::WindowResize || return type == EventType::WindowClose || type == EventType::WindowResize ||
type == EventType::WindowFocus || type == EventType::WindowFocus ||
type == EventType::WindowLostFocus || type == EventType::WindowMoved; type == EventType::WindowLostFocus || type == EventType::WindowMoved;
} }
bool isKeyboardEvent() const { bool keyboard() const {
return type == EventType::KeyPressed || type == EventType::KeyReleased || return type == EventType::KeyPressed || type == EventType::KeyReleased ||
type == EventType::KeyRepeat; type == EventType::KeyRepeat;
} }
bool isMouseEvent() const { bool mouse() const {
return type == EventType::MouseButtonPressed || return type == EventType::MouseButtonPressed ||
type == EventType::MouseButtonReleased || type == EventType::MouseButtonReleased ||
type == EventType::MouseMoved || type == EventType::MouseScrolled; type == EventType::MouseMoved || type == EventType::MouseScrolled;
} }
// 静态工厂方法 // 静态工厂方法
static Event createWindowResize(int width, int height); static Event windowResize(i32 w, i32 h);
static Event createWindowClose(); static Event windowClose();
static Event createKeyPress(int keyCode, int scancode, int mods); static Event keyPress(i32 key, i32 scancode, i32 mods);
static Event createKeyRelease(int keyCode, int scancode, int mods); static Event keyRelease(i32 key, i32 scancode, i32 mods);
static Event createMouseButtonPress(int button, int mods, const Vec2 &pos); static Event mousePress(i32 btn, i32 mods, Vec2 pos);
static Event createMouseButtonRelease(int button, int mods, const Vec2 &pos); static Event mouseRelease(i32 btn, i32 mods, Vec2 pos);
static Event createMouseMove(const Vec2 &pos, const Vec2 &delta); static Event mouseMove(Vec2 pos, Vec2 delta);
static Event createMouseScroll(const Vec2 &offset, const Vec2 &pos); static Event mouseScroll(Vec2 offset, Vec2 pos);
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -11,46 +11,46 @@ namespace extra2d {
// ============================================================================ // ============================================================================
// 事件监听器 ID // 事件监听器 ID
// ============================================================================ // ============================================================================
using ListenerId = uint64_t; using ListenerID = u64;
// ============================================================================ // ============================================================================
// 事件分发器 // 事件分发器
// ============================================================================ // ============================================================================
class EventDispatcher { class EventDispatcher {
public: public:
using EventCallback = std::function<void(Event &)>; using EventFn = Fn<void(Event &)>;
EventDispatcher(); EventDispatcher();
~EventDispatcher() = default; ~EventDispatcher() = default;
// 添加监听器 // 添加监听器
ListenerId addListener(EventType type, EventCallback callback); ListenerID on(EventType type, EventFn fn);
// 移除监听器 // 移除监听器
void removeListener(ListenerId id); void off(ListenerID id);
void removeAllListeners(EventType type); void offAll(EventType type);
void removeAllListeners(); void offAll();
// 分发事件 // 分发事件
void dispatch(Event &event); void dispatch(Event &event);
void dispatch(const Event &event); void dispatch(const Event &event);
// 处理事件队列 // 处理事件队列
void processQueue(class EventQueue &queue); void process(class EventQueue &queue);
// 统计 // 统计
size_t getListenerCount(EventType type) const; size_t listenerCount(EventType type) const;
size_t getTotalListenerCount() const; size_t totalListeners() const;
private: private:
struct Listener { struct Listener {
ListenerId id; ListenerID id;
EventType type; EventType type;
EventCallback callback; EventFn fn;
}; };
std::unordered_map<EventType, std::vector<Listener>> listeners_; std::unordered_map<EventType, std::vector<Listener>> listeners_;
ListenerId nextId_; ListenerID nextId_;
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <extra2d/core/ring_buffer.h>
#include <extra2d/core/types.h> #include <extra2d/core/types.h>
#include <extra2d/event/event.h> #include <extra2d/event/event.h>
#include <mutex> #include <mutex>
#include <queue>
namespace extra2d { namespace extra2d {
@ -12,29 +12,32 @@ namespace extra2d {
// ============================================================================ // ============================================================================
class EventQueue { class EventQueue {
public: public:
EventQueue(); static constexpr size_t DEFAULT_CAPACITY = 1024;
~EventQueue() = default;
// 添加事件到队列 EventQueue();
void push(const Event &event); ~EventQueue() = default;
void push(Event &&event);
// 从队列取出事件 // 添加事件到队列
bool poll(Event &event); bool push(const Event &event);
bool push(Event &&event);
// 查看队列头部事件(不移除) // 从队列取出事件
bool peek(Event &event) const; bool poll(Event &event);
// 清空队列 // 查看队列头部事件(不移除)
void clear(); bool peek(Event &event) const;
// 队列状态 // 清空队列
bool empty() const; void clear();
size_t size() const;
// 队列状态
bool empty() const;
size_t size() const;
size_t capacity() const { return buffer_.capacity(); }
private: private:
std::queue<Event> queue_; RingBuffer<Event, DEFAULT_CAPACITY> buffer_;
mutable std::mutex mutex_; mutable std::mutex mutex_; // 用于peek和clear的互斥
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -26,9 +26,9 @@ enum class Cursor {
*/ */
class GLFWWindow { class GLFWWindow {
public: public:
using ResizeCb = std::function<void(int, int)>; using ResizeFn = std::function<void(int, int)>;
using CloseCb = std::function<void()>; using CloseFn = std::function<void()>;
using FocusCb = std::function<void(bool)>; using FocusFn = std::function<void(bool)>;
GLFWWindow(); GLFWWindow();
~GLFWWindow(); ~GLFWWindow();
@ -36,12 +36,12 @@ public:
/** /**
* @brief * @brief
* @param title * @param title
* @param width * @param w
* @param height * @param h
* @param vsync * @param vsync
* @return * @return
*/ */
bool create(const std::string& title, int width, int height, bool vsync = true); bool create(const std::string& title, int w, int h, bool vsync = true);
/** /**
* @brief * @brief
@ -71,42 +71,42 @@ public:
/** /**
* @brief * @brief
*/ */
void setTitle(const std::string& title); void title(const std::string& t);
/** /**
* @brief * @brief
*/ */
void setSize(int w, int h); void size(int w, int h);
/** /**
* @brief * @brief
*/ */
void setPos(int x, int y); void pos(int x, int y);
/** /**
* @brief * @brief
*/ */
void setFullscreen(bool fs); void fullscreen(bool fs);
/** /**
* @brief * @brief
*/ */
void setVSync(bool vsync); void vsync(bool v);
/** /**
* @brief * @brief
*/ */
void setVisible(bool visible); void visible(bool v);
/** /**
* @brief * @brief
*/ */
int width() const { return width_; } int w() const { return w_; }
/** /**
* @brief * @brief
*/ */
int height() const { return height_; } int h() const { return h_; }
/** /**
* @brief * @brief
@ -141,17 +141,17 @@ public:
/** /**
* @brief X * @brief X
*/ */
float scaleX() const { return scaleX_; } f32 scaleX() const { return scaleX_; }
/** /**
* @brief Y * @brief Y
*/ */
float scaleY() const { return scaleY_; } f32 scaleY() const { return scaleY_; }
/** /**
* @brief * @brief
*/ */
void setCursor(Cursor cursor); void cursor(Cursor c);
/** /**
* @brief / * @brief /
@ -166,17 +166,17 @@ public:
/** /**
* @brief * @brief
*/ */
void onResize(ResizeCb cb) { resizeCb_ = cb; } void onResize(ResizeFn fn) { resizeFn_ = fn; }
/** /**
* @brief * @brief
*/ */
void onClose(CloseCb cb) { closeCb_ = cb; } void onClose(CloseFn fn) { closeFn_ = fn; }
/** /**
* @brief * @brief
*/ */
void onFocus(FocusCb cb) { focusCb_ = cb; } void onFocus(FocusFn fn) { focusFn_ = fn; }
/** /**
* @brief * @brief
@ -186,7 +186,7 @@ public:
/** /**
* @brief GLFW * @brief GLFW
*/ */
GLFWwindow* glfwWindow() const { return glfwWindow_; } GLFWwindow* handle() const { return handle_; }
private: private:
bool initGLFW(); bool initGLFW();
@ -194,33 +194,33 @@ private:
void updateContentScale(); void updateContentScale();
// GLFW 回调函数(静态) // GLFW 回调函数(静态)
static void framebufferSizeCallback(GLFWwindow* window, int width, int height); static void framebufferSizeCallback(GLFWwindow* window, int w, int h);
static void windowCloseCallback(GLFWwindow* window); static void windowCloseCallback(GLFWwindow* window);
static void windowFocusCallback(GLFWwindow* window, int focused); static void windowFocusCallback(GLFWwindow* window, int focused);
static void windowIconifyCallback(GLFWwindow* window, int iconified); static void windowIconifyCallback(GLFWwindow* window, int iconified);
static void cursorPosCallback(GLFWwindow* window, double xpos, double ypos); static void cursorPosCallback(GLFWwindow* window, double x, double y);
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); static void mouseButtonCallback(GLFWwindow* window, int btn, int action, int mods);
static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset); static void scrollCallback(GLFWwindow* window, double x, double y);
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void joystickCallback(int jid, int event); static void joystickCallback(int jid, int event);
GLFWwindow* glfwWindow_ = nullptr; GLFWwindow* handle_ = nullptr;
int width_ = 1280; int w_ = 1280;
int height_ = 720; int h_ = 720;
bool fullscreen_ = false; bool fullscreen_ = false;
bool vsync_ = true; bool vsync_ = true;
bool focused_ = true; bool focused_ = true;
bool minimized_ = false; bool minimized_ = false;
bool shouldClose_ = false; bool shouldClose_ = false;
float scaleX_ = 1.0f; f32 scaleX_ = 1.0f;
float scaleY_ = 1.0f; f32 scaleY_ = 1.0f;
bool cursorVisible_ = true; bool cursorVisible_ = true;
bool cursorLocked_ = false; bool cursorLocked_ = false;
ResizeCb resizeCb_; ResizeFn resizeFn_;
CloseCb closeCb_; CloseFn closeFn_;
FocusCb focusCb_; FocusFn focusFn_;
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -52,7 +52,7 @@ public:
private: private:
WindowCfg cfg_; WindowCfg cfg_;
UniquePtr<GLFWWindow> win_; Unique<GLFWWindow> win_;
bool initialized_ = false; bool initialized_ = false;
}; };

View File

@ -14,21 +14,21 @@ class IEventService : public IService {
public: public:
virtual ~IEventService() = default; virtual ~IEventService() = default;
virtual void pushEvent(const Event& event) = 0; virtual void push(const Event& event) = 0;
virtual void pushEvent(Event&& event) = 0; virtual void push(Event&& event) = 0;
virtual bool pollEvent(Event& event) = 0; virtual bool poll(Event& event) = 0;
virtual ListenerId addListener(EventType type, EventDispatcher::EventCallback callback) = 0; virtual ListenerID on(EventType type, EventDispatcher::EventFn fn) = 0;
virtual void removeListener(ListenerId id) = 0; virtual void off(ListenerID id) = 0;
virtual void removeAllListeners(EventType type) = 0; virtual void offAll(EventType type) = 0;
virtual void removeAllListeners() = 0; virtual void offAll() = 0;
virtual void dispatch(Event& event) = 0; virtual void dispatch(Event& event) = 0;
virtual void processQueue() = 0; virtual void process() = 0;
virtual size_t getListenerCount(EventType type) const = 0; virtual size_t listenerCount(EventType type) const = 0;
virtual size_t getTotalListenerCount() const = 0; virtual size_t totalListeners() const = 0;
virtual size_t getQueueSize() const = 0; virtual size_t queueSize() const = 0;
}; };
/** /**
@ -39,32 +39,32 @@ public:
EventService(); EventService();
~EventService() override = default; ~EventService() override = default;
ServiceInfo getServiceInfo() const override; ServiceInfo info() const override;
bool initialize() override; bool init() override;
void shutdown() override; void shutdown() override;
void update(float deltaTime) override; void update(f32 dt) override;
void pushEvent(const Event& event) override; void push(const Event& event) override;
void pushEvent(Event&& event) override; void push(Event&& event) override;
bool pollEvent(Event& event) override; bool poll(Event& event) override;
ListenerId addListener(EventType type, EventDispatcher::EventCallback callback) override; ListenerID on(EventType type, EventDispatcher::EventFn fn) override;
void removeListener(ListenerId id) override; void off(ListenerID id) override;
void removeAllListeners(EventType type) override; void offAll(EventType type) override;
void removeAllListeners() override; void offAll() override;
void dispatch(Event& event) override; void dispatch(Event& event) override;
void processQueue() override; void process() override;
size_t getListenerCount(EventType type) const override; size_t listenerCount(EventType type) const override;
size_t getTotalListenerCount() const override; size_t totalListeners() const override;
size_t getQueueSize() const override; size_t queueSize() const override;
EventQueue& getQueue() { return queue_; } EventQueue& queue() { return queue_; }
const EventQueue& getQueue() const { return queue_; } const EventQueue& queue() const { return queue_; }
EventDispatcher& getDispatcher() { return dispatcher_; } EventDispatcher& dispatcher() { return dispatcher_; }
const EventDispatcher& getDispatcher() const { return dispatcher_; } const EventDispatcher& dispatcher() const { return dispatcher_; }
private: private:
EventQueue queue_; EventQueue queue_;

View File

@ -13,10 +13,10 @@ namespace extra2d {
* @brief * @brief
*/ */
struct LogColor { struct LogColor {
uint8_t r, g, b; u8 r, g, b;
constexpr LogColor() : r(255), g(255), b(255) {} constexpr LogColor() : r(255), g(255), b(255) {}
constexpr LogColor(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {} constexpr LogColor(u8 r, u8 g, u8 b) : r(r), g(g), b(b) {}
static constexpr LogColor White() { return LogColor(255, 255, 255); } static constexpr LogColor White() { return LogColor(255, 255, 255); }
static constexpr LogColor Gray() { return LogColor(128, 128, 128); } static constexpr LogColor Gray() { return LogColor(128, 128, 128); }
@ -68,27 +68,27 @@ public:
/** /**
* @brief * @brief
*/ */
virtual void setLevel(LogLevel level) = 0; virtual void level(LogLevel lvl) = 0;
/** /**
* @brief * @brief
*/ */
virtual LogLevel getLevel() const = 0; virtual LogLevel level() const = 0;
/** /**
* @brief * @brief
*/ */
virtual bool isEnabled(LogLevel level) const = 0; virtual bool enabled(LogLevel lvl) const = 0;
/** /**
* @brief * @brief
*/ */
virtual void log(LogLevel level, const char *fmt, ...) = 0; virtual void log(LogLevel lvl, const char *fmt, ...) = 0;
/** /**
* @brief * @brief
*/ */
virtual void log(LogLevel level, const std::string &msg) = 0; virtual void log(LogLevel lvl, const std::string &msg) = 0;
/** /**
* @brief Trace级别日志 * @brief Trace级别日志
@ -127,35 +127,35 @@ public:
/** /**
* @brief * @brief
* @param level * @param lvl
* @param color * @param c
*/ */
virtual void setLevelColor(LogLevel level, const LogColor &color) = 0; virtual void levelColor(LogLevel lvl, const LogColor &c) = 0;
/** /**
* @brief * @brief
* @param level * @param lvl
* @return * @return
*/ */
virtual LogColor getLevelColor(LogLevel level) const = 0; virtual LogColor levelColor(LogLevel lvl) const = 0;
/** /**
* @brief / * @brief /
* @param enabled * @param on
*/ */
virtual void setColorEnabled(bool enabled) = 0; virtual void colors(bool on) = 0;
/** /**
* @brief * @brief
*/ */
virtual bool isColorEnabled() const = 0; virtual bool colors() const = 0;
ServiceInfo getServiceInfo() const override { ServiceInfo info() const override {
ServiceInfo info; ServiceInfo i;
info.name = "Logger"; i.name = "Logger";
info.priority = ServicePriority::Core; i.priority = ServicePriority::Core;
info.enabled = true; i.enabled = true;
return info; return i;
} }
}; };
@ -167,15 +167,15 @@ public:
ConsoleLogger(); ConsoleLogger();
~ConsoleLogger() override; ~ConsoleLogger() override;
bool initialize() override; bool init() override;
void shutdown() override; void shutdown() override;
void setLevel(LogLevel level) override; void level(LogLevel lvl) override;
LogLevel getLevel() const override; LogLevel level() const override;
bool isEnabled(LogLevel level) const override; bool enabled(LogLevel lvl) const override;
void log(LogLevel level, const char *fmt, ...) override; void log(LogLevel lvl, const char *fmt, ...) override;
void log(LogLevel level, const std::string &msg) override; void log(LogLevel lvl, const std::string &msg) override;
void trace(const char *fmt, ...) override; void trace(const char *fmt, ...) override;
void debug(const char *fmt, ...) override; void debug(const char *fmt, ...) override;
@ -185,21 +185,21 @@ public:
void error(const char *fmt, ...) override; void error(const char *fmt, ...) override;
void fatal(const char *fmt, ...) override; void fatal(const char *fmt, ...) override;
void setLevelColor(LogLevel level, const LogColor &color) override; void levelColor(LogLevel lvl, const LogColor &c) override;
LogColor getLevelColor(LogLevel level) const override; LogColor levelColor(LogLevel lvl) const override;
void setColorEnabled(bool enabled) override; void colors(bool on) override;
bool isColorEnabled() const override; bool colors() const override;
private: private:
void output(LogLevel level, const char *msg); void output(LogLevel lvl, const char *msg);
const char *getLevelString(LogLevel level); const char *levelString(LogLevel lvl);
std::string getAnsiColor(LogLevel level); std::string ansiColor(LogLevel lvl);
LogLevel level_; LogLevel level_;
bool colorEnabled_; bool colors_;
LogColor levelColors_[7]; LogColor levelColors_[7];
class Impl; class Impl;
UniquePtr<Impl> impl_; Unique<Impl> impl_;
// 服务注册元数据 // 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(ILogger, ConsoleLogger); E2D_AUTO_REGISTER_SERVICE(ILogger, ConsoleLogger);
@ -262,12 +262,12 @@ std::string format_str(const char *fmt, Args &&...args) {
} // namespace extra2d } // namespace extra2d
// 便捷宏 - 自动获取日志服务 // 便捷宏 - 自动获取日志服务
#define E2D_LOG(level, ...) \ #define E2D_LOG(lvl, ...) \
do { \ do { \
if (auto logService = ::extra2d::ServiceLocator::instance() \ if (auto logService = ::extra2d::ServiceLocator::instance() \
.tryGetService<::extra2d::ILogger>()) { \ .tryGet<::extra2d::ILogger>()) { \
if (logService->isEnabled(level)) { \ if (logService->enabled(lvl)) { \
logService->log(level, ::extra2d::format_str(__VA_ARGS__)); \ logService->log(lvl, ::extra2d::format_str(__VA_ARGS__)); \
} \ } \
} \ } \
} while (0) } while (0)
@ -281,30 +281,30 @@ std::string format_str(const char *fmt, Args &&...args) {
#define E2D_FATAL(...) E2D_LOG(::extra2d::LogLevel::Fatal, __VA_ARGS__) #define E2D_FATAL(...) E2D_LOG(::extra2d::LogLevel::Fatal, __VA_ARGS__)
// 带颜色参数的日志宏 // 带颜色参数的日志宏
#define E2D_LOG_COLOR(level, color, ...) \ #define E2D_LOG_COLOR(lvl, c, ...) \
do { \ do { \
if (auto logService = ::extra2d::ServiceLocator::instance() \ if (auto logService = ::extra2d::ServiceLocator::instance() \
.tryGetService<::extra2d::ILogger>()) { \ .tryGet<::extra2d::ILogger>()) { \
if (logService->isEnabled(level)) { \ if (logService->enabled(lvl)) { \
auto prevColor = logService->getLevelColor(level); \ auto prevColor = logService->levelColor(lvl); \
logService->setLevelColor(level, color); \ logService->levelColor(lvl, c); \
logService->log(level, ::extra2d::format_str(__VA_ARGS__)); \ logService->log(lvl, ::extra2d::format_str(__VA_ARGS__)); \
logService->setLevelColor(level, prevColor); \ logService->levelColor(lvl, prevColor); \
} \ } \
} \ } \
} while (0) } while (0)
#define E2D_TRACE_COLOR(color, ...) \ #define E2D_TRACE_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Trace, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Trace, c, __VA_ARGS__)
#define E2D_DEBUG_COLOR(color, ...) \ #define E2D_DEBUG_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Debug, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Debug, c, __VA_ARGS__)
#define E2D_INFO_COLOR(color, ...) \ #define E2D_INFO_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Info, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Info, c, __VA_ARGS__)
#define E2D_REGISTRY_COLOR(color, ...) \ #define E2D_REGISTRY_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Registry, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Registry, c, __VA_ARGS__)
#define E2D_WARN_COLOR(color, ...) \ #define E2D_WARN_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Warn, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Warn, c, __VA_ARGS__)
#define E2D_ERROR_COLOR(color, ...) \ #define E2D_ERROR_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Error, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Error, c, __VA_ARGS__)
#define E2D_FATAL_COLOR(color, ...) \ #define E2D_FATAL_COLOR(c, ...) \
E2D_LOG_COLOR(::extra2d::LogLevel::Fatal, color, __VA_ARGS__) E2D_LOG_COLOR(::extra2d::LogLevel::Fatal, c, __VA_ARGS__)

View File

@ -13,13 +13,13 @@ class ITimerService : public IService {
public: public:
virtual ~ITimerService() = default; virtual ~ITimerService() = default;
virtual uint32 addTimer(float delay, Timer::Callback callback) = 0; virtual u32 add(f32 delay, Timer::Fn fn) = 0;
virtual uint32 addRepeatingTimer(float interval, Timer::Callback callback) = 0; virtual u32 addRepeat(f32 interval, Timer::Fn fn) = 0;
virtual void cancelTimer(uint32 timerId) = 0; virtual void cancel(u32 timerId) = 0;
virtual void pauseTimer(uint32 timerId) = 0; virtual void pauseTimer(u32 timerId) = 0;
virtual void resumeTimer(uint32 timerId) = 0; virtual void resumeTimer(u32 timerId) = 0;
virtual void clear() = 0; virtual void clear() = 0;
virtual size_t getTimerCount() const = 0; virtual size_t count() const = 0;
}; };
/** /**
@ -30,25 +30,25 @@ public:
TimerService(); TimerService();
~TimerService() override = default; ~TimerService() override = default;
ServiceInfo getServiceInfo() const override; ServiceInfo info() const override;
bool initialize() override; bool init() override;
void shutdown() override; void shutdown() override;
void update(float deltaTime) override; void update(f32 dt) override;
uint32 addTimer(float delay, Timer::Callback callback) override; u32 add(f32 delay, Timer::Fn fn) override;
uint32 addRepeatingTimer(float interval, Timer::Callback callback) override; u32 addRepeat(f32 interval, Timer::Fn fn) override;
void cancelTimer(uint32 timerId) override; void cancel(u32 timerId) override;
void pauseTimer(uint32 timerId) override; void pauseTimer(u32 timerId) override;
void resumeTimer(uint32 timerId) override; void resumeTimer(u32 timerId) override;
void clear() override; void clear() override;
size_t getTimerCount() const override; size_t count() const override;
TimerManager& getManager() { return manager_; } TimerManager& mgr() { return mgr_; }
const TimerManager& getManager() const { return manager_; } const TimerManager& mgr() const { return mgr_; }
private: private:
TimerManager manager_; TimerManager mgr_;
// 服务注册元数据 // 服务注册元数据
E2D_AUTO_REGISTER_SERVICE(ITimerService, TimerService); E2D_AUTO_REGISTER_SERVICE(ITimerService, TimerService);

View File

@ -14,34 +14,34 @@ public:
static Random &get(); static Random &get();
/// 设置随机种子 /// 设置随机种子
void setSeed(uint32 seed); void seed(u32 s);
/// 使用当前时间作为种子 /// 使用当前时间作为种子
void randomize(); void randomize();
/// 获取 [0, 1) 范围内的随机浮点数 /// 获取 [0, 1) 范围内的随机浮点数
float getFloat(); f32 randomF32();
/// 获取 [min, max] 范围内的随机浮点数 /// 获取 [min, max] 范围内的随机浮点数
float getFloat(float min, float max); f32 randomF32(f32 min, f32 max);
/// 获取 [0, max] 范围内的随机整数 /// 获取 [0, max] 范围内的随机整数
int getInt(int max); i32 randomI32(i32 max);
/// 获取 [min, max] 范围内的随机整数 /// 获取 [min, max] 范围内的随机整数
int getInt(int min, int max); i32 randomI32(i32 min, i32 max);
/// 获取随机布尔值 /// 获取随机布尔值
bool getBool(); bool boolean();
/// 获取随机布尔值(带概率) /// 获取随机布尔值(带概率)
bool getBool(float probability); bool boolean(f32 probability);
/// 获取指定范围内的随机角度(弧度) /// 获取指定范围内的随机角度(弧度)
float getAngle(); f32 angle();
/// 获取 [-1, 1] 范围内的随机数(用于方向) /// 获取 [-1, 1] 范围内的随机数(用于方向)
float getSigned(); f32 signedF32();
private: private:
Random(); Random();
@ -59,27 +59,27 @@ private:
// ============================================================================ // ============================================================================
/// 获取 [0, 1) 范围内的随机浮点数 /// 获取 [0, 1) 范围内的随机浮点数
inline float randomFloat() { return Random::get().getFloat(); } inline f32 randF32() { return Random::get().randomF32(); }
/// 获取 [min, max] 范围内的随机浮点数 /// 获取 [min, max] 范围内的随机浮点数
inline float randomFloat(float min, float max) { inline f32 randF32(f32 min, f32 max) {
return Random::get().getFloat(min, max); return Random::get().randomF32(min, max);
} }
/// 获取 [0, max] 范围内的随机整数 /// 获取 [0, max] 范围内的随机整数
inline int randomInt(int max) { return Random::get().getInt(max); } inline i32 randI32(i32 max) { return Random::get().randomI32(max); }
/// 获取 [min, max] 范围内的随机整数 /// 获取 [min, max] 范围内的随机整数
inline int randomInt(int min, int max) { inline i32 randI32(i32 min, i32 max) {
return Random::get().getInt(min, max); return Random::get().randomI32(min, max);
} }
/// 获取随机布尔值 /// 获取随机布尔值
inline bool randomBool() { return Random::get().getBool(); } inline bool randBool() { return Random::get().boolean(); }
/// 获取随机布尔值(带概率) /// 获取随机布尔值(带概率)
inline bool randomBool(float probability) { inline bool randBool(f32 probability) {
return Random::get().getBool(probability); return Random::get().boolean(probability);
} }
} // namespace extra2d } // namespace extra2d

View File

@ -16,12 +16,12 @@ public:
using Clock = std::chrono::steady_clock; using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point; using TimePoint = Clock::time_point;
using Duration = Clock::duration; using Duration = Clock::duration;
using Callback = Function<void()>; using Fn = std::function<void()>;
Timer(float interval, bool repeat, Callback callback); Timer(f32 interval, bool repeat, Fn fn);
/// 更新计时器,返回 true 如果触发了回调 /// 更新计时器,返回 true 如果触发了回调
bool update(float deltaTime); bool update(f32 dt);
/// 重置计时器 /// 重置计时器
void reset(); void reset();
@ -36,27 +36,27 @@ public:
void cancel(); void cancel();
/// 是否有效 /// 是否有效
bool isValid() const { return valid_; } bool valid() const { return valid_; }
/// 是否暂停 /// 是否暂停
bool isPaused() const { return paused_; } bool paused() const { return paused_; }
/// 获取剩余时间(秒) /// 获取剩余时间(秒)
float getRemaining() const; f32 remaining() const;
/// 获取唯一ID /// 获取唯一ID
uint32 getId() const { return id_; } u32 id() const { return id_; }
private: private:
uint32 id_; u32 id_;
float interval_; f32 interval_;
float elapsed_; f32 elapsed_;
bool repeat_; bool repeat_;
bool paused_; bool paused_;
bool valid_; bool valid_;
Callback callback_; Fn fn_;
static uint32 nextId_; static u32 nextId_;
}; };
// ============================================================================ // ============================================================================
@ -68,32 +68,32 @@ public:
~TimerManager() = default; ~TimerManager() = default;
/// 创建单次计时器返回计时器ID /// 创建单次计时器返回计时器ID
uint32 addTimer(float delay, Timer::Callback callback); u32 add(f32 delay, Timer::Fn fn);
/// 创建重复计时器返回计时器ID /// 创建重复计时器返回计时器ID
uint32 addRepeatingTimer(float interval, Timer::Callback callback); u32 addRepeat(f32 interval, Timer::Fn fn);
/// 取消指定ID的计时器 /// 取消指定ID的计时器
void cancelTimer(uint32 timerId); void cancel(u32 timerId);
/// 暂停指定ID的计时器 /// 暂停指定ID的计时器
void pauseTimer(uint32 timerId); void pause(u32 timerId);
/// 恢复指定ID的计时器 /// 恢复指定ID的计时器
void resumeTimer(uint32 timerId); void resume(u32 timerId);
/// 更新所有计时器(每帧调用) /// 更新所有计时器(每帧调用)
void update(float deltaTime); void update(f32 dt);
/// 清除所有计时器 /// 清除所有计时器
void clear(); void clear();
/// 获取计时器数量 /// 获取计时器数量
size_t getTimerCount() const { return timers_.size(); } size_t count() const { return timers_.size(); }
private: private:
std::map<uint32, std::unique_ptr<Timer>> timers_; std::map<u32, std::unique_ptr<Timer>> timers_;
std::vector<uint32> timersToRemove_; std::vector<u32> timersToRemove_;
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -8,17 +8,17 @@
namespace extra2d { namespace extra2d {
static double getTimeSeconds() { static f64 getTimeSeconds() {
#ifdef __SWITCH__ #ifdef __SWITCH__
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
return static_cast<double>(ts.tv_sec) + return static_cast<f64>(ts.tv_sec) +
static_cast<double>(ts.tv_nsec) / 1000000000.0; static_cast<f64>(ts.tv_nsec) / 1000000000.0;
#else #else
using namespace std::chrono; using namespace std::chrono;
auto now = steady_clock::now(); auto now = steady_clock::now();
auto duration = now.time_since_epoch(); auto duration = now.time_since_epoch();
return duration_cast<std::chrono::duration<double>>(duration).count(); return duration_cast<std::chrono::duration<f64>>(duration).count();
#endif #endif
} }
@ -47,7 +47,7 @@ bool Application::init() {
} }
// 初始化所有服务 // 初始化所有服务
ServiceLocator::instance().initializeAll(); ServiceLocator::instance().init();
initialized_ = true; initialized_ = true;
running_ = true; running_ = true;
@ -58,7 +58,7 @@ void Application::shutdown() {
if (!initialized_) if (!initialized_)
return; return;
ServiceLocator::instance().shutdownAll(); ServiceLocator::instance().shutdown();
ServiceLocator::instance().clear(); ServiceLocator::instance().clear();
Registry::instance().shutdown(); Registry::instance().shutdown();
Registry::instance().clear(); Registry::instance().clear();
@ -90,29 +90,29 @@ void Application::quit() {
void Application::pause() { void Application::pause() {
if (!paused_) { if (!paused_) {
paused_ = true; paused_ = true;
ServiceLocator::instance().pauseAll(); ServiceLocator::instance().pause();
} }
} }
void Application::resume() { void Application::resume() {
if (paused_) { if (paused_) {
paused_ = false; paused_ = false;
ServiceLocator::instance().resumeAll(); ServiceLocator::instance().resume();
lastFrameTime_ = getTimeSeconds(); lastFrameTime_ = getTimeSeconds();
} }
} }
void Application::mainLoop() { void Application::mainLoop() {
double currentTime = getTimeSeconds(); f64 currentTime = getTimeSeconds();
deltaTime_ = static_cast<float>(currentTime - lastFrameTime_); dt_ = static_cast<f32>(currentTime - lastFrameTime_);
lastFrameTime_ = currentTime; lastFrameTime_ = currentTime;
totalTime_ += deltaTime_; totalTime_ += dt_;
frameCount_++; frameCount_++;
fpsTimer_ += deltaTime_; fpsTimer_ += dt_;
if (fpsTimer_ >= 1.0f) { if (fpsTimer_ >= 1.0f) {
currentFps_ = frameCount_; fps_ = frameCount_;
frameCount_ = 0; frameCount_ = 0;
fpsTimer_ -= 1.0f; fpsTimer_ -= 1.0f;
} }
@ -122,9 +122,9 @@ void Application::mainLoop() {
winMod->win()->poll(); winMod->win()->poll();
} }
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
eventService->processQueue(); eventService->process();
} }
if (!paused_) { if (!paused_) {
@ -134,7 +134,7 @@ void Application::mainLoop() {
render(); render();
} }
void Application::update() { ServiceLocator::instance().updateAll(deltaTime_); } void Application::update() { ServiceLocator::instance().update(dt_); }
void Application::render() { void Application::render() {
auto *winMod = get<WindowModule>(); auto *winMod = get<WindowModule>();

View File

@ -11,8 +11,8 @@ Registry &Registry::instance() {
} }
bool Registry::init() { bool Registry::init() {
auto levels = groupByLevel(); auto levels = group();
E2D_REGISTRY("正在初始化 {} 个模块,共 {} 个层级...", modules_.size(), E2D_REGISTRY("正在初始化 {} 个模块,共 {} 个层级...", moduleCount_,
levels.size()); levels.size());
for (size_t level = 0; level < levels.size(); ++level) { for (size_t level = 0; level < levels.size(); ++level) {
@ -21,7 +21,7 @@ bool Registry::init() {
// 检查当前层级是否有支持并行初始化的模块 // 检查当前层级是否有支持并行初始化的模块
bool hasParallelModules = false; bool hasParallelModules = false;
for (auto *module : modules) { for (auto *module : modules) {
if (module->allowParallelInit()) { if (module->parallel()) {
hasParallelModules = true; hasParallelModules = true;
break; break;
} }
@ -49,7 +49,7 @@ bool Registry::init() {
// 分离支持并行和不支持并行的模块 // 分离支持并行和不支持并行的模块
for (auto *module : modules) { for (auto *module : modules) {
if (module->allowParallelInit()) { if (module->parallel()) {
futures.push_back(std::async(std::launch::async, [module]() { futures.push_back(std::async(std::launch::async, [module]() {
return std::make_pair(module, module->init()); return std::make_pair(module, module->init());
})); }));
@ -88,52 +88,67 @@ bool Registry::init() {
} }
void Registry::shutdown() { void Registry::shutdown() {
auto sorted = topologicalSort(); // 从后向前关闭模块
for (size_t i = moduleCount_; i > 0; --i) {
for (auto it = sorted.rbegin(); it != sorted.rend(); ++it) { if (modules_[i - 1].valid && modules_[i - 1].module) {
(*it)->shutdown(); modules_[i - 1].module->shutdown();
}
} }
} }
void Registry::clear() { void Registry::clear() {
shutdown(); shutdown();
modules_.clear();
// 销毁所有模块
for (size_t i = 0; i < moduleCount_; ++i) {
modules_[i].module.reset();
modules_[i].valid = false;
}
moduleCount_ = 0;
} }
std::vector<Module *> Registry::topologicalSort() { std::vector<Module *> Registry::sort() {
std::vector<Module *> result; std::vector<Module *> result;
std::unordered_map<Module *, int> inDegree; std::vector<int> inDegree(moduleCount_, 0);
std::unordered_map<Module *, std::vector<Module *>> adj; std::vector<std::vector<size_t>> adj(moduleCount_);
for (auto &[typeIdx, module] : modules_) { // 构建依赖图
inDegree[module.get()] = 0; for (size_t i = 0; i < moduleCount_; ++i) {
} if (!modules_[i].valid)
continue;
for (auto &[typeIdx, module] : modules_) {
for (auto &depType : module->deps()) { auto deps = modules_[i].module->deps();
Module *dep = get(depType); for (auto &depType : deps) {
if (dep) { // 查找依赖模块的索引
adj[dep].push_back(module.get()); for (size_t j = 0; j < moduleCount_; ++j) {
inDegree[module.get()]++; if (modules_[j].valid &&
std::type_index(typeid(*modules_[j].module)) == depType) {
adj[j].push_back(i);
inDegree[i]++;
break;
}
} }
} }
} }
auto cmp = [](Module *a, Module *b) { return a->priority() > b->priority(); }; // 使用优先队列,按优先级排序
std::priority_queue<Module *, std::vector<Module *>, decltype(cmp)> pq(cmp); auto cmp = [this](size_t a, size_t b) {
return modules_[a].module->priority() > modules_[b].module->priority();
};
std::priority_queue<size_t, std::vector<size_t>, decltype(cmp)> pq(cmp);
for (auto &[mod, degree] : inDegree) { for (size_t i = 0; i < moduleCount_; ++i) {
if (degree == 0) { if (inDegree[i] == 0) {
pq.push(mod); pq.push(i);
} }
} }
while (!pq.empty()) { while (!pq.empty()) {
Module *curr = pq.top(); size_t curr = pq.top();
pq.pop(); pq.pop();
result.push_back(curr); result.push_back(modules_[curr].module.get());
for (Module *next : adj[curr]) { for (size_t next : adj[curr]) {
inDegree[next]--; inDegree[next]--;
if (inDegree[next] == 0) { if (inDegree[next] == 0) {
pq.push(next); pq.push(next);
@ -144,42 +159,44 @@ std::vector<Module *> Registry::topologicalSort() {
return result; return result;
} }
std::vector<std::vector<Module *>> Registry::groupByLevel() { std::vector<std::vector<Module *>> Registry::group() {
std::vector<std::vector<Module *>> levels; std::vector<std::vector<Module *>> levels;
std::unordered_map<Module *, int> inDegree; std::vector<int> inDegree(moduleCount_, 0);
std::unordered_map<Module *, std::vector<Module *>> adj; std::vector<std::vector<size_t>> adj(moduleCount_);
std::unordered_map<Module *, int> levelMap;
// 初始化入度
for (auto &[typeIdx, module] : modules_) {
inDegree[module.get()] = 0;
}
// 构建依赖图 // 构建依赖图
for (auto &[typeIdx, module] : modules_) { for (size_t i = 0; i < moduleCount_; ++i) {
for (auto &depType : module->deps()) { if (!modules_[i].valid)
Module *dep = get(depType); continue;
if (dep) {
adj[dep].push_back(module.get()); auto deps = modules_[i].module->deps();
inDegree[module.get()]++; for (auto &depType : deps) {
for (size_t j = 0; j < moduleCount_; ++j) {
if (modules_[j].valid &&
std::type_index(typeid(*modules_[j].module)) == depType) {
adj[j].push_back(i);
inDegree[i]++;
break;
}
} }
} }
} }
// 使用 BFS 按层级分组 // 使用 BFS 按层级分组
std::queue<Module *> q; std::queue<size_t> q;
std::vector<int> levelMap(moduleCount_, -1);
// 找到所有入度为 0 的模块(第一层) // 找到所有入度为 0 的模块(第一层)
for (auto &[mod, degree] : inDegree) { for (size_t i = 0; i < moduleCount_; ++i) {
if (degree == 0) { if (inDegree[i] == 0) {
q.push(mod); q.push(i);
levelMap[mod] = 0; levelMap[i] = 0;
} }
} }
// BFS 遍历 // BFS 遍历
while (!q.empty()) { while (!q.empty()) {
Module *curr = q.front(); size_t curr = q.front();
q.pop(); q.pop();
int currLevel = levelMap[curr]; int currLevel = levelMap[curr];
@ -188,10 +205,10 @@ std::vector<std::vector<Module *>> Registry::groupByLevel() {
if (levels.size() <= static_cast<size_t>(currLevel)) { if (levels.size() <= static_cast<size_t>(currLevel)) {
levels.resize(currLevel + 1); levels.resize(currLevel + 1);
} }
levels[currLevel].push_back(curr); levels[currLevel].push_back(modules_[curr].module.get());
// 处理依赖当前模块的其他模块 // 处理依赖当前模块的其他模块
for (Module *next : adj[curr]) { for (size_t next : adj[curr]) {
inDegree[next]--; inDegree[next]--;
if (inDegree[next] == 0) { if (inDegree[next] == 0) {
q.push(next); q.push(next);

View File

@ -8,34 +8,34 @@ ServiceLocator& ServiceLocator::instance() {
return instance; return instance;
} }
bool ServiceLocator::initializeAll() { bool ServiceLocator::init() {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& svc : orderedServices_) {
if (!service) continue; if (!svc) continue;
auto info = service->getServiceInfo(); auto info = svc->info();
if (!info.enabled) continue; if (!info.enabled) continue;
if (!service->isInitialized()) { if (!svc->initialized()) {
service->setState(ServiceState::Initializing); svc->setState(ServiceState::Initializing);
if (!service->initialize()) { if (!svc->init()) {
service->setState(ServiceState::Stopped); svc->setState(ServiceState::Stopped);
return false; return false;
} }
service->setState(ServiceState::Running); svc->setState(ServiceState::Running);
} }
} }
return true; return true;
} }
void ServiceLocator::shutdownAll() { void ServiceLocator::shutdown() {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
for (auto it = orderedServices_.rbegin(); for (auto it = orderedServices_.rbegin();
it != orderedServices_.rend(); ++it) { it != orderedServices_.rend(); ++it) {
if (*it && (*it)->isInitialized()) { if (*it && (*it)->initialized()) {
(*it)->setState(ServiceState::Stopping); (*it)->setState(ServiceState::Stopping);
(*it)->shutdown(); (*it)->shutdown();
(*it)->setState(ServiceState::Stopped); (*it)->setState(ServiceState::Stopped);
@ -43,50 +43,50 @@ void ServiceLocator::shutdownAll() {
} }
} }
void ServiceLocator::updateAll(float deltaTime) { void ServiceLocator::update(f32 dt) {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& svc : orderedServices_) {
if (service && service->isInitialized()) { if (svc && svc->initialized()) {
auto state = service->getState(); auto state = svc->state();
if (state == ServiceState::Running) { if (state == ServiceState::Running) {
service->update(deltaTime); svc->update(dt);
} }
} }
} }
} }
void ServiceLocator::pauseAll() { void ServiceLocator::pause() {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& svc : orderedServices_) {
if (service && service->isInitialized()) { if (svc && svc->initialized()) {
service->pause(); svc->pause();
} }
} }
} }
void ServiceLocator::resumeAll() { void ServiceLocator::resume() {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
for (auto& service : orderedServices_) { for (auto& svc : orderedServices_) {
if (service && service->isInitialized()) { if (svc && svc->initialized()) {
service->resume(); svc->resume();
} }
} }
} }
std::vector<SharedPtr<IService>> ServiceLocator::getAllServices() const { std::vector<Ref<IService>> ServiceLocator::all() const {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::shared_lock<std::shared_mutex> lock(mutex_);
return orderedServices_; return orderedServices_;
} }
void ServiceLocator::clear() { void ServiceLocator::clear() {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::unique_lock<std::shared_mutex> lock(mutex_);
for (auto it = orderedServices_.rbegin(); for (auto it = orderedServices_.rbegin();
it != orderedServices_.rend(); ++it) { it != orderedServices_.rend(); ++it) {
if (*it && (*it)->isInitialized()) { if (*it && (*it)->initialized()) {
(*it)->setState(ServiceState::Stopping); (*it)->setState(ServiceState::Stopping);
(*it)->shutdown(); (*it)->shutdown();
(*it)->setState(ServiceState::Stopped); (*it)->setState(ServiceState::Stopped);
@ -98,12 +98,12 @@ void ServiceLocator::clear() {
orderedServices_.clear(); orderedServices_.clear();
} }
void ServiceLocator::sortServices() { void ServiceLocator::sort() {
std::stable_sort(orderedServices_.begin(), orderedServices_.end(), std::stable_sort(orderedServices_.begin(), orderedServices_.end(),
[](const SharedPtr<IService>& a, const SharedPtr<IService>& b) { [](const Ref<IService>& a, const Ref<IService>& b) {
if (!a || !b) return false; if (!a || !b) return false;
return static_cast<int>(a->getServiceInfo().priority) < return static_cast<int>(a->info().priority) <
static_cast<int>(b->getServiceInfo().priority); static_cast<int>(b->info().priority);
}); });
} }

View File

@ -7,7 +7,7 @@ ServiceRegistry& ServiceRegistry::instance() {
return instance; return instance;
} }
void ServiceRegistry::setServiceEnabled(const std::string& name, bool enabled) { void ServiceRegistry::setEnabled(const std::string& name, bool enabled) {
for (auto& reg : registrations_) { for (auto& reg : registrations_) {
if (reg.name == name) { if (reg.name == name) {
reg.enabled = enabled; reg.enabled = enabled;
@ -16,7 +16,7 @@ void ServiceRegistry::setServiceEnabled(const std::string& name, bool enabled) {
} }
} }
void ServiceRegistry::createAllServices() { void ServiceRegistry::createAll() {
std::sort(registrations_.begin(), registrations_.end(), std::sort(registrations_.begin(), registrations_.end(),
[](const ServiceRegistration& a, const ServiceRegistration& b) { [](const ServiceRegistration& a, const ServiceRegistration& b) {
return static_cast<int>(a.priority) < static_cast<int>(b.priority); return static_cast<int>(a.priority) < static_cast<int>(b.priority);
@ -29,7 +29,7 @@ void ServiceRegistry::createAllServices() {
auto service = reg.factory(); auto service = reg.factory();
if (service) { if (service) {
ServiceLocator::instance().registerService<IService>(service); ServiceLocator::instance().add<IService>(service);
} }
} }
} }

View File

@ -2,129 +2,55 @@
namespace extra2d { namespace extra2d {
/** Event Event::windowResize(i32 w, i32 h) {
* @brief
*
* Event对象
*
* @param width
* @param height
* @return Event对象
*/
Event Event::createWindowResize(int width, int height) {
Event event; Event event;
event.type = EventType::WindowResize; event.type = EventType::WindowResize;
event.data = WindowResizeEvent{width, height}; event.data = WindowResizeEvent{w, h};
return event; return event;
} }
/** Event Event::windowClose() {
* @brief
*
* Event对象
*
* @return Event对象
*/
Event Event::createWindowClose() {
Event event; Event event;
event.type = EventType::WindowClose; event.type = EventType::WindowClose;
return event; return event;
} }
/** Event Event::keyPress(i32 key, i32 scancode, i32 mods) {
* @brief
*
* Event对象
*
* @param keyCode
* @param scancode
* @param mods ShiftCtrl等
* @return Event对象
*/
Event Event::createKeyPress(int keyCode, int scancode, int mods) {
Event event; Event event;
event.type = EventType::KeyPressed; event.type = EventType::KeyPressed;
event.data = KeyEvent{keyCode, scancode, mods}; event.data = KeyEvent{key, scancode, mods};
return event; return event;
} }
/** Event Event::keyRelease(i32 key, i32 scancode, i32 mods) {
* @brief
*
* Event对象
*
* @param keyCode
* @param scancode
* @param mods ShiftCtrl等
* @return Event对象
*/
Event Event::createKeyRelease(int keyCode, int scancode, int mods) {
Event event; Event event;
event.type = EventType::KeyReleased; event.type = EventType::KeyReleased;
event.data = KeyEvent{keyCode, scancode, mods}; event.data = KeyEvent{key, scancode, mods};
return event; return event;
} }
/** Event Event::mousePress(i32 btn, i32 mods, Vec2 pos) {
* @brief
*
* Event对象
*
* @param button
* @param mods
* @param pos
* @return Event对象
*/
Event Event::createMouseButtonPress(int button, int mods, const Vec2 &pos) {
Event event; Event event;
event.type = EventType::MouseButtonPressed; event.type = EventType::MouseButtonPressed;
event.data = MouseButtonEvent{button, mods, pos}; event.data = MouseButtonEvent{btn, mods, pos};
return event; return event;
} }
/** Event Event::mouseRelease(i32 btn, i32 mods, Vec2 pos) {
* @brief
*
* Event对象
*
* @param button
* @param mods
* @param pos
* @return Event对象
*/
Event Event::createMouseButtonRelease(int button, int mods, const Vec2 &pos) {
Event event; Event event;
event.type = EventType::MouseButtonReleased; event.type = EventType::MouseButtonReleased;
event.data = MouseButtonEvent{button, mods, pos}; event.data = MouseButtonEvent{btn, mods, pos};
return event; return event;
} }
/** Event Event::mouseMove(Vec2 pos, Vec2 delta) {
* @brief
*
* Event对象
*
* @param pos
* @param delta
* @return Event对象
*/
Event Event::createMouseMove(const Vec2 &pos, const Vec2 &delta) {
Event event; Event event;
event.type = EventType::MouseMoved; event.type = EventType::MouseMoved;
event.data = MouseMoveEvent{pos, delta}; event.data = MouseMoveEvent{pos, delta};
return event; return event;
} }
/** Event Event::mouseScroll(Vec2 offset, Vec2 pos) {
* @brief
*
* Event对象
*
* @param offset
* @param pos
* @return Event对象
*/
Event Event::createMouseScroll(const Vec2 &offset, const Vec2 &pos) {
Event event; Event event;
event.type = EventType::MouseScrolled; event.type = EventType::MouseScrolled;
event.data = MouseScrollEvent{offset, pos}; event.data = MouseScrollEvent{offset, pos};

View File

@ -3,37 +3,15 @@
namespace extra2d { namespace extra2d {
/**
* @brief
*
* ID为1
*/
EventDispatcher::EventDispatcher() : nextId_(1) {} EventDispatcher::EventDispatcher() : nextId_(1) {}
/** ListenerID EventDispatcher::on(EventType type, EventFn fn) {
* @brief ListenerID id = nextId_++;
* listeners_[type].push_back({id, type, fn});
* ID用于后续移除
*
* @param type
* @param callback
* @return ID
*/
ListenerId EventDispatcher::addListener(EventType type,
EventCallback callback) {
ListenerId id = nextId_++;
listeners_[type].push_back({id, type, callback});
return id; return id;
} }
/** void EventDispatcher::off(ListenerID id) {
* @brief
*
* ID移除对应的事件监听器
*
* @param id ID
*/
void EventDispatcher::removeListener(ListenerId id) {
for (auto &[type, listeners] : listeners_) { for (auto &[type, listeners] : listeners_) {
auto it = std::remove_if(listeners.begin(), listeners.end(), auto it = std::remove_if(listeners.begin(), listeners.end(),
[id](const Listener &l) { return l.id == id; }); [id](const Listener &l) { return l.id == id; });
@ -44,89 +22,41 @@ void EventDispatcher::removeListener(ListenerId id) {
} }
} }
/** void EventDispatcher::offAll(EventType type) {
* @brief
*
*
*
* @param type
*/
void EventDispatcher::removeAllListeners(EventType type) {
listeners_.erase(type); listeners_.erase(type);
} }
/** void EventDispatcher::offAll() { listeners_.clear(); }
* @brief
*
*
*/
void EventDispatcher::removeAllListeners() { listeners_.clear(); }
/**
* @brief
*
*
*
* @param event
*/
void EventDispatcher::dispatch(Event &event) { void EventDispatcher::dispatch(Event &event) {
auto it = listeners_.find(event.type); auto it = listeners_.find(event.type);
if (it != listeners_.end()) { if (it != listeners_.end()) {
for (auto &listener : it->second) { for (auto &listener : it->second) {
if (event.handled) if (event.handled)
break; break;
listener.callback(event); listener.fn(event);
} }
} }
} }
/**
* @brief
*
*
*
* @param event
*/
void EventDispatcher::dispatch(const Event &event) { void EventDispatcher::dispatch(const Event &event) {
Event mutableEvent = event; Event mutableEvent = event;
dispatch(mutableEvent); dispatch(mutableEvent);
} }
/** void EventDispatcher::process(EventQueue &queue) {
* @brief
*
*
*
* @param queue
*/
void EventDispatcher::processQueue(EventQueue &queue) {
Event event; Event event;
while (queue.poll(event)) { while (queue.poll(event)) {
dispatch(event); dispatch(event);
} }
} }
/** size_t EventDispatcher::listenerCount(EventType type) const {
* @brief
*
*
*
* @param type
* @return
*/
size_t EventDispatcher::getListenerCount(EventType type) const {
auto it = listeners_.find(type); auto it = listeners_.find(type);
return (it != listeners_.end()) ? it->second.size() : 0; return (it != listeners_.end()) ? it->second.size() : 0;
} }
/** size_t EventDispatcher::totalListeners() const {
* @brief
*
*
*
* @return
*/
size_t EventDispatcher::getTotalListenerCount() const {
size_t count = 0; size_t count = 0;
for (const auto &[type, listeners] : listeners_) { for (const auto &[type, listeners] : listeners_) {
count += listeners.size(); count += listeners.size();

View File

@ -2,106 +2,44 @@
namespace extra2d { namespace extra2d {
/**
* @brief
*
*
*/
EventQueue::EventQueue() = default; EventQueue::EventQueue() = default;
/** bool EventQueue::push(const Event &event) {
* @brief return buffer_.push(event);
*
* 线
*
* @param event
*/
void EventQueue::push(const Event &event) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(event);
} }
/** bool EventQueue::push(Event &&event) {
* @brief return buffer_.push(std::move(event));
*
* 线
*
* @param event
*/
void EventQueue::push(Event &&event) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(std::move(event));
} }
/**
* @brief
*
* 线
*
* @param event
* @return truefalse
*/
bool EventQueue::poll(Event &event) { bool EventQueue::poll(Event &event) {
std::lock_guard<std::mutex> lock(mutex_); return buffer_.pop(event);
if (queue_.empty()) {
return false;
}
event = queue_.front();
queue_.pop();
return true;
} }
/**
* @brief
*
* 线
*
* @param event
* @return truefalse
*/
bool EventQueue::peek(Event &event) const { bool EventQueue::peek(Event &event) const {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
if (queue_.empty()) { if (buffer_.empty()) {
return false;
}
// 环形缓冲区不支持peek这里简化处理
// 实际应用中可能需要双缓冲或其他机制
return false; return false;
}
event = queue_.front();
return true;
} }
/**
* @brief
*
* 线
*/
void EventQueue::clear() { void EventQueue::clear() {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
while (!queue_.empty()) { Event event;
queue_.pop(); while (buffer_.pop(event)) {
} // 持续弹出直到为空
}
} }
/**
* @brief
*
* 线
*
* @return truefalse
*/
bool EventQueue::empty() const { bool EventQueue::empty() const {
std::lock_guard<std::mutex> lock(mutex_); return buffer_.empty();
return queue_.empty();
} }
/**
* @brief
*
* 线
*
* @return
*/
size_t EventQueue::size() const { size_t EventQueue::size() const {
std::lock_guard<std::mutex> lock(mutex_); return buffer_.size();
return queue_.size();
} }
} // namespace extra2d } // namespace extra2d

View File

@ -1,4 +1,4 @@
#include <glfw/glfw_window.h> #include <extra2d/platform/glfw/glfw_window.h>
#include <extra2d/event/event.h> #include <extra2d/event/event.h>
#include <extra2d/platform/keys.h> #include <extra2d/platform/keys.h>
@ -33,10 +33,10 @@ bool GLFWWindow::create(const std::string &title, int width, int height,
monitor = glfwGetPrimaryMonitor(); monitor = glfwGetPrimaryMonitor();
#endif #endif
glfwWindow_ = handle_ =
glfwCreateWindow(width, height, title.c_str(), monitor, nullptr); glfwCreateWindow(width, height, title.c_str(), monitor, nullptr);
if (!glfwWindow_) { if (!handle_) {
E2D_ERROR("创建 GLFW 窗口失败"); E2D_ERROR("创建 GLFW 窗口失败");
deinitGLFW(); deinitGLFW();
return false; return false;
@ -52,87 +52,87 @@ bool GLFWWindow::create(const std::string &title, int width, int height,
int screenHeight = mode->height; int screenHeight = mode->height;
int windowX = (screenWidth - width) / 2; int windowX = (screenWidth - width) / 2;
int windowY = (screenHeight - height) / 2; int windowY = (screenHeight - height) / 2;
glfwSetWindowPos(glfwWindow_, windowX, windowY); glfwSetWindowPos(handle_, windowX, windowY);
} }
} }
} }
#endif #endif
glfwMakeContextCurrent(glfwWindow_); glfwMakeContextCurrent(handle_);
glfwSwapInterval(vsync ? 1 : 0); glfwSwapInterval(vsync ? 1 : 0);
vsync_ = vsync; vsync_ = vsync;
glfwGetWindowSize(glfwWindow_, &width_, &height_); glfwGetWindowSize(handle_, &w_, &h_);
updateContentScale(); updateContentScale();
glfwSetWindowUserPointer(glfwWindow_, this); glfwSetWindowUserPointer(handle_, this);
glfwSetFramebufferSizeCallback(glfwWindow_, framebufferSizeCallback); glfwSetFramebufferSizeCallback(handle_, framebufferSizeCallback);
glfwSetWindowCloseCallback(glfwWindow_, windowCloseCallback); glfwSetWindowCloseCallback(handle_, windowCloseCallback);
glfwSetWindowFocusCallback(glfwWindow_, windowFocusCallback); glfwSetWindowFocusCallback(handle_, windowFocusCallback);
glfwSetWindowIconifyCallback(glfwWindow_, windowIconifyCallback); glfwSetWindowIconifyCallback(handle_, windowIconifyCallback);
glfwSetCursorPosCallback(glfwWindow_, cursorPosCallback); glfwSetCursorPosCallback(handle_, cursorPosCallback);
glfwSetMouseButtonCallback(glfwWindow_, mouseButtonCallback); glfwSetMouseButtonCallback(handle_, mouseButtonCallback);
glfwSetScrollCallback(glfwWindow_, scrollCallback); glfwSetScrollCallback(handle_, scrollCallback);
glfwSetKeyCallback(glfwWindow_, keyCallback); glfwSetKeyCallback(handle_, keyCallback);
glfwSetJoystickCallback(joystickCallback); glfwSetJoystickCallback(joystickCallback);
E2D_INFO("GLFW 窗口创建成功: {}x{}", width_, height_); E2D_INFO("GLFW 窗口创建成功: {}x{}", w_, h_);
return true; return true;
} }
void GLFWWindow::destroy() { void GLFWWindow::destroy() {
if (glfwWindow_) { if (handle_) {
glfwDestroyWindow(glfwWindow_); glfwDestroyWindow(handle_);
glfwWindow_ = nullptr; handle_ = nullptr;
} }
deinitGLFW(); deinitGLFW();
} }
void GLFWWindow::poll() { void GLFWWindow::poll() {
if (!glfwWindow_) if (!handle_)
return; return;
glfwPollEvents(); glfwPollEvents();
} }
void GLFWWindow::swap() { void GLFWWindow::swap() {
if (glfwWindow_) { if (handle_) {
glfwSwapBuffers(glfwWindow_); glfwSwapBuffers(handle_);
} }
} }
bool GLFWWindow::shouldClose() const { bool GLFWWindow::shouldClose() const {
if (!glfwWindow_) if (!handle_)
return true; return true;
return shouldClose_ || glfwWindowShouldClose(glfwWindow_); return shouldClose_ || glfwWindowShouldClose(handle_);
} }
void GLFWWindow::close() { void GLFWWindow::close() {
shouldClose_ = true; shouldClose_ = true;
if (glfwWindow_) { if (handle_) {
glfwSetWindowShouldClose(glfwWindow_, GLFW_TRUE); glfwSetWindowShouldClose(handle_, GLFW_TRUE);
} }
} }
void GLFWWindow::setTitle(const std::string &title) { void GLFWWindow::title(const std::string &t) {
if (glfwWindow_) { if (handle_) {
glfwSetWindowTitle(glfwWindow_, title.c_str()); glfwSetWindowTitle(handle_, t.c_str());
} }
} }
void GLFWWindow::setSize(int w, int h) { void GLFWWindow::size(int w, int h) {
if (glfwWindow_) { if (handle_) {
glfwSetWindowSize(glfwWindow_, w, h); glfwSetWindowSize(handle_, w, h);
width_ = w; w_ = w;
height_ = h; h_ = h;
} }
} }
void GLFWWindow::setPos(int x, int y) { void GLFWWindow::pos(int x, int y) {
#ifndef __SWITCH__ #ifndef __SWITCH__
if (glfwWindow_) { if (handle_) {
glfwSetWindowPos(glfwWindow_, x, y); glfwSetWindowPos(handle_, x, y);
} }
#else #else
(void)x; (void)x;
@ -140,9 +140,9 @@ void GLFWWindow::setPos(int x, int y) {
#endif #endif
} }
void GLFWWindow::setFullscreen(bool fs) { void GLFWWindow::fullscreen(bool fs) {
#ifndef __SWITCH__ #ifndef __SWITCH__
if (!glfwWindow_) if (!handle_)
return; return;
if (fs == fullscreen_) if (fs == fullscreen_)
@ -151,68 +151,68 @@ void GLFWWindow::setFullscreen(bool fs) {
if (fs) { if (fs) {
GLFWmonitor *monitor = glfwGetPrimaryMonitor(); GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor); const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(glfwWindow_, monitor, 0, 0, mode->width, mode->height, glfwSetWindowMonitor(handle_, monitor, 0, 0, mode->width, mode->height,
mode->refreshRate); mode->refreshRate);
} else { } else {
glfwSetWindowMonitor(glfwWindow_, nullptr, 100, 100, 1280, 720, 0); glfwSetWindowMonitor(handle_, nullptr, 100, 100, 1280, 720, 0);
} }
fullscreen_ = fs; fullscreen_ = fs;
glfwGetWindowSize(glfwWindow_, &width_, &height_); glfwGetWindowSize(handle_, &w_, &h_);
updateContentScale(); updateContentScale();
#else #else
(void)fs; (void)fs;
#endif #endif
} }
void GLFWWindow::setVSync(bool vsync) { void GLFWWindow::vsync(bool v) {
if (glfwWindow_) { if (handle_) {
glfwSwapInterval(vsync ? 1 : 0); glfwSwapInterval(v ? 1 : 0);
vsync_ = vsync; vsync_ = v;
} }
} }
void GLFWWindow::setVisible(bool visible) { void GLFWWindow::visible(bool v) {
#ifndef __SWITCH__ #ifndef __SWITCH__
if (glfwWindow_) { if (handle_) {
if (visible) { if (v) {
glfwShowWindow(glfwWindow_); glfwShowWindow(handle_);
} else { } else {
glfwHideWindow(glfwWindow_); glfwHideWindow(handle_);
} }
} }
#else #else
(void)visible; (void)v;
#endif #endif
} }
Size GLFWWindow::size() const { Size GLFWWindow::size() const {
return Size(static_cast<float>(width_), static_cast<float>(height_)); return Size(static_cast<f32>(w_), static_cast<f32>(h_));
} }
Vec2 GLFWWindow::pos() const { Vec2 GLFWWindow::pos() const {
int x = 0, y = 0; int x = 0, y = 0;
#ifndef __SWITCH__ #ifndef __SWITCH__
if (glfwWindow_) { if (handle_) {
glfwGetWindowPos(glfwWindow_, &x, &y); glfwGetWindowPos(handle_, &x, &y);
} }
#endif #endif
return Vec2(static_cast<float>(x), static_cast<float>(y)); return Vec2(static_cast<f32>(x), static_cast<f32>(y));
} }
void GLFWWindow::setCursor(Cursor cursor) { void GLFWWindow::cursor(Cursor c) {
#ifndef __SWITCH__ #ifndef __SWITCH__
if (!glfwWindow_) if (!handle_)
return; return;
if (cursor == Cursor::Hidden) { if (c == Cursor::Hidden) {
glfwSetInputMode(glfwWindow_, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); glfwSetInputMode(handle_, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
return; return;
} }
glfwSetInputMode(glfwWindow_, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetInputMode(handle_, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
GLFWcursor *glfwCursor = nullptr; GLFWcursor *glfwCursor = nullptr;
switch (cursor) { switch (c) {
case Cursor::Arrow: case Cursor::Arrow:
glfwCursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); glfwCursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
break; break;
@ -237,17 +237,17 @@ void GLFWWindow::setCursor(Cursor cursor) {
} }
if (glfwCursor) { if (glfwCursor) {
glfwSetCursor(glfwWindow_, glfwCursor); glfwSetCursor(handle_, glfwCursor);
} }
#else #else
(void)cursor; (void)c;
#endif #endif
} }
void GLFWWindow::showCursor(bool show) { void GLFWWindow::showCursor(bool show) {
#ifndef __SWITCH__ #ifndef __SWITCH__
if (glfwWindow_) { if (handle_) {
glfwSetInputMode(glfwWindow_, GLFW_CURSOR, glfwSetInputMode(handle_, GLFW_CURSOR,
show ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_HIDDEN); show ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_HIDDEN);
cursorVisible_ = show; cursorVisible_ = show;
} }
@ -258,8 +258,8 @@ void GLFWWindow::showCursor(bool show) {
void GLFWWindow::lockCursor(bool lock) { void GLFWWindow::lockCursor(bool lock) {
#ifndef __SWITCH__ #ifndef __SWITCH__
if (glfwWindow_) { if (handle_) {
glfwSetInputMode(glfwWindow_, GLFW_CURSOR, glfwSetInputMode(handle_, GLFW_CURSOR,
lock ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL); lock ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
cursorLocked_ = lock; cursorLocked_ = lock;
} }
@ -268,7 +268,7 @@ void GLFWWindow::lockCursor(bool lock) {
#endif #endif
} }
void *GLFWWindow::native() const { return glfwWindow_; } void *GLFWWindow::native() const { return handle_; }
bool GLFWWindow::initGLFW() { bool GLFWWindow::initGLFW() {
static int glfwInitCount = 0; static int glfwInitCount = 0;
@ -291,11 +291,11 @@ void GLFWWindow::deinitGLFW() {
} }
void GLFWWindow::updateContentScale() { void GLFWWindow::updateContentScale() {
if (glfwWindow_) { if (handle_) {
int fbWidth, fbHeight; int fbWidth, fbHeight;
glfwGetFramebufferSize(glfwWindow_, &fbWidth, &fbHeight); glfwGetFramebufferSize(handle_, &fbWidth, &fbHeight);
scaleX_ = fbWidth > 0 ? static_cast<float>(fbWidth) / width_ : 1.0f; scaleX_ = fbWidth > 0 ? static_cast<f32>(fbWidth) / w_ : 1.0f;
scaleY_ = fbHeight > 0 ? static_cast<float>(fbHeight) / height_ : 1.0f; scaleY_ = fbHeight > 0 ? static_cast<f32>(fbHeight) / h_ : 1.0f;
} }
} }
@ -305,19 +305,19 @@ void GLFWWindow::framebufferSizeCallback(GLFWwindow *window, int width,
GLFWWindow *self = GLFWWindow *self =
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
if (self) { if (self) {
self->width_ = width; self->w_ = width;
self->height_ = height; self->h_ = height;
self->updateContentScale(); self->updateContentScale();
if (self->resizeCb_) { if (self->resizeFn_) {
self->resizeCb_(width, height); self->resizeFn_(width, height);
} }
} }
// 将事件推送到事件服务 // 将事件推送到事件服务
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
Event e = Event::createWindowResize(width, height); Event e = Event::windowResize(width, height);
eventService->pushEvent(e); eventService->push(e);
} }
} }
@ -326,16 +326,16 @@ void GLFWWindow::windowCloseCallback(GLFWwindow *window) {
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
if (self) { if (self) {
self->shouldClose_ = true; self->shouldClose_ = true;
if (self->closeCb_) { if (self->closeFn_) {
self->closeCb_(); self->closeFn_();
} }
} }
// 将事件推送到事件服务 // 将事件推送到事件服务
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
Event e = Event::createWindowClose(); Event e = Event::windowClose();
eventService->pushEvent(e); eventService->push(e);
} }
} }
@ -344,8 +344,8 @@ void GLFWWindow::windowFocusCallback(GLFWwindow *window, int focused) {
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
if (self) { if (self) {
self->focused_ = (focused == GLFW_TRUE); self->focused_ = (focused == GLFW_TRUE);
if (self->focusCb_) { if (self->focusFn_) {
self->focusCb_(self->focused_); self->focusFn_(self->focused_);
} }
} }
} }
@ -364,12 +364,12 @@ void GLFWWindow::cursorPosCallback(GLFWwindow *window, double xpos,
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
// 将事件推送到事件服务 // 将事件推送到事件服务
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
Vec2 pos{static_cast<float>(xpos), static_cast<float>(ypos)}; Vec2 pos{static_cast<f32>(xpos), static_cast<f32>(ypos)};
Vec2 delta{0.0f, 0.0f}; // GLFW 回调中没有增量,需要在其他地方计算 Vec2 delta{0.0f, 0.0f}; // GLFW 回调中没有增量,需要在其他地方计算
Event e = Event::createMouseMove(pos, delta); Event e = Event::mouseMove(pos, delta);
eventService->pushEvent(e); eventService->push(e);
} }
} }
@ -379,18 +379,18 @@ void GLFWWindow::mouseButtonCallback(GLFWwindow *window, int button, int action,
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
// 将事件推送到事件服务 // 将事件推送到事件服务
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
double x, y; double x, y;
glfwGetCursorPos(window, &x, &y); glfwGetCursorPos(window, &x, &y);
Vec2 pos{static_cast<float>(x), static_cast<float>(y)}; Vec2 pos{static_cast<f32>(x), static_cast<f32>(y)};
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
Event e = Event::createMouseButtonPress(button, mods, pos); Event e = Event::mousePress(button, mods, pos);
eventService->pushEvent(e); eventService->push(e);
} else if (action == GLFW_RELEASE) { } else if (action == GLFW_RELEASE) {
Event e = Event::createMouseButtonRelease(button, mods, pos); Event e = Event::mouseRelease(button, mods, pos);
eventService->pushEvent(e); eventService->push(e);
} }
} }
} }
@ -401,14 +401,14 @@ void GLFWWindow::scrollCallback(GLFWwindow *window, double xoffset,
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
// 将事件推送到事件服务 // 将事件推送到事件服务
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
double x, y; double x, y;
glfwGetCursorPos(window, &x, &y); glfwGetCursorPos(window, &x, &y);
Vec2 offset{static_cast<float>(xoffset), static_cast<float>(yoffset)}; Vec2 offset{static_cast<f32>(xoffset), static_cast<f32>(yoffset)};
Vec2 pos{static_cast<float>(x), static_cast<float>(y)}; Vec2 pos{static_cast<f32>(x), static_cast<f32>(y)};
Event e = Event::createMouseScroll(offset, pos); Event e = Event::mouseScroll(offset, pos);
eventService->pushEvent(e); eventService->push(e);
} }
} }
@ -418,7 +418,7 @@ void GLFWWindow::keyCallback(GLFWwindow *window, int key, int scancode,
static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window)); static_cast<GLFWWindow *>(glfwGetWindowUserPointer(window));
// 将事件推送到事件服务 // 将事件推送到事件服务
auto eventService = ServiceLocator::instance().getService<IEventService>(); auto eventService = ServiceLocator::instance().get<IEventService>();
if (eventService) { if (eventService) {
// 将 GLFW key code 转换为引擎 Key 枚举值 // 将 GLFW key code 转换为引擎 Key 枚举值
Key eKey = Key::None; Key eKey = Key::None;
@ -645,13 +645,13 @@ void GLFWWindow::keyCallback(GLFWwindow *window, int key, int scancode,
} }
if (eKey != Key::None) { if (eKey != Key::None) {
int keyCode = static_cast<int>(eKey); i32 keyCode = static_cast<i32>(eKey);
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
Event e = Event::createKeyPress(keyCode, scancode, mods); Event e = Event::keyPress(keyCode, scancode, mods);
eventService->pushEvent(e); eventService->push(e);
} else if (action == GLFW_RELEASE) { } else if (action == GLFW_RELEASE) {
Event e = Event::createKeyRelease(keyCode, scancode, mods); Event e = Event::keyRelease(keyCode, scancode, mods);
eventService->pushEvent(e); eventService->push(e);
} }
} }
} }

View File

@ -2,7 +2,7 @@
#include <extra2d/platform/window_module.h> #include <extra2d/platform/window_module.h>
#include <extra2d/services/logger_service.h> #include <extra2d/services/logger_service.h>
#include <glfw/glfw_window.h> #include <extra2d/platform/glfw/glfw_window.h>
#ifdef __SWITCH__ #ifdef __SWITCH__
#include <switch.h> #include <switch.h>
@ -26,7 +26,7 @@ bool WindowModule::init() {
E2D_INFO("正在创建 GLFW 窗口,尺寸 {}x{}", cfg_.w, cfg_.h); E2D_INFO("正在创建 GLFW 窗口,尺寸 {}x{}", cfg_.w, cfg_.h);
win_ = makeUnique<GLFWWindow>(); win_ = ptr::makeUnique<GLFWWindow>();
if (!win_) { if (!win_) {
E2D_ERROR("创建窗口失败"); E2D_ERROR("创建窗口失败");
return false; return false;

View File

@ -8,58 +8,57 @@ EventService::EventService() {
info_.enabled = true; info_.enabled = true;
} }
ServiceInfo EventService::getServiceInfo() const { return info_; } ServiceInfo EventService::info() const { return info_; }
bool EventService::initialize() { bool EventService::init() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void EventService::shutdown() { void EventService::shutdown() {
queue_.clear(); queue_.clear();
dispatcher_.removeAllListeners(); dispatcher_.offAll();
setState(ServiceState::Stopped); setState(ServiceState::Stopped);
} }
void EventService::update(float deltaTime) { void EventService::update(f32 dt) {
if (getState() == ServiceState::Running) { if (state() == ServiceState::Running) {
processQueue(); process();
} }
} }
void EventService::pushEvent(const Event &event) { queue_.push(event); } void EventService::push(const Event &event) { queue_.push(event); }
void EventService::pushEvent(Event &&event) { queue_.push(std::move(event)); } void EventService::push(Event &&event) { queue_.push(std::move(event)); }
bool EventService::pollEvent(Event &event) { return queue_.poll(event); } bool EventService::poll(Event &event) { return queue_.poll(event); }
ListenerId EventService::addListener(EventType type, ListenerID EventService::on(EventType type, EventDispatcher::EventFn fn) {
EventDispatcher::EventCallback callback) { return dispatcher_.on(type, fn);
return dispatcher_.addListener(type, callback);
} }
void EventService::removeListener(ListenerId id) { void EventService::off(ListenerID id) {
dispatcher_.removeListener(id); dispatcher_.off(id);
} }
void EventService::removeAllListeners(EventType type) { void EventService::offAll(EventType type) {
dispatcher_.removeAllListeners(type); dispatcher_.offAll(type);
} }
void EventService::removeAllListeners() { dispatcher_.removeAllListeners(); } void EventService::offAll() { dispatcher_.offAll(); }
void EventService::dispatch(Event &event) { dispatcher_.dispatch(event); } void EventService::dispatch(Event &event) { dispatcher_.dispatch(event); }
void EventService::processQueue() { dispatcher_.processQueue(queue_); } void EventService::process() { dispatcher_.process(queue_); }
size_t EventService::getListenerCount(EventType type) const { size_t EventService::listenerCount(EventType type) const {
return dispatcher_.getListenerCount(type); return dispatcher_.listenerCount(type);
} }
size_t EventService::getTotalListenerCount() const { size_t EventService::totalListeners() const {
return dispatcher_.getTotalListenerCount(); return dispatcher_.totalListeners();
} }
size_t EventService::getQueueSize() const { return queue_.size(); } size_t EventService::queueSize() const { return queue_.size(); }
} // namespace extra2d } // namespace extra2d

View File

@ -11,9 +11,6 @@
namespace extra2d { namespace extra2d {
#ifdef _WIN32 #ifdef _WIN32
/**
* @brief Windows ANSI + UTF-8
*/
static bool enableWindowsConsoleFeatures() { static bool enableWindowsConsoleFeatures() {
bool success = true; bool success = true;
@ -45,7 +42,7 @@ public:
}; };
ConsoleLogger::ConsoleLogger() ConsoleLogger::ConsoleLogger()
: level_(LogLevel::Info), colorEnabled_(true), : level_(LogLevel::Info), colors_(true),
impl_(std::make_unique<Impl>()) { impl_(std::make_unique<Impl>()) {
info_.name = "ConsoleLogger"; info_.name = "ConsoleLogger";
info_.priority = ServicePriority::Core; info_.priority = ServicePriority::Core;
@ -67,23 +64,23 @@ ConsoleLogger::ConsoleLogger()
ConsoleLogger::~ConsoleLogger() = default; ConsoleLogger::~ConsoleLogger() = default;
bool ConsoleLogger::initialize() { bool ConsoleLogger::init() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void ConsoleLogger::shutdown() { setState(ServiceState::Stopped); } void ConsoleLogger::shutdown() { setState(ServiceState::Stopped); }
void ConsoleLogger::setLevel(LogLevel level) { level_ = level; } void ConsoleLogger::level(LogLevel lvl) { level_ = lvl; }
LogLevel ConsoleLogger::getLevel() const { return level_; } LogLevel ConsoleLogger::level() const { return level_; }
bool ConsoleLogger::isEnabled(LogLevel level) const { bool ConsoleLogger::enabled(LogLevel lvl) const {
return static_cast<int>(level) >= static_cast<int>(level_); return static_cast<int>(lvl) >= static_cast<int>(level_);
} }
void ConsoleLogger::log(LogLevel level, const char *fmt, ...) { void ConsoleLogger::log(LogLevel lvl, const char *fmt, ...) {
if (!isEnabled(level)) if (!enabled(lvl))
return; return;
char buffer[1024]; char buffer[1024];
@ -92,17 +89,17 @@ void ConsoleLogger::log(LogLevel level, const char *fmt, ...) {
vsnprintf(buffer, sizeof(buffer), fmt, args); vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args); va_end(args);
output(level, buffer); output(lvl, buffer);
} }
void ConsoleLogger::log(LogLevel level, const std::string &msg) { void ConsoleLogger::log(LogLevel lvl, const std::string &msg) {
if (!isEnabled(level)) if (!enabled(lvl))
return; return;
output(level, msg.c_str()); output(lvl, msg.c_str());
} }
void ConsoleLogger::trace(const char *fmt, ...) { void ConsoleLogger::trace(const char *fmt, ...) {
if (!isEnabled(LogLevel::Trace)) if (!enabled(LogLevel::Trace))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -113,7 +110,7 @@ void ConsoleLogger::trace(const char *fmt, ...) {
} }
void ConsoleLogger::debug(const char *fmt, ...) { void ConsoleLogger::debug(const char *fmt, ...) {
if (!isEnabled(LogLevel::Debug)) if (!enabled(LogLevel::Debug))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -124,7 +121,7 @@ void ConsoleLogger::debug(const char *fmt, ...) {
} }
void ConsoleLogger::info(const char *fmt, ...) { void ConsoleLogger::info(const char *fmt, ...) {
if (!isEnabled(LogLevel::Info)) if (!enabled(LogLevel::Info))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -135,7 +132,7 @@ void ConsoleLogger::info(const char *fmt, ...) {
} }
void ConsoleLogger::registry(const char *fmt, ...) { void ConsoleLogger::registry(const char *fmt, ...) {
if (!isEnabled(LogLevel::Registry)) if (!enabled(LogLevel::Registry))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -146,7 +143,7 @@ void ConsoleLogger::registry(const char *fmt, ...) {
} }
void ConsoleLogger::warn(const char *fmt, ...) { void ConsoleLogger::warn(const char *fmt, ...) {
if (!isEnabled(LogLevel::Warn)) if (!enabled(LogLevel::Warn))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -157,7 +154,7 @@ void ConsoleLogger::warn(const char *fmt, ...) {
} }
void ConsoleLogger::error(const char *fmt, ...) { void ConsoleLogger::error(const char *fmt, ...) {
if (!isEnabled(LogLevel::Error)) if (!enabled(LogLevel::Error))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -168,7 +165,7 @@ void ConsoleLogger::error(const char *fmt, ...) {
} }
void ConsoleLogger::fatal(const char *fmt, ...) { void ConsoleLogger::fatal(const char *fmt, ...) {
if (!isEnabled(LogLevel::Fatal)) if (!enabled(LogLevel::Fatal))
return; return;
char buffer[1024]; char buffer[1024];
va_list args; va_list args;
@ -178,33 +175,33 @@ void ConsoleLogger::fatal(const char *fmt, ...) {
output(LogLevel::Fatal, buffer); output(LogLevel::Fatal, buffer);
} }
void ConsoleLogger::setLevelColor(LogLevel level, const LogColor &color) { void ConsoleLogger::levelColor(LogLevel lvl, const LogColor &c) {
int idx = static_cast<int>(level); int idx = static_cast<int>(lvl);
if (idx >= 0 && idx < 7) { if (idx >= 0 && idx < 7) {
levelColors_[idx] = color; levelColors_[idx] = c;
} }
} }
LogColor ConsoleLogger::getLevelColor(LogLevel level) const { LogColor ConsoleLogger::levelColor(LogLevel lvl) const {
int idx = static_cast<int>(level); int idx = static_cast<int>(lvl);
if (idx >= 0 && idx < 7) { if (idx >= 0 && idx < 7) {
return levelColors_[idx]; return levelColors_[idx];
} }
return LogColor::White(); return LogColor::White();
} }
void ConsoleLogger::setColorEnabled(bool enabled) { colorEnabled_ = enabled; } void ConsoleLogger::colors(bool on) { colors_ = on; }
bool ConsoleLogger::isColorEnabled() const { return colorEnabled_; } bool ConsoleLogger::colors() const { return colors_; }
std::string ConsoleLogger::getAnsiColor(LogLevel level) { std::string ConsoleLogger::ansiColor(LogLevel lvl) {
const LogColor &c = getLevelColor(level); const LogColor &c = levelColor(lvl);
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "\033[38;2;%d;%d;%dm", c.r, c.g, c.b); snprintf(buf, sizeof(buf), "\033[38;2;%d;%d;%dm", c.r, c.g, c.b);
return std::string(buf); return std::string(buf);
} }
void ConsoleLogger::output(LogLevel level, const char *msg) { void ConsoleLogger::output(LogLevel lvl, const char *msg) {
std::lock_guard<std::mutex> lock(impl_->mutex_); std::lock_guard<std::mutex> lock(impl_->mutex_);
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
@ -220,11 +217,11 @@ void ConsoleLogger::output(LogLevel level, const char *msg) {
localtime_r(&time, &tm); localtime_r(&time, &tm);
#endif #endif
const char *levelStr = getLevelString(level); const char *levelStr = levelString(lvl);
const char *reset = "\033[0m"; const char *reset = "\033[0m";
if (colorEnabled_) { if (colors_) {
std::string color = getAnsiColor(level); std::string color = ansiColor(lvl);
printf("%s[%02d:%02d:%02d.%03d] [%s] %s%s\n", color.c_str(), tm.tm_hour, printf("%s[%02d:%02d:%02d.%03d] [%s] %s%s\n", color.c_str(), tm.tm_hour,
tm.tm_min, tm.tm_sec, (int)ms.count(), levelStr, msg, reset); tm.tm_min, tm.tm_sec, (int)ms.count(), levelStr, msg, reset);
} else { } else {
@ -233,8 +230,8 @@ void ConsoleLogger::output(LogLevel level, const char *msg) {
} }
} }
const char *ConsoleLogger::getLevelString(LogLevel level) { const char *ConsoleLogger::levelString(LogLevel lvl) {
switch (level) { switch (lvl) {
case LogLevel::Trace: case LogLevel::Trace:
return "TRACE"; return "TRACE";
case LogLevel::Debug: case LogLevel::Debug:

View File

@ -8,45 +8,44 @@ TimerService::TimerService() {
info_.enabled = true; info_.enabled = true;
} }
ServiceInfo TimerService::getServiceInfo() const { return info_; } ServiceInfo TimerService::info() const { return info_; }
bool TimerService::initialize() { bool TimerService::init() {
setState(ServiceState::Running); setState(ServiceState::Running);
return true; return true;
} }
void TimerService::shutdown() { void TimerService::shutdown() {
manager_.clear(); mgr_.clear();
setState(ServiceState::Stopped); setState(ServiceState::Stopped);
} }
void TimerService::update(float deltaTime) { void TimerService::update(f32 dt) {
if (getState() == ServiceState::Running) { if (state() == ServiceState::Running) {
manager_.update(deltaTime); mgr_.update(dt);
} }
} }
uint32 TimerService::addTimer(float delay, Timer::Callback callback) { u32 TimerService::add(f32 delay, Timer::Fn fn) {
return manager_.addTimer(delay, callback); return mgr_.add(delay, fn);
} }
uint32 TimerService::addRepeatingTimer(float interval, u32 TimerService::addRepeat(f32 interval, Timer::Fn fn) {
Timer::Callback callback) { return mgr_.addRepeat(interval, fn);
return manager_.addRepeatingTimer(interval, callback);
} }
void TimerService::cancelTimer(uint32 timerId) { void TimerService::cancel(u32 timerId) {
manager_.cancelTimer(timerId); mgr_.cancel(timerId);
} }
void TimerService::pauseTimer(uint32 timerId) { manager_.pauseTimer(timerId); } void TimerService::pauseTimer(u32 timerId) { mgr_.pause(timerId); }
void TimerService::resumeTimer(uint32 timerId) { void TimerService::resumeTimer(u32 timerId) {
manager_.resumeTimer(timerId); mgr_.resume(timerId);
} }
void TimerService::clear() { manager_.clear(); } void TimerService::clear() { mgr_.clear(); }
size_t TimerService::getTimerCount() const { return manager_.getTimerCount(); } size_t TimerService::count() const { return mgr_.count(); }
} // namespace extra2d } // namespace extra2d

View File

@ -24,9 +24,9 @@ Random &Random::get() {
/** /**
* @brief * @brief
* @param seed * @param s
*/ */
void Random::setSeed(uint32 seed) { generator_.seed(seed); } void Random::seed(u32 s) { generator_.seed(s); }
/** /**
* @brief 使 * @brief 使
@ -36,14 +36,14 @@ void Random::setSeed(uint32 seed) { generator_.seed(seed); }
void Random::randomize() { void Random::randomize() {
auto now = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now();
auto time = now.time_since_epoch().count(); auto time = now.time_since_epoch().count();
generator_.seed(static_cast<uint32>(time)); generator_.seed(static_cast<u32>(time));
} }
/** /**
* @brief [0.0, 1.0] * @brief [0, 1)
* @return [0.0, 1.0] * @return [0, 1)
*/ */
float Random::getFloat() { return floatDist_(generator_); } f32 Random::randomF32() { return floatDist_(generator_); }
/** /**
* @brief * @brief
@ -51,7 +51,7 @@ float Random::getFloat() { return floatDist_(generator_); }
* @param max * @param max
* @return [min, max] * @return [min, max]
*/ */
float Random::getFloat(float min, float max) { f32 Random::randomF32(f32 min, f32 max) {
if (min >= max) { if (min >= max) {
return min; return min;
} }
@ -63,11 +63,11 @@ float Random::getFloat(float min, float max) {
* @param max * @param max
* @return [0, max] * @return [0, max]
*/ */
int Random::getInt(int max) { i32 Random::randomI32(i32 max) {
if (max <= 0) { if (max <= 0) {
return 0; return 0;
} }
std::uniform_int_distribution<int> dist(0, max); std::uniform_int_distribution<i32> dist(0, max);
return dist(generator_); return dist(generator_);
} }
@ -77,11 +77,11 @@ int Random::getInt(int max) {
* @param max * @param max
* @return [min, max] * @return [min, max]
*/ */
int Random::getInt(int min, int max) { i32 Random::randomI32(i32 min, i32 max) {
if (min >= max) { if (min >= max) {
return min; return min;
} }
std::uniform_int_distribution<int> dist(min, max); std::uniform_int_distribution<i32> dist(min, max);
return dist(generator_); return dist(generator_);
} }
@ -89,14 +89,14 @@ int Random::getInt(int min, int max) {
* @brief 50% * @brief 50%
* @return * @return
*/ */
bool Random::getBool() { return floatDist_(generator_) >= 0.5f; } bool Random::boolean() { return floatDist_(generator_) >= 0.5f; }
/** /**
* @brief * @brief
* @param probability true的概率[0.0, 1.0] * @param probability true的概率[0.0, 1.0]
* @return * @return
*/ */
bool Random::getBool(float probability) { bool Random::boolean(f32 probability) {
if (probability <= 0.0f) { if (probability <= 0.0f) {
return false; return false;
} }
@ -110,8 +110,8 @@ bool Random::getBool(float probability) {
* @brief * @brief
* @return [0, 2π] * @return [0, 2π]
*/ */
float Random::getAngle() { f32 Random::angle() {
static const float TWO_PI = 6.28318530718f; static const f32 TWO_PI = 6.28318530718f;
return floatDist_(generator_) * TWO_PI; return floatDist_(generator_) * TWO_PI;
} }
@ -119,6 +119,6 @@ float Random::getAngle() {
* @brief * @brief
* @return [-1.0, 1.0] * @return [-1.0, 1.0]
*/ */
float Random::getSigned() { return floatDist_(generator_) * 2.0f - 1.0f; } f32 Random::signedF32() { return floatDist_(generator_) * 2.0f - 1.0f; }
} // namespace extra2d } // namespace extra2d

View File

@ -3,35 +3,24 @@
namespace extra2d { namespace extra2d {
uint32 Timer::nextId_ = 1; u32 Timer::nextId_ = 1;
/** Timer::Timer(f32 interval, bool repeat, Fn fn)
* @brief
* @param interval
* @param repeat
* @param callback
*/
Timer::Timer(float interval, bool repeat, Callback callback)
: interval_(interval), elapsed_(0.0f), repeat_(repeat), paused_(false), : interval_(interval), elapsed_(0.0f), repeat_(repeat), paused_(false),
valid_(true), callback_(std::move(callback)) { valid_(true), fn_(std::move(fn)) {
id_ = nextId_++; id_ = nextId_++;
} }
/** bool Timer::update(f32 dt) {
* @brief
* @param deltaTime
* @return truefalse
*/
bool Timer::update(float deltaTime) {
if (!valid_ || paused_) { if (!valid_ || paused_) {
return false; return false;
} }
elapsed_ += deltaTime; elapsed_ += dt;
if (elapsed_ >= interval_) { if (elapsed_ >= interval_) {
if (callback_) { if (fn_) {
callback_(); fn_();
} }
if (repeat_) { if (repeat_) {
@ -46,81 +35,40 @@ bool Timer::update(float deltaTime) {
return false; return false;
} }
/**
* @brief
*
*
*/
void Timer::reset() { void Timer::reset() {
elapsed_ = 0.0f; elapsed_ = 0.0f;
valid_ = true; valid_ = true;
paused_ = false; paused_ = false;
} }
/**
* @brief
*/
void Timer::pause() { paused_ = true; } void Timer::pause() { paused_ = true; }
/**
* @brief
*/
void Timer::resume() { paused_ = false; } void Timer::resume() { paused_ = false; }
/**
* @brief
*
*
*/
void Timer::cancel() { valid_ = false; } void Timer::cancel() { valid_ = false; }
/** f32 Timer::remaining() const {
* @brief
* @return 0
*/
float Timer::getRemaining() const {
if (!valid_ || paused_) { if (!valid_ || paused_) {
return 0.0f; return 0.0f;
} }
return std::max(0.0f, interval_ - elapsed_); return std::max(0.0f, interval_ - elapsed_);
} }
// ============================================================================ u32 TimerManager::add(f32 delay, Timer::Fn fn) {
// TimerManager 实现 auto timer = std::make_unique<Timer>(delay, false, std::move(fn));
// ============================================================================ u32 id = timer->id();
/**
* @brief
* @param delay
* @param callback
* @return ID
*/
uint32 TimerManager::addTimer(float delay, Timer::Callback callback) {
auto timer = std::make_unique<Timer>(delay, false, std::move(callback));
uint32 id = timer->getId();
timers_.emplace(id, std::move(timer)); timers_.emplace(id, std::move(timer));
return id; return id;
} }
/** u32 TimerManager::addRepeat(f32 interval, Timer::Fn fn) {
* @brief auto timer = std::make_unique<Timer>(interval, true, std::move(fn));
* @param interval u32 id = timer->id();
* @param callback
* @return ID
*/
uint32 TimerManager::addRepeatingTimer(float interval,
Timer::Callback callback) {
auto timer = std::make_unique<Timer>(interval, true, std::move(callback));
uint32 id = timer->getId();
timers_.emplace(id, std::move(timer)); timers_.emplace(id, std::move(timer));
return id; return id;
} }
/** void TimerManager::cancel(u32 timerId) {
* @brief
* @param timerId ID
*/
void TimerManager::cancelTimer(uint32 timerId) {
auto it = timers_.find(timerId); auto it = timers_.find(timerId);
if (it != timers_.end()) { if (it != timers_.end()) {
it->second->cancel(); it->second->cancel();
@ -128,52 +76,35 @@ void TimerManager::cancelTimer(uint32 timerId) {
} }
} }
/** void TimerManager::pause(u32 timerId) {
* @brief
* @param timerId ID
*/
void TimerManager::pauseTimer(uint32 timerId) {
auto it = timers_.find(timerId); auto it = timers_.find(timerId);
if (it != timers_.end()) { if (it != timers_.end()) {
it->second->pause(); it->second->pause();
} }
} }
/** void TimerManager::resume(u32 timerId) {
* @brief
* @param timerId ID
*/
void TimerManager::resumeTimer(uint32 timerId) {
auto it = timers_.find(timerId); auto it = timers_.find(timerId);
if (it != timers_.end()) { if (it != timers_.end()) {
it->second->resume(); it->second->resume();
} }
} }
/** void TimerManager::update(f32 dt) {
* @brief
* @param deltaTime
*
*
*/
void TimerManager::update(float deltaTime) {
timersToRemove_.clear(); timersToRemove_.clear();
for (auto &[id, timer] : timers_) { for (auto &[id, timer] : timers_) {
timer->update(deltaTime); timer->update(dt);
if (!timer->isValid()) { if (!timer->valid()) {
timersToRemove_.push_back(id); timersToRemove_.push_back(id);
} }
} }
for (uint32 id : timersToRemove_) { for (u32 id : timersToRemove_) {
timers_.erase(id); timers_.erase(id);
} }
} }
/**
* @brief
*/
void TimerManager::clear() { void TimerManager::clear() {
timers_.clear(); timers_.clear();
timersToRemove_.clear(); timersToRemove_.clear();