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