增加事件总线

This commit is contained in:
zqm
2025-11-19 16:44:59 +08:00
parent 986c659195
commit f978a42990

View File

@@ -0,0 +1,373 @@
import { mitt } from 'mitt'
import { nanoid } from 'nanoid'
// 事件类型常量
export const EVENT_TYPES = {
// 区域事件
AREA_CLOSE: 'area.close',
AREA_POSITION_UPDATE: 'area.position.update',
AREA_DRAG_START: 'area.drag.start',
AREA_DRAG_MOVE: 'area.drag.move',
AREA_DRAG_END: 'area.drag.end',
AREA_DRAG_OVER: 'area.drag.over',
AREA_DRAG_LEAVE: 'area.drag.leave',
AREA_PANEL_CLOSED: 'area.panel.closed',
// 面板事件
PANEL_MAXIMIZE_SYNC: 'panel.maximize.sync',
PANEL_MAXIMIZE: 'panel.maximize',
PANEL_CLOSE: 'panel.close',
PANEL_CLOSE_REQUEST: 'panel.close.request',
PANEL_CLOSED: 'panel.closed',
PANEL_TOGGLE_COLLAPSE: 'panel.toggleCollapse',
PANEL_TOGGLE_TOOLBAR: 'panel.toggleToolbar',
// 面板拖拽事件
PANEL_DRAG_START: 'panel.drag.start',
PANEL_DRAG_MOVE: 'panel.drag.move',
PANEL_DRAG_END: 'panel.drag.end',
PANEL_DRAG_START_FROM_TABPAGE: 'panel.drag.start.fromTabPage',
PANEL_DRAG_MOVE_FROM_TABPAGE: 'panel.drag.move.fromTabPage',
PANEL_DRAG_END_FROM_TABPAGE: 'panel.drag.end.fromTabPage',
// 标签页事件
TAB_CHANGE: 'tab.change',
TAB_CLOSE: 'tab.close',
TAB_ADD: 'tab.add',
TAB_DRAG_START: 'tab.drag.start',
TAB_DRAG_MOVE: 'tab.drag.move',
TAB_DRAG_END: 'tab.drag.end',
// 指示器事件
INDICATOR_SHOW: 'indicator.show',
INDICATOR_HIDE: 'indicator.hide',
INDICATOR_UPDATE: 'indicator.update',
// 调整大小事件
RESIZE_START: 'resize.start',
RESIZE_MOVE: 'resize.move',
RESIZE_END: 'resize.end',
// 窗口状态事件
WINDOW_STATE_CHANGE: 'window.state.change',
Z_INDEX_UPDATE: 'zIndex.update'
}
// 增强的事件总线类
class EnhancedEventBus {
constructor() {
this.bus = mitt()
this.instanceId = nanoid()
this.debugMode = false
this.eventHistory = []
this.maxHistorySize = 100
}
/**
* 启用/禁用调试模式
*/
setDebugMode(enabled) {
this.debugMode = enabled
}
/**
* 订阅事件
*/
on(eventType, callback, options = {}) {
const unsubscribe = this.bus.on(eventType, (data) => {
const event = {
id: nanoid(),
type: eventType,
data,
timestamp: Date.now(),
source: {
instanceId: this.instanceId,
...options.source
}
}
if (this.debugMode) {
console.log(`[EventBus] ${eventType} event received:`, event)
}
// 记录事件历史
this.recordEvent(event)
try {
callback(event.data, event)
} catch (error) {
console.error(`[EventBus] Error in event listener for ${eventType}:`, error)
}
})
// 返回增强的取消订阅函数
return () => {
unsubscribe()
}
}
/**
* 触发事件
*/
emit(eventType, data, options = {}) {
const event = {
id: nanoid(),
type: eventType,
data,
timestamp: Date.now(),
source: {
instanceId: this.instanceId,
...options.source
}
}
if (this.debugMode) {
console.log(`[EventBus] Emitting ${eventType}:`, event)
}
this.recordEvent(event)
this.bus.emit(eventType, data)
return event
}
/**
* 触发一次性事件
*/
once(eventType, callback, options = {}) {
const unsubscribe = this.on(eventType, (data, event) => {
callback(data, event)
unsubscribe()
}, options)
return unsubscribe
}
/**
* 取消订阅
*/
off(eventType, callback) {
this.bus.off(eventType, callback)
}
/**
* 清除所有监听器
*/
clear() {
this.bus.all.clear()
this.eventHistory = []
}
/**
* 记录事件历史
*/
recordEvent(event) {
this.eventHistory.push(event)
// 限制历史记录大小
if (this.eventHistory.length > this.maxHistorySize) {
this.eventHistory.shift()
}
}
/**
* 获取事件历史
*/
getEventHistory(limit = 20) {
return this.eventHistory.slice(-limit)
}
/**
* 获取监听器统计
*/
getStats() {
const stats = {}
for (const [eventType, listeners] of this.bus.all.entries()) {
stats[eventType] = Array.isArray(listeners) ? listeners.length : 1
}
return stats
}
}
// 创建全局事件总线实例
export const eventBus = new EnhancedEventBus()
// 拖拽状态管理器
export class DragStateManager {
constructor(eventBus) {
this.eventBus = eventBus
this.dragStates = new Map()
}
/**
* 开始拖拽
*/
startDrag(dragInfo) {
const { type, id, event } = dragInfo
this.dragStates.set(id, {
type,
startTime: Date.now(),
initialPosition: { x: event.clientX, y: event.clientY },
currentPosition: { x: event.clientX, y: event.clientY },
isActive: true
})
// 触发拖拽开始事件
const eventType = `${type}.drag.start`
this.eventBus.emit(eventType, {
id,
position: { x: event.clientX, y: event.clientY },
initialPosition: { x: event.clientX, y: event.clientY }
})
return id
}
/**
* 拖拽移动
*/
moveDrag(id, event) {
const dragState = this.dragStates.get(id)
if (!dragState || !dragState.isActive) return
dragState.currentPosition = { x: event.clientX, y: event.clientY }
const delta = {
x: event.clientX - dragState.initialPosition.x,
y: event.clientY - dragState.initialPosition.y
}
// 触发拖拽移动事件
const eventType = `${dragState.type}.drag.move`
this.eventBus.emit(eventType, {
id,
position: dragState.currentPosition,
delta,
startTime: dragState.startTime
})
}
/**
* 结束拖拽
*/
endDrag(id, event) {
const dragState = this.dragStates.get(id)
if (!dragState) return
dragState.isActive = false
dragState.endTime = Date.now()
dragState.finalPosition = { x: event.clientX, y: event.clientY }
// 触发拖拽结束事件
const eventType = `${dragState.type}.drag.end`
this.eventBus.emit(eventType, {
id,
position: dragState.finalPosition,
initialPosition: dragState.initialPosition,
duration: dragState.endTime - dragState.startTime
})
// 清理拖拽状态
setTimeout(() => {
this.dragStates.delete(id)
}, 100)
return dragState
}
/**
* 获取拖拽状态
*/
getDragState(id) {
return this.dragStates.get(id)
}
/**
* 检查是否有活动的拖拽
*/
hasActiveDrag(id = null) {
if (id) {
const state = this.dragStates.get(id)
return state && state.isActive
}
for (const state of this.dragStates.values()) {
if (state.isActive) return true
}
return false
}
/**
* 取消所有拖拽
*/
cancelAllDrags() {
for (const [id, state] of this.dragStates.entries()) {
if (state.isActive) {
this.endDrag(id, {
clientX: state.currentPosition.x,
clientY: state.currentPosition.y
})
}
}
}
}
// 创建拖拽状态管理器实例
export const dragStateManager = new DragStateManager(eventBus)
// 便捷的拖拽事件触发函数
export const triggerDragEvent = {
area: {
start: (areaId, event) => {
return dragStateManager.startDrag({ type: 'area', id: areaId, event })
},
move: (areaId, event) => {
dragStateManager.moveDrag(areaId, event)
},
end: (areaId, event) => {
dragStateManager.endDrag(areaId, event)
}
},
tab: {
start: (tabId, event) => {
return dragStateManager.startDrag({ type: 'tab', id: tabId, event })
},
move: (tabId, event) => {
dragStateManager.moveDrag(tabId, event)
},
end: (tabId, event) => {
dragStateManager.endDrag(tabId, event)
}
},
panel: {
start: (panelId, event) => {
return dragStateManager.startDrag({ type: 'panel', id: panelId, event })
},
move: (panelId, event) => {
dragStateManager.moveDrag(panelId, event)
},
end: (panelId, event) => {
dragStateManager.endDrag(panelId, event)
}
}
}
// 导出便捷触发函数
export const emitEvent = (eventType, data, options = {}) => {
return eventBus.emit(eventType, data, options)
}
export const onEvent = (eventType, callback, options = {}) => {
return eventBus.on(eventType, callback, options)
}
export const onceEvent = (eventType, callback, options = {}) => {
return eventBus.once(eventType, callback, options)
}
export const offEvent = (eventType, callback) => {
return eventBus.off(eventType, callback)
}