@threejs-shared/protobuf 0.1.2 → 0.1.4
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/dist/ProtoBufManager.d.ts +71 -0
- package/dist/ProtoBufManager.d.ts.map +1 -0
- package/dist/ProtoBufManager.js +266 -0
- package/dist/ProtoBufManager.js.map +1 -0
- package/dist/ProtobufPlaybackClient.d.ts +118 -0
- package/dist/ProtobufPlaybackClient.d.ts.map +1 -0
- package/dist/ProtobufPlaybackClient.js +185 -0
- package/dist/ProtobufPlaybackClient.js.map +1 -0
- package/dist/ProtobufWebSocketClient.d.ts +80 -0
- package/dist/ProtobufWebSocketClient.d.ts.map +1 -0
- package/dist/ProtobufWebSocketClient.js +94 -0
- package/dist/ProtobufWebSocketClient.js.map +1 -0
- package/dist/TimerManager.d.ts +26 -0
- package/dist/TimerManager.d.ts.map +1 -0
- package/dist/TimerManager.js +93 -0
- package/dist/TimerManager.js.map +1 -0
- package/dist/WebSocketManager.d.ts +119 -0
- package/dist/WebSocketManager.d.ts.map +1 -0
- package/dist/WebSocketManager.js +302 -0
- package/dist/WebSocketManager.js.map +1 -0
- package/{src/index.ts → dist/index.d.ts} +13 -13
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +9 -9
- package/src/ProtoBufManager.ts +0 -311
- package/src/ProtobufPlaybackClient.ts +0 -238
- package/src/ProtobufWebSocketClient.ts +0 -125
- package/src/TimerManager.ts +0 -103
- package/src/WebSocketManager.ts +0 -352
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ProtobufType } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* ProtoBufManager 配置选项
|
|
4
|
+
*/
|
|
5
|
+
export interface ProtoBufManagerOptions {
|
|
6
|
+
/** 是否启用日志 */
|
|
7
|
+
enableLog?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Protobuf 管理器,用于加载和缓存 proto 文件
|
|
11
|
+
*
|
|
12
|
+
* 特性:
|
|
13
|
+
* - 自动缓存已加载的 proto 类型,避免重复加载
|
|
14
|
+
* - 并发请求控制,同一 proto 文件的多次请求会共享同一个 Promise
|
|
15
|
+
* - 完善的错误处理和参数验证
|
|
16
|
+
* - 可配置的日志输出
|
|
17
|
+
*/
|
|
18
|
+
export declare class ProtoBufManager {
|
|
19
|
+
/** 已加载的 proto 类型缓存 */
|
|
20
|
+
private protoCache;
|
|
21
|
+
/** 正在加载的 Promise 缓存,用于并发控制 */
|
|
22
|
+
private loadingPromises;
|
|
23
|
+
/** 配置选项 */
|
|
24
|
+
private options;
|
|
25
|
+
constructor(options?: ProtoBufManagerOptions);
|
|
26
|
+
/**
|
|
27
|
+
* 加载 proto 文件并获取指定的消息类型
|
|
28
|
+
*
|
|
29
|
+
* @param protoFilePath proto 文件的路径(URL)
|
|
30
|
+
* @param messageType 消息类型名称(例如:'protobuf.WsFrameData' 或 'SimulationMonitor.SimulationMonitorMsg')
|
|
31
|
+
* @returns Promise<ProtobufType> 解析后的消息类型
|
|
32
|
+
* @throws {Error} 如果参数无效、文件加载失败、解析失败或消息类型不存在
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const manager = new ProtoBufManager()
|
|
37
|
+
* const messageType = await manager.loadProto('/proto/SimulationMonitor.proto', 'SimulationMonitor.SimulationMonitorMsg')
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
loadProto(protoFilePath: string, messageType: string): Promise<ProtobufType>;
|
|
41
|
+
/**
|
|
42
|
+
* 内部加载方法
|
|
43
|
+
*/
|
|
44
|
+
private loadProtoInternal;
|
|
45
|
+
/**
|
|
46
|
+
* 清除缓存
|
|
47
|
+
* @param protoFilePath 可选的 proto 文件路径,如果提供则只清除该文件的缓存,否则清除所有缓存
|
|
48
|
+
*/
|
|
49
|
+
clearCache(protoFilePath?: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* 获取缓存的大小
|
|
52
|
+
*/
|
|
53
|
+
getCacheSize(): number;
|
|
54
|
+
/**
|
|
55
|
+
* 检查指定 proto 类型是否已缓存
|
|
56
|
+
* @param protoFilePath proto 文件路径
|
|
57
|
+
* @param messageType 消息类型名称
|
|
58
|
+
* @returns 是否已缓存
|
|
59
|
+
*/
|
|
60
|
+
isCached(protoFilePath: string, messageType: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* 获取所有已缓存的 proto 文件路径
|
|
63
|
+
* @returns 已缓存的 proto 文件路径数组
|
|
64
|
+
*/
|
|
65
|
+
getCachedProtoFiles(): string[];
|
|
66
|
+
/**
|
|
67
|
+
* 日志输出
|
|
68
|
+
*/
|
|
69
|
+
private log;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=ProtoBufManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtoBufManager.d.ts","sourceRoot":"","sources":["../src/ProtoBufManager.ts"],"names":[],"mappings":"AAkEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAG3C;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B,sBAAsB;IACtB,OAAO,CAAC,UAAU,CAAuC;IACzD,8BAA8B;IAC9B,OAAO,CAAC,eAAe,CAAgD;IACvE,WAAW;IACX,OAAO,CAAC,OAAO,CAAkC;gBAErC,OAAO,CAAC,EAAE,sBAAsB;IAM5C;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAsClF;;OAEG;YACW,iBAAiB;IAwF/B;;;OAGG;IACH,UAAU,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAoBxC;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAK7D;;;OAGG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAS/B;;OAEG;IACH,OAAO,CAAC,GAAG;CAUZ"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// import protobuf from 'protobufjs'
|
|
2
|
+
// /**
|
|
3
|
+
// * Protobuf 管理器,用于加载和缓存 proto 文件
|
|
4
|
+
// */
|
|
5
|
+
// export class ProtoBufManager {
|
|
6
|
+
// private protoCache: Map<string, protobuf.Type> = new Map()
|
|
7
|
+
// /**
|
|
8
|
+
// * 加载 proto 文件并获取指定的消息类型
|
|
9
|
+
// * @param protoFilePath proto 文件的路径(URL)
|
|
10
|
+
// * @param messageType 消息类型名称(例如:'protobuf.WsFrameData')
|
|
11
|
+
// * @returns Promise<protobuf.Type> 解析后的消息类型
|
|
12
|
+
// */
|
|
13
|
+
// async loadProto(protoFilePath: string, messageType: string): Promise<protobuf.Type> {
|
|
14
|
+
// const cacheKey = `${protoFilePath}-${messageType}`
|
|
15
|
+
// if (this.protoCache.has(cacheKey)) {
|
|
16
|
+
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17
|
+
// return this.protoCache.get(cacheKey)!
|
|
18
|
+
// }
|
|
19
|
+
// try {
|
|
20
|
+
// const response = await fetch(protoFilePath)
|
|
21
|
+
// if (!response.ok) {
|
|
22
|
+
// throw new Error(`Failed to fetch proto file: ${response.statusText}`)
|
|
23
|
+
// }
|
|
24
|
+
// const content = await response.text()
|
|
25
|
+
// const root = protobuf.parse(content).root
|
|
26
|
+
// const messageTypeDefinition = root.lookupType(messageType)
|
|
27
|
+
// if (!messageTypeDefinition) {
|
|
28
|
+
// throw new Error(`Message type '${messageType}' not found in proto file`)
|
|
29
|
+
// }
|
|
30
|
+
// this.protoCache.set(cacheKey, messageTypeDefinition)
|
|
31
|
+
// return messageTypeDefinition
|
|
32
|
+
// } catch (error) {
|
|
33
|
+
// console.error('Error loading proto file:', error)
|
|
34
|
+
// throw error
|
|
35
|
+
// }
|
|
36
|
+
// }
|
|
37
|
+
// /**
|
|
38
|
+
// * 清除缓存
|
|
39
|
+
// * @param protoFilePath 可选的 proto 文件路径,如果提供则只清除该文件的缓存,否则清除所有缓存
|
|
40
|
+
// */
|
|
41
|
+
// clearCache(protoFilePath?: string): void {
|
|
42
|
+
// if (protoFilePath) {
|
|
43
|
+
// const keysToDelete: string[] = []
|
|
44
|
+
// this.protoCache.forEach((_, key) => {
|
|
45
|
+
// if (key.startsWith(protoFilePath)) {
|
|
46
|
+
// keysToDelete.push(key)
|
|
47
|
+
// }
|
|
48
|
+
// })
|
|
49
|
+
// keysToDelete.forEach(key => this.protoCache.delete(key))
|
|
50
|
+
// } else {
|
|
51
|
+
// this.protoCache.clear()
|
|
52
|
+
// }
|
|
53
|
+
// }
|
|
54
|
+
// /**
|
|
55
|
+
// * 获取缓存的大小
|
|
56
|
+
// */
|
|
57
|
+
// getCacheSize(): number {
|
|
58
|
+
// return this.protoCache.size
|
|
59
|
+
// }
|
|
60
|
+
// }
|
|
61
|
+
import * as protobuf from 'protobufjs';
|
|
62
|
+
/**
|
|
63
|
+
* Protobuf 管理器,用于加载和缓存 proto 文件
|
|
64
|
+
*
|
|
65
|
+
* 特性:
|
|
66
|
+
* - 自动缓存已加载的 proto 类型,避免重复加载
|
|
67
|
+
* - 并发请求控制,同一 proto 文件的多次请求会共享同一个 Promise
|
|
68
|
+
* - 完善的错误处理和参数验证
|
|
69
|
+
* - 可配置的日志输出
|
|
70
|
+
*/
|
|
71
|
+
export class ProtoBufManager {
|
|
72
|
+
constructor(options) {
|
|
73
|
+
var _a;
|
|
74
|
+
/** 已加载的 proto 类型缓存 */
|
|
75
|
+
this.protoCache = new Map();
|
|
76
|
+
/** 正在加载的 Promise 缓存,用于并发控制 */
|
|
77
|
+
this.loadingPromises = new Map();
|
|
78
|
+
this.options = {
|
|
79
|
+
enableLog: (_a = options === null || options === void 0 ? void 0 : options.enableLog) !== null && _a !== void 0 ? _a : true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 加载 proto 文件并获取指定的消息类型
|
|
84
|
+
*
|
|
85
|
+
* @param protoFilePath proto 文件的路径(URL)
|
|
86
|
+
* @param messageType 消息类型名称(例如:'protobuf.WsFrameData' 或 'SimulationMonitor.SimulationMonitorMsg')
|
|
87
|
+
* @returns Promise<ProtobufType> 解析后的消息类型
|
|
88
|
+
* @throws {Error} 如果参数无效、文件加载失败、解析失败或消息类型不存在
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const manager = new ProtoBufManager()
|
|
93
|
+
* const messageType = await manager.loadProto('/proto/SimulationMonitor.proto', 'SimulationMonitor.SimulationMonitorMsg')
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
async loadProto(protoFilePath, messageType) {
|
|
97
|
+
// 参数验证
|
|
98
|
+
if (!protoFilePath || typeof protoFilePath !== 'string') {
|
|
99
|
+
throw new Error('protoFilePath must be a non-empty string');
|
|
100
|
+
}
|
|
101
|
+
if (!messageType || typeof messageType !== 'string') {
|
|
102
|
+
throw new Error('messageType must be a non-empty string');
|
|
103
|
+
}
|
|
104
|
+
const cacheKey = `${protoFilePath}-${messageType}`;
|
|
105
|
+
// 如果已缓存,直接返回
|
|
106
|
+
if (this.protoCache.has(cacheKey)) {
|
|
107
|
+
this.log(`Using cached proto type: ${messageType}`);
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
109
|
+
return this.protoCache.get(cacheKey);
|
|
110
|
+
}
|
|
111
|
+
// 如果正在加载,返回同一个 Promise(并发控制)
|
|
112
|
+
if (this.loadingPromises.has(cacheKey)) {
|
|
113
|
+
this.log(`Proto file is already loading: ${protoFilePath}, waiting...`);
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
115
|
+
return this.loadingPromises.get(cacheKey);
|
|
116
|
+
}
|
|
117
|
+
// 创建加载 Promise
|
|
118
|
+
const loadPromise = this.loadProtoInternal(protoFilePath, messageType, cacheKey);
|
|
119
|
+
this.loadingPromises.set(cacheKey, loadPromise);
|
|
120
|
+
try {
|
|
121
|
+
const result = await loadPromise;
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
// 加载完成后移除 Promise 缓存
|
|
126
|
+
this.loadingPromises.delete(cacheKey);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 内部加载方法
|
|
131
|
+
*/
|
|
132
|
+
async loadProtoInternal(protoFilePath, messageType, cacheKey) {
|
|
133
|
+
try {
|
|
134
|
+
this.log(`Loading proto file: ${protoFilePath}`);
|
|
135
|
+
// 1. 获取 proto 文件内容
|
|
136
|
+
let response;
|
|
137
|
+
try {
|
|
138
|
+
response = await fetch(protoFilePath);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new Error(`Failed to fetch proto file from "${protoFilePath}": ${error instanceof Error ? error.message : String(error)}`);
|
|
142
|
+
}
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
throw new Error(`Failed to fetch proto file: HTTP ${response.status} ${response.statusText}`);
|
|
145
|
+
}
|
|
146
|
+
// 2. 读取文件内容
|
|
147
|
+
let content;
|
|
148
|
+
try {
|
|
149
|
+
content = await response.text();
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
throw new Error(`Failed to read proto file content: ${error instanceof Error ? error.message : String(error)}`);
|
|
153
|
+
}
|
|
154
|
+
if (!content || content.trim().length === 0) {
|
|
155
|
+
throw new Error('Proto file is empty');
|
|
156
|
+
}
|
|
157
|
+
// 3. 解析 proto 文件
|
|
158
|
+
let root;
|
|
159
|
+
try {
|
|
160
|
+
root = protobuf.parse(content).root;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
throw new Error(`Failed to parse proto file: ${error instanceof Error ? error.message : String(error)}`);
|
|
164
|
+
}
|
|
165
|
+
// 4. 查找消息类型
|
|
166
|
+
const messageTypeDefinition = root.lookupType(messageType);
|
|
167
|
+
if (!messageTypeDefinition) {
|
|
168
|
+
// 尝试列出可用的类型,帮助调试
|
|
169
|
+
const availableTypes = [];
|
|
170
|
+
root.nestedArray.forEach((nested) => {
|
|
171
|
+
if (nested instanceof protobuf.Type) {
|
|
172
|
+
availableTypes.push(nested.fullName);
|
|
173
|
+
}
|
|
174
|
+
else if (nested instanceof protobuf.Namespace) {
|
|
175
|
+
nested.nestedArray.forEach((nestedType) => {
|
|
176
|
+
if (nestedType instanceof protobuf.Type) {
|
|
177
|
+
availableTypes.push(nestedType.fullName);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
const availableTypesHint = availableTypes.length > 0
|
|
183
|
+
? ` Available types: ${availableTypes.slice(0, 10).join(', ')}${availableTypes.length > 10 ? '...' : ''}`
|
|
184
|
+
: '';
|
|
185
|
+
throw new Error(`Message type "${messageType}" not found in proto file.${availableTypesHint}`);
|
|
186
|
+
}
|
|
187
|
+
// 5. 缓存结果
|
|
188
|
+
this.protoCache.set(cacheKey, messageTypeDefinition);
|
|
189
|
+
this.log(`Successfully loaded proto type: ${messageType}`);
|
|
190
|
+
return messageTypeDefinition;
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
194
|
+
this.log(`Error loading proto file: ${errorMessage}`, 'error');
|
|
195
|
+
// 重新抛出错误,但使用更友好的错误信息
|
|
196
|
+
throw error instanceof Error ? error : new Error(errorMessage);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* 清除缓存
|
|
201
|
+
* @param protoFilePath 可选的 proto 文件路径,如果提供则只清除该文件的缓存,否则清除所有缓存
|
|
202
|
+
*/
|
|
203
|
+
clearCache(protoFilePath) {
|
|
204
|
+
if (protoFilePath) {
|
|
205
|
+
const keysToDelete = [];
|
|
206
|
+
this.protoCache.forEach((_, key) => {
|
|
207
|
+
if (key.startsWith(protoFilePath)) {
|
|
208
|
+
keysToDelete.push(key);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
keysToDelete.forEach((key) => {
|
|
212
|
+
this.protoCache.delete(key);
|
|
213
|
+
this.log(`Cleared cache for: ${key}`);
|
|
214
|
+
});
|
|
215
|
+
this.log(`Cleared ${keysToDelete.length} cache entries for proto file: ${protoFilePath}`);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
const size = this.protoCache.size;
|
|
219
|
+
this.protoCache.clear();
|
|
220
|
+
this.log(`Cleared all ${size} cache entries`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 获取缓存的大小
|
|
225
|
+
*/
|
|
226
|
+
getCacheSize() {
|
|
227
|
+
return this.protoCache.size;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 检查指定 proto 类型是否已缓存
|
|
231
|
+
* @param protoFilePath proto 文件路径
|
|
232
|
+
* @param messageType 消息类型名称
|
|
233
|
+
* @returns 是否已缓存
|
|
234
|
+
*/
|
|
235
|
+
isCached(protoFilePath, messageType) {
|
|
236
|
+
const cacheKey = `${protoFilePath}-${messageType}`;
|
|
237
|
+
return this.protoCache.has(cacheKey);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 获取所有已缓存的 proto 文件路径
|
|
241
|
+
* @returns 已缓存的 proto 文件路径数组
|
|
242
|
+
*/
|
|
243
|
+
getCachedProtoFiles() {
|
|
244
|
+
const protoFiles = new Set();
|
|
245
|
+
this.protoCache.forEach((_, key) => {
|
|
246
|
+
const protoFilePath = key.split('-').slice(0, -1).join('-');
|
|
247
|
+
protoFiles.add(protoFilePath);
|
|
248
|
+
});
|
|
249
|
+
return Array.from(protoFiles);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 日志输出
|
|
253
|
+
*/
|
|
254
|
+
log(message, level = 'log') {
|
|
255
|
+
if (!this.options.enableLog)
|
|
256
|
+
return;
|
|
257
|
+
const prefix = '[ProtoBufManager]';
|
|
258
|
+
if (level === 'error') {
|
|
259
|
+
console.error(prefix, message);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
console.log(prefix, message);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=ProtoBufManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtoBufManager.js","sourceRoot":"","sources":["../src/ProtoBufManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { TimerManager } from './TimerManager';
|
|
2
|
+
import type { ProtoBufManagerOptions } from './ProtoBufManager';
|
|
3
|
+
import type { LoadXodrOptions } from '@threejs-shared/xodr';
|
|
4
|
+
/**
|
|
5
|
+
* Protobuf 回放客户端回调函数
|
|
6
|
+
*/
|
|
7
|
+
export interface ProtobufPlaybackCallbacks {
|
|
8
|
+
/** 每帧数据回调 */
|
|
9
|
+
onFrame?: (frameData: any) => void;
|
|
10
|
+
/** 播放进度回调(当前秒数) */
|
|
11
|
+
onProcess?: (currentSecond: number) => void;
|
|
12
|
+
/** 播放完成回调 */
|
|
13
|
+
onComplete?: () => void;
|
|
14
|
+
/** 错误回调 */
|
|
15
|
+
onError?: (error: Error | any) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Protobuf 回放客户端配置
|
|
19
|
+
*/
|
|
20
|
+
export interface ProtobufPlaybackClientConfig {
|
|
21
|
+
/** Proto 文件路径 */
|
|
22
|
+
protoPath: string;
|
|
23
|
+
/** 消息类型名称(例如:'SimulationMonitor.SimulationMonitorBag') */
|
|
24
|
+
messageType: string;
|
|
25
|
+
/** 文件下载配置(URL、请求头等) */
|
|
26
|
+
fileOptions: LoadXodrOptions;
|
|
27
|
+
/** 播放频率(帧/秒,FPS),默认 50。例如:50 表示每秒播放 50 帧,即每 20ms 触发一次帧回调 */
|
|
28
|
+
frequency?: number;
|
|
29
|
+
/** 每帧返回的数据量,默认 1。例如:1 表示每次 onFrame 回调接收 1 个帧数据对象;2 表示每次接收 2 个帧数据对象 */
|
|
30
|
+
frameSize?: number;
|
|
31
|
+
/** ProtoBuf 管理器选项 */
|
|
32
|
+
protoBufOptions?: ProtoBufManagerOptions;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Protobuf 回放客户端
|
|
36
|
+
*
|
|
37
|
+
* 这是一个高级封装类,将 Protobuf 文件下载、解码和 TimerManager 的使用流程封装起来,
|
|
38
|
+
* 简化业务代码中的使用。业务代码只需要配置参数和定义回调函数即可。
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const client = new ProtobufPlaybackClient({
|
|
43
|
+
* protoPath: '/proto/SimulationMonitor.proto',
|
|
44
|
+
* messageType: 'SimulationMonitor.SimulationMonitorBag',
|
|
45
|
+
* fileOptions: {
|
|
46
|
+
* url: '/api/simpro/simtask/pb/download/?task_id=14532&scene_id=1276197',
|
|
47
|
+
* responseType: 'arrayBuffer',
|
|
48
|
+
* useStreaming: false,
|
|
49
|
+
* header: {
|
|
50
|
+
* Authorization: `JWT ${token}`,
|
|
51
|
+
* 'X-Project-Id': projectId,
|
|
52
|
+
* }
|
|
53
|
+
* },
|
|
54
|
+
* frequency: 50,
|
|
55
|
+
* })
|
|
56
|
+
*
|
|
57
|
+
* await client.loadAndPlay({
|
|
58
|
+
* onFrame: (frameData) => {
|
|
59
|
+
* console.log('Frame data:', frameData)
|
|
60
|
+
* },
|
|
61
|
+
* onProcess: (currentSecond) => {
|
|
62
|
+
* console.log('Current second:', currentSecond)
|
|
63
|
+
* },
|
|
64
|
+
* onComplete: () => {
|
|
65
|
+
* console.log('Playback completed')
|
|
66
|
+
* },
|
|
67
|
+
* onError: (error) => {
|
|
68
|
+
* console.error('Error:', error)
|
|
69
|
+
* }
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare class ProtobufPlaybackClient {
|
|
74
|
+
private protoBufManager;
|
|
75
|
+
private timerManager;
|
|
76
|
+
private config;
|
|
77
|
+
constructor(config: ProtobufPlaybackClientConfig);
|
|
78
|
+
/**
|
|
79
|
+
* 加载 Protobuf 文件并开始播放
|
|
80
|
+
* @param callbacks 事件回调函数
|
|
81
|
+
* @returns Promise<void>
|
|
82
|
+
*/
|
|
83
|
+
loadAndPlay(callbacks?: ProtobufPlaybackCallbacks): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* 开始播放(如果已加载)
|
|
86
|
+
*/
|
|
87
|
+
start(): void;
|
|
88
|
+
/**
|
|
89
|
+
* 从指定秒数开始播放
|
|
90
|
+
* @param startSecond 起始秒数
|
|
91
|
+
*/
|
|
92
|
+
startFrom(startSecond: number): void;
|
|
93
|
+
/**
|
|
94
|
+
* 暂停播放
|
|
95
|
+
*/
|
|
96
|
+
pause(): void;
|
|
97
|
+
/**
|
|
98
|
+
* 继续播放
|
|
99
|
+
*/
|
|
100
|
+
resume(): void;
|
|
101
|
+
/**
|
|
102
|
+
* 停止播放
|
|
103
|
+
*/
|
|
104
|
+
stop(): void;
|
|
105
|
+
/**
|
|
106
|
+
* 重置播放器(可重新开始)
|
|
107
|
+
*/
|
|
108
|
+
reset(): void;
|
|
109
|
+
/**
|
|
110
|
+
* 销毁客户端,清理所有资源
|
|
111
|
+
*/
|
|
112
|
+
destroy(): void;
|
|
113
|
+
/**
|
|
114
|
+
* 获取 TimerManager 实例(用于高级操作)
|
|
115
|
+
*/
|
|
116
|
+
getTimerManager(): TimerManager | null;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=ProtobufPlaybackClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtobufPlaybackClient.d.ts","sourceRoot":"","sources":["../src/ProtobufPlaybackClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAG3D;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,aAAa;IACb,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,KAAK,IAAI,CAAA;IAClC,mBAAmB;IACnB,SAAS,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,aAAa;IACb,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,WAAW;IACX,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,KAAK,IAAI,CAAA;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAA;IACnB,uBAAuB;IACvB,WAAW,EAAE,eAAe,CAAA;IAC5B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qBAAqB;IACrB,eAAe,CAAC,EAAE,sBAAsB,CAAA;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,MAAM,CAA8B;gBAEhC,MAAM,EAAE,4BAA4B;IAKhD;;;;OAIG;IACG,WAAW,CAAC,SAAS,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiEvE;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;;OAGG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAOpC;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf;;OAEG;IACH,eAAe,IAAI,YAAY,GAAG,IAAI;CAGvC"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { ProtoBufManager } from './ProtoBufManager';
|
|
2
|
+
import { TimerManager } from './TimerManager';
|
|
3
|
+
import { loadXodr } from '@threejs-shared/xodr';
|
|
4
|
+
/**
|
|
5
|
+
* Protobuf 回放客户端
|
|
6
|
+
*
|
|
7
|
+
* 这是一个高级封装类,将 Protobuf 文件下载、解码和 TimerManager 的使用流程封装起来,
|
|
8
|
+
* 简化业务代码中的使用。业务代码只需要配置参数和定义回调函数即可。
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const client = new ProtobufPlaybackClient({
|
|
13
|
+
* protoPath: '/proto/SimulationMonitor.proto',
|
|
14
|
+
* messageType: 'SimulationMonitor.SimulationMonitorBag',
|
|
15
|
+
* fileOptions: {
|
|
16
|
+
* url: '/api/simpro/simtask/pb/download/?task_id=14532&scene_id=1276197',
|
|
17
|
+
* responseType: 'arrayBuffer',
|
|
18
|
+
* useStreaming: false,
|
|
19
|
+
* header: {
|
|
20
|
+
* Authorization: `JWT ${token}`,
|
|
21
|
+
* 'X-Project-Id': projectId,
|
|
22
|
+
* }
|
|
23
|
+
* },
|
|
24
|
+
* frequency: 50,
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* await client.loadAndPlay({
|
|
28
|
+
* onFrame: (frameData) => {
|
|
29
|
+
* console.log('Frame data:', frameData)
|
|
30
|
+
* },
|
|
31
|
+
* onProcess: (currentSecond) => {
|
|
32
|
+
* console.log('Current second:', currentSecond)
|
|
33
|
+
* },
|
|
34
|
+
* onComplete: () => {
|
|
35
|
+
* console.log('Playback completed')
|
|
36
|
+
* },
|
|
37
|
+
* onError: (error) => {
|
|
38
|
+
* console.error('Error:', error)
|
|
39
|
+
* }
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class ProtobufPlaybackClient {
|
|
44
|
+
constructor(config) {
|
|
45
|
+
this.timerManager = null;
|
|
46
|
+
this.config = config;
|
|
47
|
+
this.protoBufManager = new ProtoBufManager(config.protoBufOptions);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 加载 Protobuf 文件并开始播放
|
|
51
|
+
* @param callbacks 事件回调函数
|
|
52
|
+
* @returns Promise<void>
|
|
53
|
+
*/
|
|
54
|
+
async loadAndPlay(callbacks) {
|
|
55
|
+
var _a, _b, _c;
|
|
56
|
+
try {
|
|
57
|
+
// 1. 下载文件
|
|
58
|
+
const fileContent = await loadXodr(this.config.fileOptions);
|
|
59
|
+
// 2. 加载 Proto 文件
|
|
60
|
+
const protobufType = await this.protoBufManager.loadProto(this.config.protoPath, this.config.messageType);
|
|
61
|
+
// 3. 解码文件内容
|
|
62
|
+
let decodedData;
|
|
63
|
+
try {
|
|
64
|
+
decodedData = protobufType.decode(fileContent);
|
|
65
|
+
}
|
|
66
|
+
catch (decodeError) {
|
|
67
|
+
// 如果解码失败,尝试解析为 JSON 错误消息
|
|
68
|
+
try {
|
|
69
|
+
const decoder = new TextDecoder('utf-8');
|
|
70
|
+
const rawText = decoder.decode(fileContent);
|
|
71
|
+
const errorData = JSON.parse(rawText);
|
|
72
|
+
const error = new Error((errorData === null || errorData === void 0 ? void 0 : errorData.err) || 'Failed to decode protobuf file');
|
|
73
|
+
(_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onError) === null || _a === void 0 ? void 0 : _a.call(callbacks, error);
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
catch (jsonError) {
|
|
77
|
+
const error = decodeError instanceof Error
|
|
78
|
+
? decodeError
|
|
79
|
+
: new Error('Failed to decode protobuf file');
|
|
80
|
+
(_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onError) === null || _b === void 0 ? void 0 : _b.call(callbacks, error);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// 4. 创建 TimerManager 并开始播放
|
|
85
|
+
// frequency: 播放频率(帧/秒,FPS),默认 50,表示每秒播放 50 帧数据
|
|
86
|
+
// 例如:frequency = 50 表示每 20ms(1000ms / 50)触发一次帧回调
|
|
87
|
+
const frequency = this.config.frequency || 50;
|
|
88
|
+
// frameSize: 每帧返回的数据量,默认 1,表示每次回调返回 1 个帧数据对象
|
|
89
|
+
// 例如:frameSize = 1 表示每次 onFrame 回调接收 1 个帧数据;frameSize = 2 表示每次接收 2 个帧数据
|
|
90
|
+
const frameSize = this.config.frameSize || 1;
|
|
91
|
+
if (!decodedData.frames || !Array.isArray(decodedData.frames)) {
|
|
92
|
+
throw new Error('Decoded data does not contain a valid "frames" array');
|
|
93
|
+
}
|
|
94
|
+
this.timerManager = new TimerManager(decodedData.frames, frequency, frameSize);
|
|
95
|
+
this.timerManager.connect((frameData) => {
|
|
96
|
+
var _a;
|
|
97
|
+
(_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onFrame) === null || _a === void 0 ? void 0 : _a.call(callbacks, frameData);
|
|
98
|
+
}, (currentSecond) => {
|
|
99
|
+
var _a;
|
|
100
|
+
(_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onProcess) === null || _a === void 0 ? void 0 : _a.call(callbacks, currentSecond);
|
|
101
|
+
}, () => {
|
|
102
|
+
var _a;
|
|
103
|
+
(_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onComplete) === null || _a === void 0 ? void 0 : _a.call(callbacks);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
108
|
+
(_c = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onError) === null || _c === void 0 ? void 0 : _c.call(callbacks, err);
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 开始播放(如果已加载)
|
|
114
|
+
*/
|
|
115
|
+
start() {
|
|
116
|
+
if (!this.timerManager) {
|
|
117
|
+
throw new Error('TimerManager is not initialized. Please call loadAndPlay() first.');
|
|
118
|
+
}
|
|
119
|
+
this.timerManager.start();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 从指定秒数开始播放
|
|
123
|
+
* @param startSecond 起始秒数
|
|
124
|
+
*/
|
|
125
|
+
startFrom(startSecond) {
|
|
126
|
+
if (!this.timerManager) {
|
|
127
|
+
throw new Error('TimerManager is not initialized. Please call loadAndPlay() first.');
|
|
128
|
+
}
|
|
129
|
+
this.timerManager.startFrom(startSecond);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 暂停播放
|
|
133
|
+
*/
|
|
134
|
+
pause() {
|
|
135
|
+
if (!this.timerManager) {
|
|
136
|
+
console.warn('TimerManager is not initialized. Cannot pause.');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.timerManager.pause();
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 继续播放
|
|
143
|
+
*/
|
|
144
|
+
resume() {
|
|
145
|
+
if (!this.timerManager) {
|
|
146
|
+
console.warn('TimerManager is not initialized. Cannot resume.');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.timerManager.resume();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* 停止播放
|
|
153
|
+
*/
|
|
154
|
+
stop() {
|
|
155
|
+
if (this.timerManager) {
|
|
156
|
+
this.timerManager.stop();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 重置播放器(可重新开始)
|
|
161
|
+
*/
|
|
162
|
+
reset() {
|
|
163
|
+
if (!this.timerManager) {
|
|
164
|
+
console.warn('TimerManager is not initialized. Cannot reset.');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.timerManager.reset();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 销毁客户端,清理所有资源
|
|
171
|
+
*/
|
|
172
|
+
destroy() {
|
|
173
|
+
if (this.timerManager) {
|
|
174
|
+
this.timerManager.stop();
|
|
175
|
+
this.timerManager = null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 获取 TimerManager 实例(用于高级操作)
|
|
180
|
+
*/
|
|
181
|
+
getTimerManager() {
|
|
182
|
+
return this.timerManager;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=ProtobufPlaybackClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtobufPlaybackClient.js","sourceRoot":"","sources":["../src/ProtobufPlaybackClient.ts"],"names":[],"mappings":"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"}
|