refactor(core): 移除TBB依赖并重构事件系统和调度器
重构服务管理器和调度器,使用标准库替代TBB并发容器 将事件系统从core移动到独立event目录并优化实现 更新构建脚本移除TBB相关配置 添加线程安全队列实现并行调度
This commit is contained in:
parent
0761b55864
commit
5a3d0cd9de
|
|
@ -1,112 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <core/event/event_bus.h>
|
|
||||||
|
|
||||||
#define E2D_EVENT_BUS_NAME_(n) n##_Bus
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明事件总线
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_BUS(BusName) \
|
|
||||||
struct BusName##_Bus { \
|
|
||||||
static constexpr const char* NAME = #BusName; \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明无参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_0(EventName, BusName) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName)> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit() { ::extra2d::event::broadcast<EventName>(); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明单参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_1(EventName, BusName, Arg0) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0) { ::extra2d::event::broadcast<EventName>(arg0); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明双参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_2(EventName, BusName, Arg0, Arg1) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1) { ::extra2d::event::broadcast<EventName>(arg0, arg1); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明三参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_3(EventName, BusName, Arg0, Arg1, Arg2) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, Arg2> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2) { ::extra2d::event::broadcast<EventName>(arg0, arg1, arg2); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明四参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_4(EventName, BusName, Arg0, Arg1, Arg2, Arg3) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, Arg2, Arg3> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3) { ::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明五参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_5(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, Arg2, Arg3, Arg4> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { ::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明六参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_6(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { ::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4, arg5); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明七参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_7(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { ::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4, arg5, arg6); } \
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 声明八参数事件
|
|
||||||
*/
|
|
||||||
#define DECLARE_EVENT_8(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) \
|
|
||||||
struct EventName : ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7> { \
|
|
||||||
using Listener = ::extra2d::event::Listener<EventName>; \
|
|
||||||
static constexpr const char* NAME = #EventName; \
|
|
||||||
static constexpr const char* BUS_NAME = E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
|
||||||
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7) { ::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } \
|
|
||||||
};
|
|
||||||
|
|
@ -4,12 +4,11 @@
|
||||||
#include <types/ptr/ref_counted.h>
|
#include <types/ptr/ref_counted.h>
|
||||||
#include <types/ptr/intrusive_ptr.h>
|
#include <types/ptr/intrusive_ptr.h>
|
||||||
#include <types/const/priority.h>
|
#include <types/const/priority.h>
|
||||||
#include <tbb/concurrent_hash_map.h>
|
|
||||||
#include <tbb/concurrent_priority_queue.h>
|
|
||||||
#include <tbb/parallel_for.h>
|
|
||||||
#include <tbb/blocked_range.h>
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <queue>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -65,7 +64,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* @brief 调度器
|
* @brief 调度器
|
||||||
*
|
*
|
||||||
* 基于 TBB 实现的线程安全调度器,支持定时器和 update 回调
|
* 基于标准库实现的线程安全调度器,支持定时器和 update 回调
|
||||||
*/
|
*/
|
||||||
class Scheduler {
|
class Scheduler {
|
||||||
public:
|
public:
|
||||||
|
|
@ -107,10 +106,27 @@ private:
|
||||||
bool operator<(const UpdateEntry& o) const { return pri > o.pri; }
|
bool operator<(const UpdateEntry& o) const { return pri > o.pri; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 线程安全的优先队列包装
|
||||||
|
class SafePriorityQueue {
|
||||||
|
public:
|
||||||
|
void push(const UpdateEntry& entry);
|
||||||
|
bool pop(UpdateEntry& entry);
|
||||||
|
bool empty() const;
|
||||||
|
size_t size() const;
|
||||||
|
void clear();
|
||||||
|
private:
|
||||||
|
mutable std::mutex mutex_;
|
||||||
|
std::priority_queue<UpdateEntry> queue_;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<UpdateEntry> updates_;
|
std::vector<UpdateEntry> updates_;
|
||||||
tbb::concurrent_hash_map<TimerTarget*, size_t> updateIndex_;
|
std::unordered_map<TimerTarget*, size_t> updateIndex_;
|
||||||
tbb::concurrent_hash_map<TimerHdl, Ptr<Timer>> timers_;
|
mutable std::mutex updateIndexMutex_;
|
||||||
tbb::concurrent_priority_queue<UpdateEntry> updateQueue_;
|
|
||||||
|
std::unordered_map<TimerHdl, Ptr<Timer>> timers_;
|
||||||
|
mutable std::mutex timersMutex_;
|
||||||
|
|
||||||
|
SafePriorityQueue updateQueue_;
|
||||||
|
|
||||||
std::atomic<TimerHdl> nextHdl_{1};
|
std::atomic<TimerHdl> nextHdl_{1};
|
||||||
std::atomic<float> timeScale_{1.0f};
|
std::atomic<float> timeScale_{1.0f};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
#include <types/const/priority.h>
|
#include <types/const/priority.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <tbb/concurrent_hash_map.h>
|
#include <unordered_map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -88,8 +89,10 @@ public:
|
||||||
private:
|
private:
|
||||||
SvcMgr() = default;
|
SvcMgr() = default;
|
||||||
|
|
||||||
using SvcMap = tbb::concurrent_hash_map<std::string, Ptr<IService>>;
|
using SvcMap = std::unordered_map<std::string, Ptr<IService>>;
|
||||||
SvcMap svcMap_;
|
SvcMap svcMap_;
|
||||||
|
mutable std::mutex svcMapMutex_;
|
||||||
|
|
||||||
std::vector<Ptr<IService>> sortedSvcs_;
|
std::vector<Ptr<IService>> sortedSvcs_;
|
||||||
|
|
||||||
void sortSvcs();
|
void sortSvcs();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <event/event_bus.h>
|
||||||
|
|
||||||
|
#define E2D_EVENT_BUS_NAME_(n) n##_Bus
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明事件总线
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_BUS(BusName) \
|
||||||
|
struct BusName##_Bus { \
|
||||||
|
static constexpr const char *NAME = #BusName; \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明无参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_0(EventName, BusName) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName)> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit() { ::extra2d::event::broadcast<EventName>(); } \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明单参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_1(EventName, BusName, Arg0) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明双参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_2(EventName, BusName, Arg0, Arg1) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, \
|
||||||
|
Arg1> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明三参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_3(EventName, BusName, Arg0, Arg1, Arg2) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, \
|
||||||
|
Arg2> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1, arg2); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明四参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_4(EventName, BusName, Arg0, Arg1, Arg2, Arg3) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, \
|
||||||
|
Arg2, Arg3> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明五参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_5(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, \
|
||||||
|
Arg2, Arg3, Arg4> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明六参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_6(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4, \
|
||||||
|
Arg5) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, \
|
||||||
|
Arg2, Arg3, Arg4, Arg5> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, \
|
||||||
|
Arg5 arg5) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4, \
|
||||||
|
arg5); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明七参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_7(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4, \
|
||||||
|
Arg5, Arg6) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, \
|
||||||
|
Arg2, Arg3, Arg4, Arg5, Arg6> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, \
|
||||||
|
Arg5 arg5, Arg6 arg6) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4, \
|
||||||
|
arg5, arg6); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 声明八参数事件
|
||||||
|
*/
|
||||||
|
#define DECLARE_EVENT_8(EventName, BusName, Arg0, Arg1, Arg2, Arg3, Arg4, \
|
||||||
|
Arg5, Arg6, Arg7) \
|
||||||
|
struct EventName \
|
||||||
|
: ::extra2d::event::EventTrait<E2D_EVENT_BUS_NAME_(BusName), Arg0, Arg1, \
|
||||||
|
Arg2, Arg3, Arg4, Arg5, Arg6, Arg7> { \
|
||||||
|
using Listener = ::extra2d::event::Listener<EventName>; \
|
||||||
|
static constexpr const char *NAME = #EventName; \
|
||||||
|
static constexpr const char *BUS_NAME = \
|
||||||
|
E2D_EVENT_BUS_NAME_(BusName)::NAME; \
|
||||||
|
static void emit(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, \
|
||||||
|
Arg5 arg5, Arg6 arg6, Arg7 arg7) { \
|
||||||
|
::extra2d::event::broadcast<EventName>(arg0, arg1, arg2, arg3, arg4, \
|
||||||
|
arg5, arg6, arg7); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <core/event/event_bus_macros.h>
|
#include <event/event_bus_macros.h>
|
||||||
#include <types/base/types.h>
|
|
||||||
#include <platform/input.h>
|
#include <platform/input.h>
|
||||||
|
#include <types/base/types.h>
|
||||||
|
|
||||||
|
|
||||||
namespace extra2d::events {
|
namespace extra2d::events {
|
||||||
|
|
||||||
|
|
@ -138,25 +139,25 @@ DECLARE_EVENT_1(OnMouseWheel, Engine, int32)
|
||||||
* @brief 触摸开始事件
|
* @brief 触摸开始事件
|
||||||
* @param touch 触摸点信息
|
* @param touch 触摸点信息
|
||||||
*/
|
*/
|
||||||
DECLARE_EVENT_1(OnTouchBegan, Engine, const TouchPoint&)
|
DECLARE_EVENT_1(OnTouchBegan, Engine, const TouchPoint &)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 触摸移动事件
|
* @brief 触摸移动事件
|
||||||
* @param touch 触摸点信息
|
* @param touch 触摸点信息
|
||||||
*/
|
*/
|
||||||
DECLARE_EVENT_1(OnTouchMoved, Engine, const TouchPoint&)
|
DECLARE_EVENT_1(OnTouchMoved, Engine, const TouchPoint &)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 触摸结束事件
|
* @brief 触摸结束事件
|
||||||
* @param touch 触摸点信息
|
* @param touch 触摸点信息
|
||||||
*/
|
*/
|
||||||
DECLARE_EVENT_1(OnTouchEnded, Engine, const TouchPoint&)
|
DECLARE_EVENT_1(OnTouchEnded, Engine, const TouchPoint &)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 触摸取消事件
|
* @brief 触摸取消事件
|
||||||
* @param touch 触摸点信息
|
* @param touch 触摸点信息
|
||||||
*/
|
*/
|
||||||
DECLARE_EVENT_1(OnTouchCancelled, Engine, const TouchPoint&)
|
DECLARE_EVENT_1(OnTouchCancelled, Engine, const TouchPoint &)
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// 场景事件
|
// 场景事件
|
||||||
|
|
@ -23,10 +23,15 @@
|
||||||
#include <core/service.h>
|
#include <core/service.h>
|
||||||
|
|
||||||
// Platform
|
// Platform
|
||||||
#include <platform/sdl2.h>
|
|
||||||
#include <platform/input.h>
|
|
||||||
#include <platform/window.h>
|
|
||||||
#include <platform/file.h>
|
#include <platform/file.h>
|
||||||
|
#include <platform/input.h>
|
||||||
|
#include <platform/sdl2.h>
|
||||||
|
#include <platform/window.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Event
|
||||||
|
#include <event/event_bus.h>
|
||||||
|
#include <event/events.h>
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
#include <app/application.h>
|
#include <app/application.h>
|
||||||
#include <core/director.h>
|
#include <core/director.h>
|
||||||
#include <core/event/events.h>
|
|
||||||
#include <core/service.h>
|
#include <core/service.h>
|
||||||
|
#include <event/events.h>
|
||||||
#include <platform/file.h>
|
#include <platform/file.h>
|
||||||
#include <platform/input.h>
|
#include <platform/input.h>
|
||||||
#include <platform/sdl2.h>
|
#include <platform/sdl2.h>
|
||||||
#include <platform/window.h>
|
#include <platform/window.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
#include <core/event/event_bus.h>
|
|
||||||
|
|
||||||
namespace extra2d::event {
|
|
||||||
|
|
||||||
ListenerContainer::~ListenerContainer() {
|
|
||||||
ListenerEntry* curr = listenerList_;
|
|
||||||
while (curr) {
|
|
||||||
ListenerEntry* next = curr->next;
|
|
||||||
delete curr;
|
|
||||||
curr = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
curr = listenersToAdd_;
|
|
||||||
while (curr) {
|
|
||||||
ListenerEntry* next = curr->next;
|
|
||||||
delete curr;
|
|
||||||
curr = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto* entry : listenersToRemove_) {
|
|
||||||
delete entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenerContainer::addListener(ListenerBase* listener) {
|
|
||||||
if (!listener || !listener->entry_) return;
|
|
||||||
|
|
||||||
if (broadcasting_ > 0) {
|
|
||||||
listener->entry_->next = listenersToAdd_;
|
|
||||||
listenersToAdd_ = listener->entry_;
|
|
||||||
} else {
|
|
||||||
listener->entry_->next = listenerList_;
|
|
||||||
listener->entry_->prev = nullptr;
|
|
||||||
if (listenerList_) {
|
|
||||||
listenerList_->prev = listener->entry_;
|
|
||||||
}
|
|
||||||
listenerList_ = listener->entry_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenerContainer::removeListener(ListenerBase* listener) {
|
|
||||||
if (!listener || !listener->entry_) return;
|
|
||||||
|
|
||||||
if (broadcasting_ > 0) {
|
|
||||||
listenersToRemove_.push_back(listener->entry_);
|
|
||||||
listener->entry_->listener = nullptr;
|
|
||||||
} else {
|
|
||||||
if (listener->entry_->prev) {
|
|
||||||
listener->entry_->prev->next = listener->entry_->next;
|
|
||||||
} else {
|
|
||||||
listenerList_ = listener->entry_->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener->entry_->next) {
|
|
||||||
listener->entry_->next->prev = listener->entry_->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete listener->entry_;
|
|
||||||
listener->entry_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenerContainer::processPendingListeners() {
|
|
||||||
while (listenersToAdd_) {
|
|
||||||
ListenerEntry* entry = listenersToAdd_;
|
|
||||||
listenersToAdd_ = entry->next;
|
|
||||||
|
|
||||||
entry->next = listenerList_;
|
|
||||||
entry->prev = nullptr;
|
|
||||||
if (listenerList_) {
|
|
||||||
listenerList_->prev = entry;
|
|
||||||
}
|
|
||||||
listenerList_ = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto* entry : listenersToRemove_) {
|
|
||||||
if (entry->prev) {
|
|
||||||
entry->prev->next = entry->next;
|
|
||||||
} else {
|
|
||||||
listenerList_ = entry->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->next) {
|
|
||||||
entry->next->prev = entry->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete entry;
|
|
||||||
}
|
|
||||||
listenersToRemove_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ListenerContainer::hasPendingListeners() const {
|
|
||||||
return listenersToAdd_ != nullptr || !listenersToRemove_.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace extra2d::event
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#include <core/scheduler.h>
|
#include <core/scheduler.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <thread>
|
||||||
|
#include <future>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -76,6 +78,35 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SafePriorityQueue 实现
|
||||||
|
void Scheduler::SafePriorityQueue::push(const UpdateEntry& entry) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
queue_.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scheduler::SafePriorityQueue::pop(UpdateEntry& entry) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
if (queue_.empty()) return false;
|
||||||
|
entry = queue_.top();
|
||||||
|
queue_.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scheduler::SafePriorityQueue::empty() const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return queue_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Scheduler::SafePriorityQueue::size() const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return queue_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scheduler::SafePriorityQueue::clear() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
while (!queue_.empty()) queue_.pop();
|
||||||
|
}
|
||||||
|
|
||||||
Scheduler& Scheduler::inst() {
|
Scheduler& Scheduler::inst() {
|
||||||
static Scheduler instance;
|
static Scheduler instance;
|
||||||
return instance;
|
return instance;
|
||||||
|
|
@ -84,9 +115,10 @@ Scheduler& Scheduler::inst() {
|
||||||
TimerHdl Scheduler::scheduleUpdate(TimerTarget* target, int pri) {
|
TimerHdl Scheduler::scheduleUpdate(TimerTarget* target, int pri) {
|
||||||
if (!target) return INVALID_HDL;
|
if (!target) return INVALID_HDL;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(updateIndexMutex_);
|
||||||
UpdateEntry entry{target, pri, false, false};
|
UpdateEntry entry{target, pri, false, false};
|
||||||
updates_.push_back(entry);
|
updates_.push_back(entry);
|
||||||
updateIndex_.insert({target, updates_.size() - 1});
|
updateIndex_[target] = updates_.size() - 1;
|
||||||
|
|
||||||
return genHdl();
|
return genHdl();
|
||||||
}
|
}
|
||||||
|
|
@ -94,13 +126,14 @@ TimerHdl Scheduler::scheduleUpdate(TimerTarget* target, int pri) {
|
||||||
void Scheduler::unscheduleUpdate(TimerTarget* target) {
|
void Scheduler::unscheduleUpdate(TimerTarget* target) {
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
|
|
||||||
tbb::concurrent_hash_map<TimerTarget*, size_t>::accessor acc;
|
std::lock_guard<std::mutex> lock(updateIndexMutex_);
|
||||||
if (updateIndex_.find(acc, target)) {
|
auto it = updateIndex_.find(target);
|
||||||
size_t idx = acc->second;
|
if (it != updateIndex_.end()) {
|
||||||
|
size_t idx = it->second;
|
||||||
if (idx < updates_.size()) {
|
if (idx < updates_.size()) {
|
||||||
updates_[idx].markedForDel = true;
|
updates_[idx].markedForDel = true;
|
||||||
}
|
}
|
||||||
updateIndex_.erase(acc);
|
updateIndex_.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +144,10 @@ TimerHdl Scheduler::schedule(Cb cb, float interval, uint32 repeat, float delay)
|
||||||
TimerHdl hdl = genHdl();
|
TimerHdl hdl = genHdl();
|
||||||
timer->hdl_ = hdl;
|
timer->hdl_ = hdl;
|
||||||
|
|
||||||
timers_.insert({hdl, timer});
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
|
timers_[hdl] = timer;
|
||||||
|
}
|
||||||
return hdl;
|
return hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +158,10 @@ TimerHdl Scheduler::scheduleOnce(VoidCb cb, float delay) {
|
||||||
TimerHdl hdl = genHdl();
|
TimerHdl hdl = genHdl();
|
||||||
timer->hdl_ = hdl;
|
timer->hdl_ = hdl;
|
||||||
|
|
||||||
timers_.insert({hdl, timer});
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
|
timers_[hdl] = timer;
|
||||||
|
}
|
||||||
return hdl;
|
return hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,26 +170,36 @@ TimerHdl Scheduler::scheduleForever(Cb cb, float interval) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::unschedule(TimerHdl hdl) {
|
void Scheduler::unschedule(TimerHdl hdl) {
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
timers_.erase(hdl);
|
timers_.erase(hdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::unscheduleAll() {
|
void Scheduler::unscheduleAll() {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
timers_.clear();
|
timers_.clear();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(updateIndexMutex_);
|
||||||
updates_.clear();
|
updates_.clear();
|
||||||
updateIndex_.clear();
|
updateIndex_.clear();
|
||||||
|
}
|
||||||
|
updateQueue_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::pause(TimerHdl hdl) {
|
void Scheduler::pause(TimerHdl hdl) {
|
||||||
tbb::concurrent_hash_map<TimerHdl, Ptr<Timer>>::accessor acc;
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
if (timers_.find(acc, hdl)) {
|
auto it = timers_.find(hdl);
|
||||||
acc->second->pause();
|
if (it != timers_.end()) {
|
||||||
|
it->second->pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::resume(TimerHdl hdl) {
|
void Scheduler::resume(TimerHdl hdl) {
|
||||||
tbb::concurrent_hash_map<TimerHdl, Ptr<Timer>>::accessor acc;
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
if (timers_.find(acc, hdl)) {
|
auto it = timers_.find(hdl);
|
||||||
acc->second->resume();
|
if (it != timers_.end()) {
|
||||||
|
it->second->resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,6 +208,9 @@ void Scheduler::update(float dt) {
|
||||||
|
|
||||||
locked_ = true;
|
locked_ = true;
|
||||||
|
|
||||||
|
// 更新所有 update 回调
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(updateIndexMutex_);
|
||||||
for (auto& entry : updates_) {
|
for (auto& entry : updates_) {
|
||||||
if (!entry.markedForDel && !entry.paused && entry.target) {
|
if (!entry.markedForDel && !entry.paused && entry.target) {
|
||||||
entry.target->update(scaledDt);
|
entry.target->update(scaledDt);
|
||||||
|
|
@ -170,8 +222,12 @@ void Scheduler::update(float dt) {
|
||||||
[](const UpdateEntry& e) { return e.markedForDel; }),
|
[](const UpdateEntry& e) { return e.markedForDel; }),
|
||||||
updates_.end()
|
updates_.end()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新定时器
|
||||||
std::vector<TimerHdl> toRemove;
|
std::vector<TimerHdl> toRemove;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
for (auto it = timers_.begin(); it != timers_.end(); ++it) {
|
for (auto it = timers_.begin(); it != timers_.end(); ++it) {
|
||||||
auto& timer = it->second;
|
auto& timer = it->second;
|
||||||
timer->update(scaledDt);
|
timer->update(scaledDt);
|
||||||
|
|
@ -183,6 +239,7 @@ void Scheduler::update(float dt) {
|
||||||
for (auto hdl : toRemove) {
|
for (auto hdl : toRemove) {
|
||||||
timers_.erase(hdl);
|
timers_.erase(hdl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
locked_ = false;
|
locked_ = false;
|
||||||
}
|
}
|
||||||
|
|
@ -192,23 +249,46 @@ void Scheduler::updateParallel(float dt) {
|
||||||
|
|
||||||
locked_ = true;
|
locked_ = true;
|
||||||
|
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, updates_.size()),
|
// 并行更新所有 update 回调(使用标准库线程)
|
||||||
[this, scaledDt](const tbb::blocked_range<size_t>& range) {
|
{
|
||||||
for (size_t i = range.begin(); i != range.end(); ++i) {
|
std::lock_guard<std::mutex> lock(updateIndexMutex_);
|
||||||
|
size_t numThreads = std::thread::hardware_concurrency();
|
||||||
|
if (numThreads == 0) numThreads = 4;
|
||||||
|
|
||||||
|
size_t batchSize = updates_.size() / numThreads;
|
||||||
|
if (batchSize == 0) batchSize = 1;
|
||||||
|
|
||||||
|
std::vector<std::future<void>> futures;
|
||||||
|
|
||||||
|
for (size_t t = 0; t < numThreads && t * batchSize < updates_.size(); ++t) {
|
||||||
|
size_t start = t * batchSize;
|
||||||
|
size_t end = (t == numThreads - 1) ? updates_.size() : (t + 1) * batchSize;
|
||||||
|
|
||||||
|
futures.push_back(std::async(std::launch::async, [this, start, end, scaledDt]() {
|
||||||
|
for (size_t i = start; i < end; ++i) {
|
||||||
auto& entry = updates_[i];
|
auto& entry = updates_[i];
|
||||||
if (!entry.markedForDel && !entry.paused && entry.target) {
|
if (!entry.markedForDel && !entry.paused && entry.target) {
|
||||||
entry.target->update(scaledDt);
|
entry.target->update(scaledDt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& f : futures) {
|
||||||
|
f.wait();
|
||||||
|
}
|
||||||
|
|
||||||
updates_.erase(
|
updates_.erase(
|
||||||
std::remove_if(updates_.begin(), updates_.end(),
|
std::remove_if(updates_.begin(), updates_.end(),
|
||||||
[](const UpdateEntry& e) { return e.markedForDel; }),
|
[](const UpdateEntry& e) { return e.markedForDel; }),
|
||||||
updates_.end()
|
updates_.end()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新定时器
|
||||||
std::vector<TimerHdl> toRemove;
|
std::vector<TimerHdl> toRemove;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
for (auto it = timers_.begin(); it != timers_.end(); ++it) {
|
for (auto it = timers_.begin(); it != timers_.end(); ++it) {
|
||||||
auto& timer = it->second;
|
auto& timer = it->second;
|
||||||
timer->update(scaledDt);
|
timer->update(scaledDt);
|
||||||
|
|
@ -220,16 +300,18 @@ void Scheduler::updateParallel(float dt) {
|
||||||
for (auto hdl : toRemove) {
|
for (auto hdl : toRemove) {
|
||||||
timers_.erase(hdl);
|
timers_.erase(hdl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
locked_ = false;
|
locked_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scheduler::isScheduled(TimerHdl hdl) const {
|
bool Scheduler::isScheduled(TimerHdl hdl) const {
|
||||||
tbb::concurrent_hash_map<TimerHdl, Ptr<Timer>>::const_accessor acc;
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
return timers_.find(acc, hdl);
|
return timers_.find(hdl) != timers_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Scheduler::count() const {
|
size_t Scheduler::count() const {
|
||||||
|
std::lock_guard<std::mutex> lock(timersMutex_);
|
||||||
return timers_.size();
|
return timers_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,26 +10,29 @@ SvcMgr& SvcMgr::inst() {
|
||||||
|
|
||||||
void SvcMgr::reg(IService* svc) {
|
void SvcMgr::reg(IService* svc) {
|
||||||
if (!svc) return;
|
if (!svc) return;
|
||||||
SvcMap::accessor acc;
|
|
||||||
svcMap_.insert(acc, svc->name());
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
acc->second = Ptr<IService>(svc);
|
svcMap_[svc->name()] = Ptr<IService>(svc);
|
||||||
sortSvcs();
|
sortSvcs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::unreg(const char* name) {
|
void SvcMgr::unreg(const char* name) {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
svcMap_.erase(name);
|
svcMap_.erase(name);
|
||||||
sortSvcs();
|
sortSvcs();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<IService> SvcMgr::get(const char* name) {
|
Ptr<IService> SvcMgr::get(const char* name) {
|
||||||
SvcMap::const_accessor acc;
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
if (svcMap_.find(acc, name)) {
|
auto it = svcMap_.find(name);
|
||||||
return acc->second;
|
if (it != svcMap_.end()) {
|
||||||
|
return it->second;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SvcMgr::initAll() {
|
bool SvcMgr::initAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto& svc : sortedSvcs_) {
|
for (auto& svc : sortedSvcs_) {
|
||||||
if (svc && svc->state_ == SvcState::None) {
|
if (svc && svc->state_ == SvcState::None) {
|
||||||
if (!svc->init()) {
|
if (!svc->init()) {
|
||||||
|
|
@ -42,6 +45,7 @@ bool SvcMgr::initAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::pauseAll() {
|
void SvcMgr::pauseAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto& svc : sortedSvcs_) {
|
for (auto& svc : sortedSvcs_) {
|
||||||
if (svc && svc->state_ == SvcState::Running) {
|
if (svc && svc->state_ == SvcState::Running) {
|
||||||
svc->pause();
|
svc->pause();
|
||||||
|
|
@ -51,6 +55,7 @@ void SvcMgr::pauseAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::resumeAll() {
|
void SvcMgr::resumeAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto& svc : sortedSvcs_) {
|
for (auto& svc : sortedSvcs_) {
|
||||||
if (svc && svc->state_ == SvcState::Paused) {
|
if (svc && svc->state_ == SvcState::Paused) {
|
||||||
svc->resume();
|
svc->resume();
|
||||||
|
|
@ -60,6 +65,7 @@ void SvcMgr::resumeAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::shutdownAll() {
|
void SvcMgr::shutdownAll() {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto it = sortedSvcs_.rbegin(); it != sortedSvcs_.rend(); ++it) {
|
for (auto it = sortedSvcs_.rbegin(); it != sortedSvcs_.rend(); ++it) {
|
||||||
if (*it && (*it)->state_ >= SvcState::Inited) {
|
if (*it && (*it)->state_ >= SvcState::Inited) {
|
||||||
(*it)->shutdown();
|
(*it)->shutdown();
|
||||||
|
|
@ -69,6 +75,7 @@ void SvcMgr::shutdownAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::updateAll(float dt) {
|
void SvcMgr::updateAll(float dt) {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto& svc : sortedSvcs_) {
|
for (auto& svc : sortedSvcs_) {
|
||||||
if (svc && svc->state_ >= SvcState::Inited && svc->isEnabled()) {
|
if (svc && svc->state_ >= SvcState::Inited && svc->isEnabled()) {
|
||||||
if (svc->state_ == SvcState::Inited) {
|
if (svc->state_ == SvcState::Inited) {
|
||||||
|
|
@ -80,6 +87,7 @@ void SvcMgr::updateAll(float dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::lateUpdateAll(float dt) {
|
void SvcMgr::lateUpdateAll(float dt) {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto& svc : sortedSvcs_) {
|
for (auto& svc : sortedSvcs_) {
|
||||||
if (svc && svc->state_ >= SvcState::Running && svc->isEnabled()) {
|
if (svc && svc->state_ >= SvcState::Running && svc->isEnabled()) {
|
||||||
svc->lateUpdate(dt);
|
svc->lateUpdate(dt);
|
||||||
|
|
@ -88,6 +96,7 @@ void SvcMgr::lateUpdateAll(float dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvcMgr::fixedUpdateAll(float dt) {
|
void SvcMgr::fixedUpdateAll(float dt) {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
for (auto& svc : sortedSvcs_) {
|
for (auto& svc : sortedSvcs_) {
|
||||||
if (svc && svc->state_ >= SvcState::Running && svc->isEnabled()) {
|
if (svc && svc->state_ >= SvcState::Running && svc->isEnabled()) {
|
||||||
svc->fixedUpdate(dt);
|
svc->fixedUpdate(dt);
|
||||||
|
|
@ -96,11 +105,12 @@ void SvcMgr::fixedUpdateAll(float dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SvcMgr::has(const char* name) const {
|
bool SvcMgr::has(const char* name) const {
|
||||||
SvcMap::const_accessor acc;
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
return svcMap_.find(acc, name);
|
return svcMap_.find(name) != svcMap_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SvcMgr::count() const {
|
size_t SvcMgr::count() const {
|
||||||
|
std::lock_guard<std::mutex> lock(svcMapMutex_);
|
||||||
return svcMap_.size();
|
return svcMap_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include <event/event_bus.h>
|
||||||
|
|
||||||
|
namespace extra2d::event {
|
||||||
|
|
||||||
|
ListenerContainer::~ListenerContainer() {
|
||||||
|
ListenerEntry *curr = listenerList_;
|
||||||
|
while (curr) {
|
||||||
|
ListenerEntry *next = curr->next;
|
||||||
|
delete curr;
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = listenersToAdd_;
|
||||||
|
while (curr) {
|
||||||
|
ListenerEntry *next = curr->next;
|
||||||
|
delete curr;
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto *entry : listenersToRemove_) {
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListenerContainer::addListener(ListenerBase *listener) {
|
||||||
|
if (!listener || !listener->entry_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (broadcasting_ > 0) {
|
||||||
|
listener->entry_->next = listenersToAdd_;
|
||||||
|
listenersToAdd_ = listener->entry_;
|
||||||
|
} else {
|
||||||
|
listener->entry_->next = listenerList_;
|
||||||
|
listener->entry_->prev = nullptr;
|
||||||
|
if (listenerList_) {
|
||||||
|
listenerList_->prev = listener->entry_;
|
||||||
|
}
|
||||||
|
listenerList_ = listener->entry_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListenerContainer::removeListener(ListenerBase *listener) {
|
||||||
|
if (!listener || !listener->entry_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (broadcasting_ > 0) {
|
||||||
|
listenersToRemove_.push_back(listener->entry_);
|
||||||
|
listener->entry_->listener = nullptr;
|
||||||
|
} else {
|
||||||
|
if (listener->entry_->prev) {
|
||||||
|
listener->entry_->prev->next = listener->entry_->next;
|
||||||
|
} else {
|
||||||
|
listenerList_ = listener->entry_->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener->entry_->next) {
|
||||||
|
listener->entry_->next->prev = listener->entry_->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete listener->entry_;
|
||||||
|
listener->entry_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListenerContainer::processPendingListeners() {
|
||||||
|
while (listenersToAdd_) {
|
||||||
|
ListenerEntry *entry = listenersToAdd_;
|
||||||
|
listenersToAdd_ = entry->next;
|
||||||
|
|
||||||
|
entry->next = listenerList_;
|
||||||
|
entry->prev = nullptr;
|
||||||
|
if (listenerList_) {
|
||||||
|
listenerList_->prev = entry;
|
||||||
|
}
|
||||||
|
listenerList_ = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto *entry : listenersToRemove_) {
|
||||||
|
if (entry->prev) {
|
||||||
|
entry->prev->next = entry->next;
|
||||||
|
} else {
|
||||||
|
listenerList_ = entry->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->next) {
|
||||||
|
entry->next->prev = entry->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
listenersToRemove_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListenerContainer::hasPendingListeners() const {
|
||||||
|
return listenersToAdd_ != nullptr || !listenersToRemove_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace extra2d::event
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 492c01ee2b906e945f08355787dfc015dd7cc505
|
|
||||||
|
|
@ -8,44 +8,11 @@ local function get_current_plat()
|
||||||
return get_config("plat") or os.host()
|
return get_config("plat") or os.host()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 定义 TBB 源码编译目标
|
|
||||||
function define_tbb_target()
|
|
||||||
target("tbb")
|
|
||||||
set_kind("static")
|
|
||||||
set_languages("c++17")
|
|
||||||
|
|
||||||
add_includedirs("third_party/tbb/include", {public = true})
|
|
||||||
|
|
||||||
add_files("third_party/tbb/src/tbb/*.cpp")
|
|
||||||
|
|
||||||
add_defines("__TBB_BUILD=1")
|
|
||||||
add_defines("TBB_SUPPRESS_DEPRECATED_MESSAGES=1")
|
|
||||||
add_defines("TBB_USE_PROFILING_TOOLS=0")
|
|
||||||
|
|
||||||
local plat = get_current_plat()
|
|
||||||
if plat == "mingw" then
|
|
||||||
-- TBB uses ANSI Windows APIs, don't define UNICODE
|
|
||||||
-- MinGW doesn't define LOAD_LIBRARY_SAFE_CURRENT_DIRS
|
|
||||||
add_defines("LOAD_LIBRARY_SAFE_CURRENT_DIRS=0x00002000")
|
|
||||||
elseif plat == "switch" then
|
|
||||||
add_defines("__TBB_USE_THREAD_SANITIZER=0")
|
|
||||||
add_defines("TBB_USE_ASSERT=0")
|
|
||||||
add_defines("TBB_USE_DEBUG=0")
|
|
||||||
end
|
|
||||||
|
|
||||||
add_cxflags("-Wno-implicit-fallthrough", "-Wno-unused-function", "-Wno-unused-variable", {force = true})
|
|
||||||
target_end()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 定义 Extra2D 引擎库目标
|
-- 定义 Extra2D 引擎库目标
|
||||||
function define_extra2d_engine()
|
function define_extra2d_engine()
|
||||||
define_tbb_target()
|
|
||||||
|
|
||||||
target("extra2d")
|
target("extra2d")
|
||||||
set_kind("static")
|
set_kind("static")
|
||||||
|
|
||||||
add_deps("tbb")
|
|
||||||
|
|
||||||
add_files("src/**.cpp")
|
add_files("src/**.cpp")
|
||||||
add_files("third_party/glad/src/glad.c")
|
add_files("third_party/glad/src/glad.c")
|
||||||
|
|
||||||
|
|
@ -53,8 +20,6 @@ function define_extra2d_engine()
|
||||||
add_includedirs("third_party/glad/include", {public = true})
|
add_includedirs("third_party/glad/include", {public = true})
|
||||||
add_includedirs("third_party", {public = true})
|
add_includedirs("third_party", {public = true})
|
||||||
|
|
||||||
add_defines("TBB_USE_PROFILING_TOOLS=0")
|
|
||||||
|
|
||||||
local plat = get_current_plat()
|
local plat = get_current_plat()
|
||||||
if plat == "mingw" then
|
if plat == "mingw" then
|
||||||
add_defines("_UNICODE", "UNICODE")
|
add_defines("_UNICODE", "UNICODE")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue