初次提交
This commit is contained in:
264
source/tools/broadcast-tools.ts
Normal file
264
source/tools/broadcast-tools.ts
Normal file
@@ -0,0 +1,264 @@
|
||||
import { ToolDefinition, ToolResponse, ToolExecutor } from '../types';
|
||||
|
||||
export class BroadcastTools implements ToolExecutor {
|
||||
private listeners: Map<string, Function[]> = new Map();
|
||||
private messageLog: Array<{ message: string; data: any; timestamp: number }> = [];
|
||||
|
||||
constructor() {
|
||||
this.setupBroadcastListeners();
|
||||
}
|
||||
|
||||
getTools(): ToolDefinition[] {
|
||||
return [
|
||||
{
|
||||
name: 'get_broadcast_log',
|
||||
description: 'Get recent broadcast messages log',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
limit: {
|
||||
type: 'number',
|
||||
description: 'Number of recent messages to return',
|
||||
default: 50
|
||||
},
|
||||
messageType: {
|
||||
type: 'string',
|
||||
description: 'Filter by message type (optional)'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'listen_broadcast',
|
||||
description: 'Start listening for specific broadcast messages',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
messageType: {
|
||||
type: 'string',
|
||||
description: 'Message type to listen for'
|
||||
}
|
||||
},
|
||||
required: ['messageType']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'stop_listening',
|
||||
description: 'Stop listening for specific broadcast messages',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
messageType: {
|
||||
type: 'string',
|
||||
description: 'Message type to stop listening for'
|
||||
}
|
||||
},
|
||||
required: ['messageType']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'clear_broadcast_log',
|
||||
description: 'Clear the broadcast messages log',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'get_active_listeners',
|
||||
description: 'Get list of active broadcast listeners',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {}
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
async execute(toolName: string, args: any): Promise<ToolResponse> {
|
||||
switch (toolName) {
|
||||
case 'get_broadcast_log':
|
||||
return await this.getBroadcastLog(args.limit, args.messageType);
|
||||
case 'listen_broadcast':
|
||||
return await this.listenBroadcast(args.messageType);
|
||||
case 'stop_listening':
|
||||
return await this.stopListening(args.messageType);
|
||||
case 'clear_broadcast_log':
|
||||
return await this.clearBroadcastLog();
|
||||
case 'get_active_listeners':
|
||||
return await this.getActiveListeners();
|
||||
default:
|
||||
throw new Error(`Unknown tool: ${toolName}`);
|
||||
}
|
||||
}
|
||||
|
||||
private setupBroadcastListeners(): void {
|
||||
// 设置预定义的重要广播消息监听
|
||||
const importantMessages = [
|
||||
'build-worker:ready',
|
||||
'build-worker:closed',
|
||||
'scene:ready',
|
||||
'scene:close',
|
||||
'scene:light-probe-edit-mode-changed',
|
||||
'scene:light-probe-bounding-box-edit-mode-changed',
|
||||
'asset-db:ready',
|
||||
'asset-db:close',
|
||||
'asset-db:asset-add',
|
||||
'asset-db:asset-change',
|
||||
'asset-db:asset-delete'
|
||||
];
|
||||
|
||||
importantMessages.forEach(messageType => {
|
||||
this.addBroadcastListener(messageType);
|
||||
});
|
||||
}
|
||||
|
||||
private addBroadcastListener(messageType: string): void {
|
||||
const listener = (data: any) => {
|
||||
this.messageLog.push({
|
||||
message: messageType,
|
||||
data: data,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
// 保持日志大小在合理范围内
|
||||
if (this.messageLog.length > 1000) {
|
||||
this.messageLog = this.messageLog.slice(-500);
|
||||
}
|
||||
|
||||
console.log(`[Broadcast] ${messageType}:`, data);
|
||||
};
|
||||
|
||||
if (!this.listeners.has(messageType)) {
|
||||
this.listeners.set(messageType, []);
|
||||
}
|
||||
this.listeners.get(messageType)!.push(listener);
|
||||
|
||||
// 注册 Editor 消息监听 - 暂时注释掉,Editor.Message API可能不支持
|
||||
// Editor.Message.on(messageType, listener);
|
||||
console.log(`[BroadcastTools] Added listener for ${messageType} (simulated)`);
|
||||
}
|
||||
|
||||
private removeBroadcastListener(messageType: string): void {
|
||||
const listeners = this.listeners.get(messageType);
|
||||
if (listeners) {
|
||||
listeners.forEach(listener => {
|
||||
// Editor.Message.off(messageType, listener);
|
||||
console.log(`[BroadcastTools] Removed listener for ${messageType} (simulated)`);
|
||||
});
|
||||
this.listeners.delete(messageType);
|
||||
}
|
||||
}
|
||||
|
||||
private async getBroadcastLog(limit: number = 50, messageType?: string): Promise<ToolResponse> {
|
||||
return new Promise((resolve) => {
|
||||
let filteredLog = this.messageLog;
|
||||
|
||||
if (messageType) {
|
||||
filteredLog = this.messageLog.filter(entry => entry.message === messageType);
|
||||
}
|
||||
|
||||
const recentLog = filteredLog.slice(-limit).map(entry => ({
|
||||
...entry,
|
||||
timestamp: new Date(entry.timestamp).toISOString()
|
||||
}));
|
||||
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
log: recentLog,
|
||||
count: recentLog.length,
|
||||
totalCount: filteredLog.length,
|
||||
filter: messageType || 'all',
|
||||
message: 'Broadcast log retrieved successfully'
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async listenBroadcast(messageType: string): Promise<ToolResponse> {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
if (!this.listeners.has(messageType)) {
|
||||
this.addBroadcastListener(messageType);
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
messageType: messageType,
|
||||
message: `Started listening for broadcast: ${messageType}`
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
messageType: messageType,
|
||||
message: `Already listening for broadcast: ${messageType}`
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err: any) {
|
||||
resolve({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async stopListening(messageType: string): Promise<ToolResponse> {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
if (this.listeners.has(messageType)) {
|
||||
this.removeBroadcastListener(messageType);
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
messageType: messageType,
|
||||
message: `Stopped listening for broadcast: ${messageType}`
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
messageType: messageType,
|
||||
message: `Was not listening for broadcast: ${messageType}`
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err: any) {
|
||||
resolve({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async clearBroadcastLog(): Promise<ToolResponse> {
|
||||
return new Promise((resolve) => {
|
||||
const previousCount = this.messageLog.length;
|
||||
this.messageLog = [];
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
clearedCount: previousCount,
|
||||
message: 'Broadcast log cleared successfully'
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async getActiveListeners(): Promise<ToolResponse> {
|
||||
return new Promise((resolve) => {
|
||||
const activeListeners = Array.from(this.listeners.keys()).map(messageType => ({
|
||||
messageType: messageType,
|
||||
listenerCount: this.listeners.get(messageType)?.length || 0
|
||||
}));
|
||||
|
||||
resolve({
|
||||
success: true,
|
||||
data: {
|
||||
listeners: activeListeners,
|
||||
count: activeListeners.length,
|
||||
message: 'Active listeners retrieved successfully'
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user