refactor: Simplify and optimize event handling and listener management

This commit is contained in:
子沐呀
2024-12-16 17:44:06 +08:00
Unverified
parent e88362e96a
commit 4494e7986c
4 changed files with 76 additions and 47 deletions
+2 -5
View File
@@ -636,10 +636,7 @@ export namespace Event {
/** 回调 */
callback: (event: {
/** 事件参数 */
params: {
/** 末影龙复活后的uniqueId */
0: number
},
params: {},
/** 拦截事件 */
cancel: () => void,
/** 设置拦截状态 */
@@ -668,7 +665,7 @@ export namespace Event {
callback: (event: {
/** 事件参数 */
params: {
/** 末影实体 */
/** 末影实体 */
0: Entity
},
/** 获取事件ID */
+6 -5
View File
@@ -7,7 +7,7 @@ const getPluginName = () => {
} catch (error) {
return error.stack.trim().match(/plugins\\(.*)\\.*\.js:[0-9]+\)$/i)?.[1] || "Unknown";
}
}
};
module.exports = {
Event: {
@@ -37,6 +37,7 @@ module.exports = {
*/
listen: function (eventName, callback) {
try {
if (typeof callback !== "function") return false;
const eventReflection = {
onServerStopping: "ll::ServerStoppingEvent",
onClientLogin: "gmlib::ClientLoginAfterEvent",
@@ -75,6 +76,7 @@ module.exports = {
* @returns {number}
*/
emplaceListener: function (eventName, callback, priority = this.EventPriority.Normal, pluginName = getPluginName()) {
if (typeof callback !== "function") throw new Error("callback must be a function!");
const /** @type {number} */ eventId = ll.imports("GMLIB_Event_API", "emplaceListener")(pluginName, eventName, priority);
if (eventId === -1) throw new Error(`Event ${eventName} creation failed!`);
ll.exports((...data) => {
@@ -83,7 +85,7 @@ module.exports = {
callback({
params: data,
cancel: () => result = true,
setCancelled: (/** @type {boolean} */value) => result = value,
setCancelled: (/** @type {boolean} */value) => { result = value; },
isCancelled: () => result,
getId: () => eventId,
getEventType: () => eventName
@@ -95,8 +97,7 @@ module.exports = {
}
return result;
}, pluginName, eventName + "_" + eventId);
if (this.mEventData[eventName] === undefined) this.mEventData[eventName] = [];
this.mEventData[eventName].push(eventId);
(this.mEventData[eventName] ??= []).push(eventId);
return eventId;
},
@@ -140,7 +141,7 @@ module.exports = {
* @param {string | undefined} eventName
* @returns {number[] | Object.<string, number[]>}
*/
getListener: function(eventName) {
getListener: function (eventName) {
return eventName === undefined ? this.mEventData : this.mEventData[eventName] ?? [];
},
+67 -36
View File
@@ -1,42 +1,72 @@
#include "Global.h"
using namespace ll::hash_utils;
class EventManager {
private:
std::unordered_map<ullong, ll::event::ListenerPtr> mEventIds;
public:
static EventManager& getInstance() {
static std::unique_ptr<EventManager> instance;
if (!instance) instance = std::make_unique<EventManager>();
return *instance;
}
ullong getNextId() {
auto id = mEventIds.size();
mEventIds.emplace(id, nullptr);
return id;
}
bool addListener(ullong id, ll::event::ListenerPtr const& listener) {
if (mEventIds.contains(id) && mEventIds[id]) return false;
mEventIds[id] = listener;
return true;
}
bool removeListener(ullong id) {
if (ll::event::EventBus::getInstance().removeListener(mEventIds[id])) {
mEventIds[id] = nullptr;
return true;
}
return false;
}
bool hasListener(ullong id) { return mEventIds.contains(id) && mEventIds[id]; }
ll::event::ListenerPtr getListener(ullong id) { return mEventIds.contains(id) ? mEventIds[id] : nullptr; }
};
#define REGISTER_EVENT_LISTEN(eventType, paramType, params, cancelFun, ...) \
ll::event::ListenerPtr eventPtr = eventBus.emplaceListener<eventType>( \
[&eventBus, pluginName, eventName, eventId = (llong)mEventIds.size()](eventType& event) -> void { \
if (!RemoteCall::hasFunc(pluginName, eventName + "_" + std::to_string(mEventIds.at(eventId)))) { \
eventBus.removeListener(mEventIds.at(eventId)); \
auto eventPtr = ll::event::EventBus::getInstance().emplaceListener<eventType>( \
[pluginName, eventName, eventId](eventType& event) -> void { \
if (!RemoteCall::hasFunc(pluginName, eventName + "_" + std::to_string(eventId))) { \
EventManager::getInstance().removeListener(eventId); \
return; \
} \
try { \
__VA_ARGS__ \
auto result = RemoteCall::importAs<bool paramType>( \
pluginName, \
eventName + "_" + std::to_string(mEventIds.at(eventId)) \
) params; \
cancelFun; \
auto result = \
RemoteCall::importAs<bool paramType>(pluginName, eventName + "_" + std::to_string(eventId)) \
params; \
cancelFun \
} catch (...) {} \
}, \
ll::event::EventPriority(priority) \
); \
mEventIds[mEventIds.size()] = eventPtr->getId(); \
return (llong)eventPtr->getId()
return eventId
void Export_Event_API() {
static std::unordered_map<llong, ullong> mEventIds = {};
auto& eventBus = ll::event::EventBus::getInstance();
RemoteCall::exportAs("GMLIB_Event_API", "removeListener", [&eventBus](ll::event::ListenerId eventId) -> bool {
return eventBus.removeListener(eventId);
RemoteCall::exportAs("GMLIB_Event_API", "removeListener", [](ll::event::ListenerId eventId) -> bool {
return EventManager::getInstance().removeListener(eventId);
});
RemoteCall::exportAs("GMLIB_Event_API", "hasListener", [&eventBus](ll::event::ListenerId eventId) -> bool {
return eventBus.hasListener(eventId);
RemoteCall::exportAs("GMLIB_Event_API", "hasListener", [](ll::event::ListenerId eventId) -> bool {
return EventManager::getInstance().hasListener(eventId);
});
RemoteCall::exportAs("GMLIB_Event_API", "getListenerPriority", [&eventBus](ll::event::ListenerId eventId) -> int {
if (auto event = eventBus.getListener(eventId); event != nullptr) {
RemoteCall::exportAs("GMLIB_Event_API", "getListenerPriority", [](ll::event::ListenerId eventId) -> int {
if (auto event = EventManager::getInstance().getListener(eventId); event != nullptr) {
return (int)event->getPriority();
}
return -1;
@@ -45,7 +75,8 @@ void Export_Event_API() {
RemoteCall::exportAs(
"GMLIB_Event_API",
"emplaceListener",
[&eventBus](std::string const& pluginName, std::string const& eventName, int priority) -> llong {
[](std::string const& pluginName, std::string const& eventName, int priority) -> llong {
auto eventId = EventManager::getInstance().getNextId();
switch (doHash(eventName)) {
case doHash("ll::ServerStoppingEvent"): {
REGISTER_EVENT_LISTEN(ll::event::ServerStoppingEvent, (), (), , );
@@ -61,7 +92,7 @@ void Export_Event_API() {
event.getUuid().asString(),
event.getServerAuthXuid(),
event.getClientAuthXuid()),
if (result) event.disConnectClient()
if (result) event.disConnectClient();
);
}
case doHash("gmlib::WeatherUpdateBeforeEvent"): {
@@ -73,7 +104,7 @@ void Export_Event_API() {
event.getLightningLevel(),
event.getLightningLastTick(),
event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::WeatherUpdateAfterEvent"): {
@@ -92,7 +123,7 @@ void Export_Event_API() {
GMLIB::Event::EntityEvent::MobPickupItemBeforeEvent,
(Actor * mob, Actor * item, bool isCancelled),
(&event.self(), (Actor*)&event.getItemActor(), event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::MobPickupItemAfterEvent"): {
@@ -111,7 +142,7 @@ void Export_Event_API() {
{event.getPosition(), event.getBlockSource().getDimensionId().id},
event.getSpawner().has_value() ? event.getSpawner()->getOrCreateUniqueID().id : -1,
event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::ItemActorSpawnAfterEvent"): {
@@ -129,7 +160,7 @@ void Export_Event_API() {
GMLIB::Event::EntityEvent::ActorChangeDimensionBeforeEvent,
(Actor * entity, int toDimId, bool isCancelled),
(&event.self(), event.getToDimensionId(), event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::ActorChangeDimensionAfterEvent"): {
@@ -145,7 +176,7 @@ void Export_Event_API() {
GMLIB::Event::PlayerEvent::PlayerStartSleepBeforeEvent,
(Player * entity, BlockPos pos, bool isCancelled),
(&event.self(), event.getPosition(), event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::PlayerStartSleepAfterEvent"): {
@@ -161,7 +192,7 @@ void Export_Event_API() {
GMLIB::Event::PlayerEvent::PlayerStopSleepBeforeEvent,
(Player * entity, bool forcefulWakeUp, bool updateLevelList, bool isCancelled),
(&event.self(), event.isForcefulWakeUp(), event.isUpdateLevelList(), event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::PlayerStopSleepAfterEvent"): {
@@ -200,15 +231,15 @@ void Export_Event_API() {
GMLIB::Event::EntityEvent::EndermanTakeBlockBeforeEvent,
(Actor * mob, bool isCancelled),
(&event.self(), event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::DragonRespawnBeforeEvent"): {
REGISTER_EVENT_LISTEN(
GMLIB::Event::EntityEvent::DragonRespawnBeforeEvent,
(int64 uniqueId, bool isCancelled),
(event.getEnderDragon().id, event.isCancelled()),
event.setCancelled(result)
(bool isCancelled),
(event.isCancelled()),
event.setCancelled(result);
);
}
case doHash("gmlib::DragonRespawnAfterEvent"): {
@@ -225,7 +256,7 @@ void Export_Event_API() {
(&event.self(),
event.getShooter() ? event.getShooter()->getOrCreateUniqueID().id : -1,
event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::ProjectileCreateAfterEvent"): {
@@ -240,7 +271,7 @@ void Export_Event_API() {
GMLIB::Event::EntityEvent::SpawnWanderingTraderBeforeEvent,
(std::pair<BlockPos, int> pos, bool isCancelled),
({event.getPos(), event.getRegion().getDimensionId()}, event.isCancelled()),
event.setCancelled(result)
event.setCancelled(result);
);
}
case doHash("gmlib::SpawnWanderingTraderAfterEvent"): {
@@ -274,7 +305,7 @@ void Export_Event_API() {
(int)requestAction.mDst.mSlot,
event.isCancelled()
),
event.setCancelled(result),
event.setCancelled(result);,
auto& requestAction = (ItemStackRequestActionTransferBase&)event.getRequestAction();
);
// clang-format on
+1 -1
View File
@@ -10,7 +10,7 @@ end
-- Option 1: Use the latest version of LeviLamina released on GitHub.
add_requires("levilaminalibrary")
add_requires("legacyremotecall")
add_requires("gmlib 0.13.7")
add_requires("gmlib")
-- Option 2: Use a specific version of LeviLamina released on GitHub.
-- add_requires("levilamina x.x.x")