@snailycfx/nexus 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/events/core/EventClass.d.ts +1 -0
- package/out/events/core/EventClass.luau +2 -0
- package/out/events/core/EventHandlerMeta.d.ts +8 -0
- package/out/events/core/EventHandlerMeta.luau +2 -0
- package/out/events/core/EventHandlerOptions.d.ts +5 -0
- package/out/events/core/EventHandlerOptions.luau +2 -0
- package/out/events/core/EventPriority.d.ts +8 -0
- package/out/events/core/EventPriority.luau +2 -0
- package/out/events/core/NexusEvent.d.ts +5 -0
- package/out/events/core/NexusEvent.luau +17 -0
- package/out/events/core/metadata/NexusMetadata.d.ts +6 -0
- package/out/events/core/metadata/NexusMetadata.luau +37 -0
- package/out/events/decorators/EventHandler.d.ts +4 -0
- package/out/events/decorators/EventHandler.luau +47 -0
- package/out/events/handlers/player/PlayerJoinEvent.d.ts +6 -0
- package/out/events/handlers/player/PlayerJoinEvent.luau +28 -0
- package/out/events/handlers/player/PlayerLeaveEvent.d.ts +6 -0
- package/out/events/handlers/player/PlayerLeaveEvent.luau +28 -0
- package/out/index.server.d.ts +9 -0
- package/out/init.server.luau +10 -0
- package/out/interfaces/IListener.d.ts +2 -0
- package/out/interfaces/IListener.luau +2 -0
- package/out/server/Nexus.d.ts +10 -0
- package/out/server/Nexus.luau +34 -0
- package/out/server/managers/EventManager.d.ts +8 -0
- package/out/server/managers/EventManager.luau +84 -0
- package/package.json +27 -0
- package/src/events/core/EventClass.ts +1 -0
- package/src/events/core/EventHandlerMeta.ts +9 -0
- package/src/events/core/EventHandlerOptions.ts +6 -0
- package/src/events/core/EventPriority.ts +8 -0
- package/src/events/core/NexusEvent.ts +11 -0
- package/src/events/core/metadata/NexusMetadata.ts +16 -0
- package/src/events/decorators/EventHandler.ts +30 -0
- package/src/events/handlers/player/PlayerJoinEvent.ts +12 -0
- package/src/events/handlers/player/PlayerLeaveEvent.ts +12 -0
- package/src/index.server.ts +11 -0
- package/src/interfaces/IListener.ts +1 -0
- package/src/server/Nexus.ts +29 -0
- package/src/server/managers/EventManager.ts +48 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type EventClass = new (...args: unknown[]) => object;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local NexusEvent
|
|
3
|
+
do
|
|
4
|
+
NexusEvent = {}
|
|
5
|
+
function NexusEvent:constructor()
|
|
6
|
+
self.cancelled = false
|
|
7
|
+
end
|
|
8
|
+
function NexusEvent:setCancelled(cancelled)
|
|
9
|
+
self.cancelled = cancelled
|
|
10
|
+
end
|
|
11
|
+
function NexusEvent:isCancelled()
|
|
12
|
+
return self.cancelled
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
return {
|
|
16
|
+
NexusEvent = NexusEvent,
|
|
17
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EventClass } from "../EventClass";
|
|
2
|
+
export declare class NexusMetadata {
|
|
3
|
+
private static readonly store;
|
|
4
|
+
static define(key: string, paramTypes: EventClass[], _target: object, methodName: string): void;
|
|
5
|
+
static getEventClass(methodName: string): EventClass | undefined;
|
|
6
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local NexusMetadata
|
|
3
|
+
do
|
|
4
|
+
NexusMetadata = setmetatable({}, {
|
|
5
|
+
__tostring = function()
|
|
6
|
+
return "NexusMetadata"
|
|
7
|
+
end,
|
|
8
|
+
})
|
|
9
|
+
NexusMetadata.__index = NexusMetadata
|
|
10
|
+
function NexusMetadata.new(...)
|
|
11
|
+
local self = setmetatable({}, NexusMetadata)
|
|
12
|
+
return self:constructor(...) or self
|
|
13
|
+
end
|
|
14
|
+
function NexusMetadata:constructor()
|
|
15
|
+
end
|
|
16
|
+
function NexusMetadata:define(key, paramTypes, _target, methodName)
|
|
17
|
+
if key ~= "paramtypes" then
|
|
18
|
+
return nil
|
|
19
|
+
end
|
|
20
|
+
if #paramTypes == 0 then
|
|
21
|
+
return nil
|
|
22
|
+
end
|
|
23
|
+
local _store = NexusMetadata.store
|
|
24
|
+
local _methodName = methodName
|
|
25
|
+
local _arg1 = paramTypes[1]
|
|
26
|
+
_store[_methodName] = _arg1
|
|
27
|
+
end
|
|
28
|
+
function NexusMetadata:getEventClass(methodName)
|
|
29
|
+
local _store = NexusMetadata.store
|
|
30
|
+
local _methodName = methodName
|
|
31
|
+
return _store[_methodName]
|
|
32
|
+
end
|
|
33
|
+
NexusMetadata.store = {}
|
|
34
|
+
end
|
|
35
|
+
return {
|
|
36
|
+
NexusMetadata = NexusMetadata,
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { EventHandlerOptions } from "../../events/core/EventHandlerOptions";
|
|
2
|
+
import { EventHandlerMeta } from "../../events/core/EventHandlerMeta";
|
|
3
|
+
export declare function EventHandler(options?: EventHandlerOptions): (target: object, methodName: string) => void;
|
|
4
|
+
export declare function getEventHandlerMetas(target: object): EventHandlerMeta[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local NexusMetadata = TS.import(script, script.Parent.Parent, "core", "metadata", "NexusMetadata").NexusMetadata
|
|
4
|
+
local EVENT_HANDLER_KEY = "__nexus_event_handlers__"
|
|
5
|
+
local function EventHandler(options)
|
|
6
|
+
return function(target, methodName)
|
|
7
|
+
local eventClass = NexusMetadata:getEventClass(methodName)
|
|
8
|
+
if eventClass == nil then
|
|
9
|
+
return nil
|
|
10
|
+
end
|
|
11
|
+
local _object = {
|
|
12
|
+
methodName = methodName,
|
|
13
|
+
eventClass = eventClass,
|
|
14
|
+
}
|
|
15
|
+
local _left = "async"
|
|
16
|
+
local _result = options
|
|
17
|
+
if _result ~= nil then
|
|
18
|
+
_result = _result.async
|
|
19
|
+
end
|
|
20
|
+
local _condition = _result
|
|
21
|
+
if _condition == nil then
|
|
22
|
+
_condition = false
|
|
23
|
+
end
|
|
24
|
+
_object[_left] = _condition
|
|
25
|
+
local _left_1 = "priority"
|
|
26
|
+
local _result_1 = options
|
|
27
|
+
if _result_1 ~= nil then
|
|
28
|
+
_result_1 = _result_1.priority
|
|
29
|
+
end
|
|
30
|
+
local _condition_1 = _result_1
|
|
31
|
+
if _condition_1 == nil then
|
|
32
|
+
_condition_1 = 2
|
|
33
|
+
end
|
|
34
|
+
_object[_left_1] = _condition_1
|
|
35
|
+
local meta = _object
|
|
36
|
+
local existing = target[EVENT_HANDLER_KEY] or {}
|
|
37
|
+
table.insert(existing, meta)
|
|
38
|
+
target[EVENT_HANDLER_KEY] = existing
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
local function getEventHandlerMetas(target)
|
|
42
|
+
return target[EVENT_HANDLER_KEY] or {}
|
|
43
|
+
end
|
|
44
|
+
return {
|
|
45
|
+
EventHandler = EventHandler,
|
|
46
|
+
getEventHandlerMetas = getEventHandlerMetas,
|
|
47
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local NexusEvent = TS.import(script, script.Parent.Parent.Parent, "core", "NexusEvent").NexusEvent
|
|
4
|
+
local PlayerJoinEvent
|
|
5
|
+
do
|
|
6
|
+
local super = NexusEvent
|
|
7
|
+
PlayerJoinEvent = setmetatable({}, {
|
|
8
|
+
__tostring = function()
|
|
9
|
+
return "PlayerJoinEvent"
|
|
10
|
+
end,
|
|
11
|
+
__index = super,
|
|
12
|
+
})
|
|
13
|
+
PlayerJoinEvent.__index = PlayerJoinEvent
|
|
14
|
+
function PlayerJoinEvent.new(...)
|
|
15
|
+
local self = setmetatable({}, PlayerJoinEvent)
|
|
16
|
+
return self:constructor(...) or self
|
|
17
|
+
end
|
|
18
|
+
function PlayerJoinEvent:constructor(player)
|
|
19
|
+
super.constructor(self)
|
|
20
|
+
self.player = player
|
|
21
|
+
end
|
|
22
|
+
function PlayerJoinEvent:getPlayer()
|
|
23
|
+
return self.player
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
return {
|
|
27
|
+
PlayerJoinEvent = PlayerJoinEvent,
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local NexusEvent = TS.import(script, script.Parent.Parent.Parent, "core", "NexusEvent").NexusEvent
|
|
4
|
+
local PlayerLeaveEvent
|
|
5
|
+
do
|
|
6
|
+
local super = NexusEvent
|
|
7
|
+
PlayerLeaveEvent = setmetatable({}, {
|
|
8
|
+
__tostring = function()
|
|
9
|
+
return "PlayerLeaveEvent"
|
|
10
|
+
end,
|
|
11
|
+
__index = super,
|
|
12
|
+
})
|
|
13
|
+
PlayerLeaveEvent.__index = PlayerLeaveEvent
|
|
14
|
+
function PlayerLeaveEvent.new(...)
|
|
15
|
+
local self = setmetatable({}, PlayerLeaveEvent)
|
|
16
|
+
return self:constructor(...) or self
|
|
17
|
+
end
|
|
18
|
+
function PlayerLeaveEvent:constructor(player)
|
|
19
|
+
super.constructor(self)
|
|
20
|
+
self.player = player
|
|
21
|
+
end
|
|
22
|
+
function PlayerLeaveEvent:getPlayer()
|
|
23
|
+
return self.player
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
return {
|
|
27
|
+
PlayerLeaveEvent = PlayerLeaveEvent,
|
|
28
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { Nexus } from './server/Nexus';
|
|
2
|
+
export { NexusEvent } from './events/core/NexusEvent';
|
|
3
|
+
export { NexusMetadata } from './events/core/metadata/NexusMetadata';
|
|
4
|
+
export { EventPriority } from './events/core/EventPriority';
|
|
5
|
+
export { EventHandler } from './events/decorators/EventHandler';
|
|
6
|
+
export { EventHandlerMeta } from './events/core/EventHandlerMeta';
|
|
7
|
+
export { EventHandlerOptions } from './events/core/EventHandlerOptions';
|
|
8
|
+
export { PlayerJoinEvent } from './events/handlers/player/PlayerJoinEvent';
|
|
9
|
+
export { PlayerLeaveEvent } from './events/handlers/player/PlayerLeaveEvent';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local exports = {}
|
|
4
|
+
exports.Nexus = TS.import(script, script, "server", "Nexus").Nexus
|
|
5
|
+
exports.NexusEvent = TS.import(script, script, "events", "core", "NexusEvent").NexusEvent
|
|
6
|
+
exports.NexusMetadata = TS.import(script, script, "events", "core", "metadata", "NexusMetadata").NexusMetadata
|
|
7
|
+
exports.EventHandler = TS.import(script, script, "events", "decorators", "EventHandler").EventHandler
|
|
8
|
+
exports.PlayerJoinEvent = TS.import(script, script, "events", "handlers", "player", "PlayerJoinEvent").PlayerJoinEvent
|
|
9
|
+
exports.PlayerLeaveEvent = TS.import(script, script, "events", "handlers", "player", "PlayerLeaveEvent").PlayerLeaveEvent
|
|
10
|
+
return exports
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EventManager } from "./managers/EventManager";
|
|
2
|
+
export declare abstract class Nexus {
|
|
3
|
+
private readonly eventManager;
|
|
4
|
+
private static instance;
|
|
5
|
+
constructor();
|
|
6
|
+
static getInstance<T extends Nexus>(): T;
|
|
7
|
+
getEventManager(): EventManager;
|
|
8
|
+
onEnable(): void;
|
|
9
|
+
onDisable(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
|
|
4
|
+
local EventManager = TS.import(script, script.Parent, "managers", "EventManager").EventManager
|
|
5
|
+
local Nexus
|
|
6
|
+
do
|
|
7
|
+
Nexus = {}
|
|
8
|
+
function Nexus:constructor()
|
|
9
|
+
self.eventManager = EventManager.new()
|
|
10
|
+
if not RunService:IsServer() then
|
|
11
|
+
error("Nexus can only be instantiated in server!")
|
|
12
|
+
end
|
|
13
|
+
if Nexus.instance ~= nil then
|
|
14
|
+
error("Nexus can only be instantiated once!")
|
|
15
|
+
end
|
|
16
|
+
Nexus.instance = self
|
|
17
|
+
game:BindToClose(function()
|
|
18
|
+
return self:onDisable()
|
|
19
|
+
end)
|
|
20
|
+
end
|
|
21
|
+
function Nexus:getInstance()
|
|
22
|
+
return Nexus.instance
|
|
23
|
+
end
|
|
24
|
+
function Nexus:getEventManager()
|
|
25
|
+
return self.eventManager
|
|
26
|
+
end
|
|
27
|
+
function Nexus:onEnable()
|
|
28
|
+
end
|
|
29
|
+
function Nexus:onDisable()
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
return {
|
|
33
|
+
Nexus = Nexus,
|
|
34
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NexusEvent } from "../../index.server";
|
|
2
|
+
import IListener from "../../interfaces/IListener";
|
|
3
|
+
export declare class EventManager {
|
|
4
|
+
private readonly handlers;
|
|
5
|
+
register(listener: IListener): void;
|
|
6
|
+
dispatch<T extends NexusEvent>(event: T): void;
|
|
7
|
+
private addHandler;
|
|
8
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local getEventHandlerMetas = TS.import(script, script.Parent.Parent.Parent, "events", "decorators", "EventHandler").getEventHandlerMetas
|
|
4
|
+
local EventManager
|
|
5
|
+
do
|
|
6
|
+
EventManager = setmetatable({}, {
|
|
7
|
+
__tostring = function()
|
|
8
|
+
return "EventManager"
|
|
9
|
+
end,
|
|
10
|
+
})
|
|
11
|
+
EventManager.__index = EventManager
|
|
12
|
+
function EventManager.new(...)
|
|
13
|
+
local self = setmetatable({}, EventManager)
|
|
14
|
+
return self:constructor(...) or self
|
|
15
|
+
end
|
|
16
|
+
function EventManager:constructor()
|
|
17
|
+
self.handlers = {}
|
|
18
|
+
end
|
|
19
|
+
function EventManager:register(listener)
|
|
20
|
+
local metas = getEventHandlerMetas(listener)
|
|
21
|
+
if #metas == 0 then
|
|
22
|
+
return nil
|
|
23
|
+
end
|
|
24
|
+
-- ▼ ReadonlyArray.forEach ▼
|
|
25
|
+
local _callback = function(meta)
|
|
26
|
+
return self:addHandler(meta.eventClass, {
|
|
27
|
+
listener = listener,
|
|
28
|
+
meta = meta,
|
|
29
|
+
})
|
|
30
|
+
end
|
|
31
|
+
for _k, _v in metas do
|
|
32
|
+
_callback(_v, _k - 1, metas)
|
|
33
|
+
end
|
|
34
|
+
-- ▲ ReadonlyArray.forEach ▲
|
|
35
|
+
return nil
|
|
36
|
+
end
|
|
37
|
+
function EventManager:dispatch(event)
|
|
38
|
+
local eventClass = getmetatable(event)
|
|
39
|
+
local registered = self.handlers[eventClass]
|
|
40
|
+
if registered == nil then
|
|
41
|
+
return nil
|
|
42
|
+
end
|
|
43
|
+
-- ▼ ReadonlyArray.forEach ▼
|
|
44
|
+
local _callback = function(_param)
|
|
45
|
+
local listener = _param.listener
|
|
46
|
+
local meta = _param.meta
|
|
47
|
+
if meta.priority == 5 and event:isCancelled() then
|
|
48
|
+
return nil
|
|
49
|
+
end
|
|
50
|
+
local method = listener[meta.methodName]
|
|
51
|
+
if meta.async then
|
|
52
|
+
task.defer(function()
|
|
53
|
+
return method(event)
|
|
54
|
+
end)
|
|
55
|
+
else
|
|
56
|
+
method(event)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
for _k, _v in registered do
|
|
60
|
+
_callback(_v, _k - 1, registered)
|
|
61
|
+
end
|
|
62
|
+
-- ▲ ReadonlyArray.forEach ▲
|
|
63
|
+
end
|
|
64
|
+
function EventManager:addHandler(eventClass, handler)
|
|
65
|
+
local _handlers = self.handlers
|
|
66
|
+
local _eventClass = eventClass
|
|
67
|
+
local _condition = _handlers[_eventClass]
|
|
68
|
+
if _condition == nil then
|
|
69
|
+
_condition = {}
|
|
70
|
+
end
|
|
71
|
+
local existing = _condition
|
|
72
|
+
local _handler = handler
|
|
73
|
+
table.insert(existing, _handler)
|
|
74
|
+
table.sort(existing, function(a, b)
|
|
75
|
+
return a.meta.priority < b.meta.priority
|
|
76
|
+
end)
|
|
77
|
+
local _handlers_1 = self.handlers
|
|
78
|
+
local _eventClass_1 = eventClass
|
|
79
|
+
_handlers_1[_eventClass_1] = existing
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
return {
|
|
83
|
+
EventManager = EventManager,
|
|
84
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@snailycfx/nexus",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "out/init.lua",
|
|
6
|
+
"types": "out/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rbxtsc",
|
|
9
|
+
"watch": "rbxtsc -w",
|
|
10
|
+
"prepublishOnly": "npm run build"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"packageManager": "pnpm@10.11.0",
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@rbxts/compiler-types": "3.0.0-types.0",
|
|
18
|
+
"@rbxts/types": "^1.0.911",
|
|
19
|
+
"roblox-ts": "^3.0.0",
|
|
20
|
+
"typescript": "^5.9.3"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@rbxts/services": "^1.6.0",
|
|
24
|
+
"@snailycfx/nexus-transformer": "^1.0.1",
|
|
25
|
+
"ts-patch": "^3.3.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type EventClass = new (...args: unknown[]) => object;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EventPriority } from "./EventPriority"
|
|
2
|
+
import { EventClass } from "./EventClass";
|
|
3
|
+
|
|
4
|
+
export interface EventHandlerMeta {
|
|
5
|
+
readonly methodName: string;
|
|
6
|
+
readonly eventClass: EventClass;
|
|
7
|
+
readonly async: boolean;
|
|
8
|
+
readonly priority: EventPriority;
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EventClass } from "../EventClass";
|
|
2
|
+
|
|
3
|
+
export class NexusMetadata {
|
|
4
|
+
private static readonly store = new Map<string, EventClass>();
|
|
5
|
+
|
|
6
|
+
public static define(key: string, paramTypes: EventClass[], _target: object, methodName: string): void {
|
|
7
|
+
if (key !== 'paramtypes') return;
|
|
8
|
+
if (paramTypes.size() === 0) return;
|
|
9
|
+
|
|
10
|
+
NexusMetadata.store.set(methodName, paramTypes[0]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public static getEventClass(methodName: string): EventClass | undefined {
|
|
14
|
+
return NexusMetadata.store.get(methodName);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EventHandlerOptions } from "../../events/core/EventHandlerOptions";
|
|
2
|
+
import { EventHandlerMeta } from "../../events/core/EventHandlerMeta";
|
|
3
|
+
import { EventPriority } from "../../events/core/EventPriority";
|
|
4
|
+
|
|
5
|
+
import { NexusMetadata } from "../../events/core/metadata/NexusMetadata";
|
|
6
|
+
|
|
7
|
+
const EVENT_HANDLER_KEY = '__nexus_event_handlers__';
|
|
8
|
+
|
|
9
|
+
export function EventHandler(options?: EventHandlerOptions) {
|
|
10
|
+
return (target: object, methodName: string) => {
|
|
11
|
+
const eventClass = NexusMetadata.getEventClass(methodName);
|
|
12
|
+
if (eventClass === undefined) return;
|
|
13
|
+
|
|
14
|
+
const meta: EventHandlerMeta = {
|
|
15
|
+
methodName,
|
|
16
|
+
eventClass,
|
|
17
|
+
async: options?.async ?? false,
|
|
18
|
+
priority: options?.priority ?? EventPriority.Normal
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const existing: EventHandlerMeta[] = (target as Record<string, unknown>)[EVENT_HANDLER_KEY] as EventHandlerMeta[] ?? [];
|
|
22
|
+
existing.push(meta);
|
|
23
|
+
|
|
24
|
+
(target as Record<string, unknown>)[EVENT_HANDLER_KEY] = existing;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function getEventHandlerMetas(target: object): EventHandlerMeta[] {
|
|
29
|
+
return (target as Record<string, unknown>)[EVENT_HANDLER_KEY] as EventHandlerMeta[] ?? [];
|
|
30
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NexusEvent } from "../../core/NexusEvent";
|
|
2
|
+
|
|
3
|
+
export class PlayerJoinEvent extends NexusEvent {
|
|
4
|
+
private readonly player: Player;
|
|
5
|
+
|
|
6
|
+
public constructor(player: Player) {
|
|
7
|
+
super();
|
|
8
|
+
this.player = player;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public getPlayer(): Player { return this.player; }
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NexusEvent } from "../../core/NexusEvent";
|
|
2
|
+
|
|
3
|
+
export class PlayerLeaveEvent extends NexusEvent {
|
|
4
|
+
private readonly player: Player;
|
|
5
|
+
|
|
6
|
+
public constructor(player: Player) {
|
|
7
|
+
super();
|
|
8
|
+
this.player = player;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public getPlayer(): Player { return this.player; }
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Nexus } from './server/Nexus';
|
|
2
|
+
export { NexusEvent } from './events/core/NexusEvent';
|
|
3
|
+
export { NexusMetadata } from './events/core/metadata/NexusMetadata';
|
|
4
|
+
|
|
5
|
+
export { EventPriority } from './events/core/EventPriority';
|
|
6
|
+
export { EventHandler } from './events/decorators/EventHandler';
|
|
7
|
+
export { EventHandlerMeta } from './events/core/EventHandlerMeta';
|
|
8
|
+
export { EventHandlerOptions } from './events/core/EventHandlerOptions';
|
|
9
|
+
|
|
10
|
+
export { PlayerJoinEvent } from './events/handlers/player/PlayerJoinEvent';
|
|
11
|
+
export { PlayerLeaveEvent } from './events/handlers/player/PlayerLeaveEvent';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default interface IListener {}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { RunService } from "@rbxts/services";
|
|
2
|
+
import { EventManager } from "./managers/EventManager";
|
|
3
|
+
|
|
4
|
+
export abstract class Nexus {
|
|
5
|
+
private readonly eventManager: EventManager = new EventManager();
|
|
6
|
+
private static instance: Nexus;
|
|
7
|
+
|
|
8
|
+
public constructor() {
|
|
9
|
+
if (!RunService.IsServer()) {
|
|
10
|
+
error('Nexus can only be instantiated in server!');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (Nexus.instance !== undefined) {
|
|
14
|
+
error('Nexus can only be instantiated once!');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Nexus.instance = this;
|
|
18
|
+
game.BindToClose(() => this.onDisable());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public static getInstance<T extends Nexus>(): T {
|
|
22
|
+
return Nexus.instance as T;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public getEventManager(): EventManager { return this.eventManager; }
|
|
26
|
+
|
|
27
|
+
public onEnable(): void {};
|
|
28
|
+
public onDisable(): void {};
|
|
29
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getEventHandlerMetas } from "../../events/decorators/EventHandler";
|
|
2
|
+
import { EventHandlerMeta, NexusEvent, EventPriority } from "../../index.server";
|
|
3
|
+
|
|
4
|
+
import { EventClass } from "../../events/core/EventClass";
|
|
5
|
+
import IListener from "../../interfaces/IListener";
|
|
6
|
+
|
|
7
|
+
interface RegisteredHandler {
|
|
8
|
+
readonly listener: IListener; // TODO: IListener
|
|
9
|
+
readonly meta: EventHandlerMeta;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class EventManager {
|
|
13
|
+
private readonly handlers = new Map<EventClass, RegisteredHandler[]>();
|
|
14
|
+
|
|
15
|
+
public register(listener: IListener): void {
|
|
16
|
+
const metas = getEventHandlerMetas(listener);
|
|
17
|
+
if (metas.size() === 0) return;
|
|
18
|
+
|
|
19
|
+
return metas.forEach((meta) => this.addHandler(meta.eventClass as EventClass, { listener, meta }));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public dispatch<T extends NexusEvent>(event: T): void {
|
|
23
|
+
const eventClass = getmetatable(event) as unknown as EventClass
|
|
24
|
+
const registered = this.handlers.get(eventClass)
|
|
25
|
+
if (registered === undefined) return
|
|
26
|
+
|
|
27
|
+
registered.forEach(({ listener, meta }) => {
|
|
28
|
+
if (meta.priority === EventPriority.Monitor && event.isCancelled()) return
|
|
29
|
+
|
|
30
|
+
const method = (listener as Record<string, unknown>)[meta.methodName] as (event: NexusEvent) => void
|
|
31
|
+
|
|
32
|
+
if (meta.async) {
|
|
33
|
+
task.defer(() => method(event))
|
|
34
|
+
} else {
|
|
35
|
+
method(event)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private addHandler(eventClass: EventClass, handler: RegisteredHandler): void {
|
|
41
|
+
const existing = this.handlers.get(eventClass) ?? [];
|
|
42
|
+
|
|
43
|
+
existing.push(handler);
|
|
44
|
+
existing.sort((a, b) => a.meta.priority < b.meta.priority);
|
|
45
|
+
|
|
46
|
+
this.handlers.set(eventClass, existing);
|
|
47
|
+
}
|
|
48
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowSyntheticDefaultImports": true,
|
|
4
|
+
"downlevelIteration": true,
|
|
5
|
+
"jsx": "react",
|
|
6
|
+
"jsxFactory": "React.createElement",
|
|
7
|
+
"jsxFragmentFactory": "React.Fragment",
|
|
8
|
+
"experimentalDecorators": true,
|
|
9
|
+
"module": "commonjs",
|
|
10
|
+
"moduleResolution": "Node",
|
|
11
|
+
"noLib": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"target": "ESNext",
|
|
15
|
+
"stripInternal": true,
|
|
16
|
+
"typeRoots": ["node_modules/@rbxts"],
|
|
17
|
+
"moduleDetection": "force",
|
|
18
|
+
"declaration": true,
|
|
19
|
+
"rootDir": "src",
|
|
20
|
+
"outDir": "out",
|
|
21
|
+
"plugins": [
|
|
22
|
+
{ "transform": "@snailycfx/nexus-transformer" }
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"include": ["src"]
|
|
26
|
+
}
|