增加事件总线
This commit is contained in:
373
AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js
Normal file
373
AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user