refactor: EventEmitter3

This commit is contained in:
RainbowBird
2025-01-09 13:14:39 +08:00
parent 244361a11c
commit 8381f2da08
2 changed files with 13 additions and 29 deletions
@@ -3,6 +3,7 @@ import type { Message } from 'neuri/openai'
import type { z } from 'zod'
import type { MineflayerPlugin } from './plugin'
import { useLogg } from '@guiiai/logg'
import EventEmitter from 'eventemitter3'
import mineflayer from 'mineflayer'
import { type CommandContext, parseCommand } from './command'
import { formBotChat } from './message'
@@ -26,16 +27,6 @@ export type EventsHandler<K extends Events> = EventHandlers[K]
export type Handler = (ctx: Context) => void | Promise<void>
function createEventHandlers(): Record<Events, Array<EventsHandler<Events>>> {
return {
'command': [],
'time:sunrise': [],
'time:noon': [],
'time:sunset': [],
'time:midnight': [],
}
}
export class Health {
public value: number
public lastDamageTime?: number
@@ -133,7 +124,7 @@ export interface MineflayerOptions {
plugins?: Array<MineflayerPlugin>
}
export class Mineflayer {
export class Mineflayer extends EventEmitter<EventHandlers> {
public bot: Bot
public username: string
public health: Health = new Health()
@@ -149,10 +140,10 @@ export class Mineflayer {
private options: MineflayerOptions
private logger: ReturnType<typeof useLogg>
private commands: Map<string, EventsHandler<'command'>> = new Map()
private eventHandlers = createEventHandlers()
private ticker: Ticker = new Ticker()
constructor(options: MineflayerOptions) {
super()
this.options = options
this.bot = mineflayer.createBot(options.botConfig)
this.username = options.botConfig.username
@@ -277,10 +268,7 @@ export class Mineflayer {
}
public emit<E extends Events>(event: E, ...args: Parameters<EventsHandler<E>>) {
const handlers = this.eventHandlers[event]
for (const handler of handlers) {
handler(args[0])
}
return super.emit(event, ...args)
}
public async stop() {
@@ -292,6 +280,7 @@ export class Mineflayer {
this.components.cleanup()
this.bot.removeListener('chat', this.handleCommand())
this.bot.end()
this.removeAllListeners()
}
private handleCommand() {
@@ -1,3 +1,5 @@
import EventEmitter from 'eventemitter3'
export interface TickContext {
delta: number
nextTick: () => Promise<void>
@@ -11,29 +13,23 @@ export type TickEvents = keyof TickEventHandlers
export type TickEventsHandler<K extends TickEvents> = TickEventHandlers[K]
// This update loop ensures that each update() is called one at a time, even if it takes longer than the interval
export class Ticker {
private tickingCbs: Record<TickEvents, Array<TickEventHandlers[TickEvents]>> = {
tick: [],
}
export class Ticker extends EventEmitter<TickEventHandlers> {
constructor(options?: { interval?: number }) {
super()
const { interval = 300 } = options ?? { interval: 300 }
let last = Date.now()
const tickingCbs: Record<TickEvents, Array<TickEventHandlers[TickEvents]>> = {
tick: [],
}
setTimeout(async () => {
while (true) {
const start = Date.now()
const nextTickPromise = new Promise<void>((resolve) => {
// Schedule nextTick resolution for after all callbacks complete
// Schedule nextTick resolution for after all callbacks complete
setImmediate(resolve)
})
// Run all callbacks without awaiting them
const callbackPromises = tickingCbs.tick.map(cb => cb({
const callbackPromises = this.listeners('tick').map(cb => cb({
delta: start - last,
nextTick: () => nextTickPromise,
}))
@@ -47,9 +43,8 @@ export class Ticker {
])
const remaining = interval - (Date.now() - start)
if (remaining > 0) {
if (remaining > 0)
await new Promise(resolve => setTimeout(resolve, remaining))
}
last = start
}
@@ -57,6 +52,6 @@ export class Ticker {
}
on<K extends TickEvents>(event: K, cb: TickEventsHandler<K>) {
this.tickingCbs[event].push(cb)
return super.on(event, cb)
}
}