mm_machine 2.7.7 → 2.7.9
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/drive.js +716 -705
- package/index.js +1006 -1000
- package/package.json +4 -4
package/index.js
CHANGED
|
@@ -1,1000 +1,1006 @@
|
|
|
1
|
-
const { Mod } = require('./mod');
|
|
2
|
-
const { Drive } = require('./drive.js');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 管理器类
|
|
6
|
-
*/
|
|
7
|
-
class Manager extends Mod {
|
|
8
|
-
/**
|
|
9
|
-
* 配置项
|
|
10
|
-
* @type {object}
|
|
11
|
-
*/
|
|
12
|
-
static config = {
|
|
13
|
-
/**
|
|
14
|
-
* 管理器名称
|
|
15
|
-
* @type {string}
|
|
16
|
-
*/
|
|
17
|
-
name: 'manager',
|
|
18
|
-
/**
|
|
19
|
-
* 管理器标题
|
|
20
|
-
* @type {string}
|
|
21
|
-
*/
|
|
22
|
-
title: '管理器',
|
|
23
|
-
/**
|
|
24
|
-
* 管理器描述
|
|
25
|
-
* @type {string}
|
|
26
|
-
*/
|
|
27
|
-
description: '用于管理驱动',
|
|
28
|
-
/**
|
|
29
|
-
* 检索文件名
|
|
30
|
-
* @type {string}
|
|
31
|
-
*/
|
|
32
|
-
filename: 'manager.json',
|
|
33
|
-
/**
|
|
34
|
-
* 模板目录
|
|
35
|
-
* @type {string}
|
|
36
|
-
*/
|
|
37
|
-
tpl_dir: __dirname,
|
|
38
|
-
/**
|
|
39
|
-
* 基础目录,加载模块内置资源
|
|
40
|
-
* @type {string}
|
|
41
|
-
*/
|
|
42
|
-
base_dir: '', // '../common/manager'.fullname(__dirname),
|
|
43
|
-
/**
|
|
44
|
-
* 自定义目录,加载项目自定义资源
|
|
45
|
-
* @type {string}
|
|
46
|
-
*/
|
|
47
|
-
dir: '', // './ai/manager'.fullname(),
|
|
48
|
-
/**
|
|
49
|
-
* 搜索模式 dir按目录搜索 | file按文件名搜索
|
|
50
|
-
* @type {string}
|
|
51
|
-
*/
|
|
52
|
-
search_way: 'file',
|
|
53
|
-
/**
|
|
54
|
-
* 类型 script脚本 | json配置 | drive驱动
|
|
55
|
-
* @type {string}
|
|
56
|
-
*/
|
|
57
|
-
mod_type: 'drive',
|
|
58
|
-
/**
|
|
59
|
-
* 是否懒加载
|
|
60
|
-
* @type {boolean}
|
|
61
|
-
*/
|
|
62
|
-
lazy_load: true,
|
|
63
|
-
/**
|
|
64
|
-
* 模式
|
|
65
|
-
* 1.生产模式,改变文件不会重新加载
|
|
66
|
-
* 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
|
|
67
|
-
* 3.热重载模式,改变配置文件都会加载配置和脚本
|
|
68
|
-
* 4.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
|
|
69
|
-
* 5.重载模式,执行完后重新加载脚本,避免变量污染
|
|
70
|
-
* @type {number}
|
|
71
|
-
*/
|
|
72
|
-
mode: 3,
|
|
73
|
-
/**
|
|
74
|
-
* 排序项
|
|
75
|
-
* @type {string}
|
|
76
|
-
*/
|
|
77
|
-
sort_key: 'sort',
|
|
78
|
-
/**
|
|
79
|
-
* 作用域
|
|
80
|
-
* @type {string}
|
|
81
|
-
*/
|
|
82
|
-
scope:
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* 构造函数
|
|
87
|
-
* @param {object} config 配置项
|
|
88
|
-
* @param {object} parent 父项对象
|
|
89
|
-
* @param {object} mods 模块对象列表
|
|
90
|
-
* @param {object} Drive 驱动对象
|
|
91
|
-
*/
|
|
92
|
-
constructor(config, parent, mods = {}, Drive) {
|
|
93
|
-
super(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
*
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
*
|
|
195
|
-
* @returns {string}
|
|
196
|
-
*/
|
|
197
|
-
Manager.prototype.
|
|
198
|
-
return this.config.
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
*
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
*
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
let
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
*
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
*
|
|
276
|
-
* @
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
*
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
*
|
|
406
|
-
*/
|
|
407
|
-
Manager.prototype.
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
*
|
|
502
|
-
*/
|
|
503
|
-
Manager.prototype.
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
this.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
//
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
*
|
|
614
|
-
*/
|
|
615
|
-
Manager.prototype.
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
*
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
};
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
//
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
);
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
//
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
);
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
if (!config.
|
|
948
|
-
throw new TypeError('
|
|
949
|
-
}
|
|
950
|
-
if (
|
|
951
|
-
throw new
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1
|
+
const { Mod } = require('./mod');
|
|
2
|
+
const { Drive } = require('./drive.js');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 管理器类
|
|
6
|
+
*/
|
|
7
|
+
class Manager extends Mod {
|
|
8
|
+
/**
|
|
9
|
+
* 配置项
|
|
10
|
+
* @type {object}
|
|
11
|
+
*/
|
|
12
|
+
static config = {
|
|
13
|
+
/**
|
|
14
|
+
* 管理器名称
|
|
15
|
+
* @type {string}
|
|
16
|
+
*/
|
|
17
|
+
name: 'manager',
|
|
18
|
+
/**
|
|
19
|
+
* 管理器标题
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
22
|
+
title: '管理器',
|
|
23
|
+
/**
|
|
24
|
+
* 管理器描述
|
|
25
|
+
* @type {string}
|
|
26
|
+
*/
|
|
27
|
+
description: '用于管理驱动',
|
|
28
|
+
/**
|
|
29
|
+
* 检索文件名
|
|
30
|
+
* @type {string}
|
|
31
|
+
*/
|
|
32
|
+
filename: 'manager.json',
|
|
33
|
+
/**
|
|
34
|
+
* 模板目录
|
|
35
|
+
* @type {string}
|
|
36
|
+
*/
|
|
37
|
+
tpl_dir: __dirname,
|
|
38
|
+
/**
|
|
39
|
+
* 基础目录,加载模块内置资源
|
|
40
|
+
* @type {string}
|
|
41
|
+
*/
|
|
42
|
+
base_dir: '', // '../common/manager'.fullname(__dirname),
|
|
43
|
+
/**
|
|
44
|
+
* 自定义目录,加载项目自定义资源
|
|
45
|
+
* @type {string}
|
|
46
|
+
*/
|
|
47
|
+
dir: '', // './ai/manager'.fullname(),
|
|
48
|
+
/**
|
|
49
|
+
* 搜索模式 dir按目录搜索 | file按文件名搜索
|
|
50
|
+
* @type {string}
|
|
51
|
+
*/
|
|
52
|
+
search_way: 'file',
|
|
53
|
+
/**
|
|
54
|
+
* 类型 script脚本 | json配置 | drive驱动
|
|
55
|
+
* @type {string}
|
|
56
|
+
*/
|
|
57
|
+
mod_type: 'drive',
|
|
58
|
+
/**
|
|
59
|
+
* 是否懒加载
|
|
60
|
+
* @type {boolean}
|
|
61
|
+
*/
|
|
62
|
+
lazy_load: true,
|
|
63
|
+
/**
|
|
64
|
+
* 模式
|
|
65
|
+
* 1.生产模式,改变文件不会重新加载
|
|
66
|
+
* 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
|
|
67
|
+
* 3.热重载模式,改变配置文件都会加载配置和脚本
|
|
68
|
+
* 4.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
|
|
69
|
+
* 5.重载模式,执行完后重新加载脚本,避免变量污染
|
|
70
|
+
* @type {number}
|
|
71
|
+
*/
|
|
72
|
+
mode: 3,
|
|
73
|
+
/**
|
|
74
|
+
* 排序项
|
|
75
|
+
* @type {string}
|
|
76
|
+
*/
|
|
77
|
+
sort_key: 'sort',
|
|
78
|
+
/**
|
|
79
|
+
* 作用域
|
|
80
|
+
* @type {string}
|
|
81
|
+
*/
|
|
82
|
+
scope: $.val && $.val.scope ? $.val.scope + '' : 'server'
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 构造函数
|
|
87
|
+
* @param {object} config 配置项
|
|
88
|
+
* @param {object} parent 父项对象
|
|
89
|
+
* @param {object} mods 模块对象列表
|
|
90
|
+
* @param {object} Drive 驱动对象
|
|
91
|
+
*/
|
|
92
|
+
constructor(config, parent, mods = {}, Drive) {
|
|
93
|
+
super(
|
|
94
|
+
{
|
|
95
|
+
...Manager.config,
|
|
96
|
+
...config
|
|
97
|
+
},
|
|
98
|
+
parent
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// 模块信息列表 { name: '', sort: 0, available: true, enabled: true }
|
|
102
|
+
this.infos = [];
|
|
103
|
+
// 模块
|
|
104
|
+
this.mods = mods;
|
|
105
|
+
// getList 缓存
|
|
106
|
+
this._list_cache = null;
|
|
107
|
+
if (Drive) {
|
|
108
|
+
this.Drive = Drive;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get list() {
|
|
113
|
+
return this.getList();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 获取事件触发器
|
|
119
|
+
* @returns {object} 事件触发器
|
|
120
|
+
*/
|
|
121
|
+
Manager.prototype.getEventer = function () {
|
|
122
|
+
return $.eventer;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 获取所有模块信息
|
|
127
|
+
* @returns {object[]} 模块信息数组
|
|
128
|
+
*/
|
|
129
|
+
Manager.prototype.getInfos = function () {
|
|
130
|
+
return this.infos;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 创建模块状态模型
|
|
135
|
+
* @param {string} name 模块名
|
|
136
|
+
* @param {number} sort 排序值
|
|
137
|
+
* @param {boolean} state 状态
|
|
138
|
+
* @param {string} file 文件名
|
|
139
|
+
* @returns {object} 模块状态模型
|
|
140
|
+
*/
|
|
141
|
+
Manager.prototype.newInfo = function (name, sort, state, file = '') {
|
|
142
|
+
return {
|
|
143
|
+
name,
|
|
144
|
+
sort,
|
|
145
|
+
state,
|
|
146
|
+
enabled: true,
|
|
147
|
+
file: file || '',
|
|
148
|
+
get available() {
|
|
149
|
+
return this.state == true && this.enabled;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 设置模块信息
|
|
156
|
+
* @param {object} info 模块信息
|
|
157
|
+
*/
|
|
158
|
+
Manager.prototype.setInfo = function (info) {
|
|
159
|
+
this._list_cache = null;
|
|
160
|
+
let has = false;
|
|
161
|
+
for (let i = 0; i < this.infos.length; i++) {
|
|
162
|
+
let o = this.infos[i];
|
|
163
|
+
if (o.name == info.name) {
|
|
164
|
+
this.infos[i] = info;
|
|
165
|
+
has = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!has) {
|
|
170
|
+
this.infos.push(info);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 获取所有模块对象
|
|
176
|
+
* @returns {object[]} 模块对象数组
|
|
177
|
+
*/
|
|
178
|
+
Manager.prototype.getList = function () {
|
|
179
|
+
if (this._list_cache) return this._list_cache;
|
|
180
|
+
var list = [];
|
|
181
|
+
for (var i = 0; i < this.infos.length; i++) {
|
|
182
|
+
var info = this.infos[i];
|
|
183
|
+
var mod = this.getMod(info.name);
|
|
184
|
+
if (mod) {
|
|
185
|
+
mod.config.state = info.state;
|
|
186
|
+
}
|
|
187
|
+
list.push(mod);
|
|
188
|
+
}
|
|
189
|
+
this._list_cache = list;
|
|
190
|
+
return list;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 获取基础目录
|
|
195
|
+
* @returns {string} 基础目录
|
|
196
|
+
*/
|
|
197
|
+
Manager.prototype.getBaseDir = function () {
|
|
198
|
+
return this.config.base_dir || __dirname;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* 获取模板目录
|
|
203
|
+
* @returns {string} 模板目录
|
|
204
|
+
*/
|
|
205
|
+
Manager.prototype.getTplDir = function () {
|
|
206
|
+
return this.config.tpl_dir || __dirname;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* 默认驱动
|
|
211
|
+
*/
|
|
212
|
+
Manager.prototype.Drive = Drive;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 更新模块信息
|
|
216
|
+
*/
|
|
217
|
+
Manager.prototype.updateInfo = function () {
|
|
218
|
+
this._list_cache = null;
|
|
219
|
+
this.infos = [];
|
|
220
|
+
let mods = this.getMods();
|
|
221
|
+
for (let name in mods) {
|
|
222
|
+
let o = mods[name];
|
|
223
|
+
let info = this.newInfo(name, o.config.sort, o.config.state, o.config_file);
|
|
224
|
+
this.infos.push(info);
|
|
225
|
+
}
|
|
226
|
+
this.sort();
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 排序
|
|
231
|
+
*/
|
|
232
|
+
Manager.prototype._sort = function () {
|
|
233
|
+
var sort_key = this.config.sort_key || 'sort';
|
|
234
|
+
this.infos.sort((o1, o2) => {
|
|
235
|
+
let p1 = o1[sort_key] || 100;
|
|
236
|
+
let p2 = o2[sort_key] || 100;
|
|
237
|
+
return p1 - p2;
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* 排序
|
|
243
|
+
*/
|
|
244
|
+
Manager.prototype.sort = function () {
|
|
245
|
+
this._list_cache = null;
|
|
246
|
+
this._sort();
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// ==== 模块管理接口 ====
|
|
250
|
+
/**
|
|
251
|
+
* 清除所有模块
|
|
252
|
+
*/
|
|
253
|
+
Manager.prototype.clearMods = function () {
|
|
254
|
+
this._list_cache = null;
|
|
255
|
+
for (let name in this.mods) {
|
|
256
|
+
delete this.mods[name];
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* 删除模块
|
|
262
|
+
* @param {string} name 模块名
|
|
263
|
+
* @returns {object|null} 删除的模块对象
|
|
264
|
+
*/
|
|
265
|
+
Manager.prototype.delMod = function (name) {
|
|
266
|
+
this._list_cache = null;
|
|
267
|
+
let mod = this.mods[name];
|
|
268
|
+
if (mod) {
|
|
269
|
+
delete this.mods[name];
|
|
270
|
+
}
|
|
271
|
+
return mod;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* 设置模块
|
|
276
|
+
* @param {string} name 模块名
|
|
277
|
+
* @param {object} mod 模块对象
|
|
278
|
+
* @returns {object|null} 设置的模块对象
|
|
279
|
+
*/
|
|
280
|
+
Manager.prototype.setMod = function (name, mod) {
|
|
281
|
+
this._list_cache = null;
|
|
282
|
+
this.mods[name] = mod;
|
|
283
|
+
return this.getMod(name);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* 获取模块
|
|
288
|
+
* @param {string} name 模块名
|
|
289
|
+
* @returns {object|null} 模块对象,若模块则返回模块对象,否则返回null
|
|
290
|
+
*/
|
|
291
|
+
Manager.prototype.getMod = function (name) {
|
|
292
|
+
return this.mods[name];
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* 获取所有模块
|
|
297
|
+
* @returns {object[]} 模块对象数组
|
|
298
|
+
*/
|
|
299
|
+
Manager.prototype.getMods = function () {
|
|
300
|
+
return this.mods;
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* 创建模块
|
|
305
|
+
* @param {string} config_file 配置文件路径
|
|
306
|
+
* @param {object} config 配置项
|
|
307
|
+
* @param {object} script 模块对象
|
|
308
|
+
* @returns {object} 模块对象
|
|
309
|
+
*/
|
|
310
|
+
Manager.prototype.newMod = function (config_file, config, script) {
|
|
311
|
+
let mod;
|
|
312
|
+
switch (this.config.mod_type) {
|
|
313
|
+
case 'script':
|
|
314
|
+
mod = new Mod(config, this);
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
// 创建模块
|
|
318
|
+
mod = new this.Drive(config, this);
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
mod.mode = this.config.mode;
|
|
322
|
+
mod.loadConfig(config_file);
|
|
323
|
+
if (script) {
|
|
324
|
+
for (let key in script) {
|
|
325
|
+
let obj = script[key];
|
|
326
|
+
if (typeof obj == 'function') {
|
|
327
|
+
mod.setMethod(key, obj);
|
|
328
|
+
} else {
|
|
329
|
+
mod.setData(key, obj);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return mod;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* 注册模块
|
|
338
|
+
* @param {string} config_file 配置文件路径
|
|
339
|
+
* @param {object} config 配置项
|
|
340
|
+
* @param {object} script 模块对象
|
|
341
|
+
* @returns {object} 模块对象
|
|
342
|
+
*/
|
|
343
|
+
Manager.prototype.registerMod = function (config_file, config = {}, script = {}) {
|
|
344
|
+
let mod = this.newMod(config_file, config, script);
|
|
345
|
+
this.setMod(mod.config.name, mod);
|
|
346
|
+
return mod;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* 加载模块
|
|
351
|
+
* @param {string} name 模块名
|
|
352
|
+
* @returns {Promise<any>} 加载结果
|
|
353
|
+
*/
|
|
354
|
+
Manager.prototype.loadMod = async function (name) {
|
|
355
|
+
let mod = this.getMod(name);
|
|
356
|
+
if (mod) {
|
|
357
|
+
return await mod.do('load');
|
|
358
|
+
}
|
|
359
|
+
return null;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* 卸载模块
|
|
364
|
+
* @param {string} name 模块名
|
|
365
|
+
* @returns {Promise<any>} 卸载结果
|
|
366
|
+
*/
|
|
367
|
+
Manager.prototype.unloadMod = async function (name) {
|
|
368
|
+
let mod = this.getMod(name);
|
|
369
|
+
if (mod) {
|
|
370
|
+
return await mod.do('unload');
|
|
371
|
+
}
|
|
372
|
+
return null;
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* 重载模块
|
|
377
|
+
* @param {string} name 模块名
|
|
378
|
+
* @returns {Promise<any>} 重载结果
|
|
379
|
+
*/
|
|
380
|
+
Manager.prototype.reloadMod = async function (name) {
|
|
381
|
+
let mod = this.getMod(name);
|
|
382
|
+
if (mod) {
|
|
383
|
+
return await mod.do('reload');
|
|
384
|
+
}
|
|
385
|
+
return null;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* 注销模块
|
|
390
|
+
* @param {string} name 模块名
|
|
391
|
+
* @returns {Promise<any>} 注销结果
|
|
392
|
+
*/
|
|
393
|
+
Manager.prototype.unregisterMod = function (name) {
|
|
394
|
+
// 卸载模块
|
|
395
|
+
this.unloadMod(name);
|
|
396
|
+
// 删除模块
|
|
397
|
+
let mod = this.delMod(name);
|
|
398
|
+
return mod;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* 批量注册模块
|
|
403
|
+
* @param {string[]} files 配置文件路径数组
|
|
404
|
+
* @param {object} config 配置项
|
|
405
|
+
* @param {object} script 模块对象
|
|
406
|
+
*/
|
|
407
|
+
Manager.prototype.registerMods = function (files, config = {}, script = {}) {
|
|
408
|
+
for (let file of files) {
|
|
409
|
+
this.registerMod(file, config, script);
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* 加载所有模块
|
|
415
|
+
*/
|
|
416
|
+
Manager.prototype.loadMods = async function () {
|
|
417
|
+
var promises = [];
|
|
418
|
+
let mods = this.getMods();
|
|
419
|
+
for (let name in mods) {
|
|
420
|
+
let mod = mods[name];
|
|
421
|
+
promises.push(mod.do('load'));
|
|
422
|
+
}
|
|
423
|
+
await Promise.all(promises);
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* 获取目录名
|
|
428
|
+
* @returns {string} 目录名
|
|
429
|
+
*/
|
|
430
|
+
Manager.prototype.getDirName = function () {
|
|
431
|
+
// 前缀,为当前类名
|
|
432
|
+
let prefix = this.constructor.name.toLowerCase();
|
|
433
|
+
// 后缀,为配置项名称
|
|
434
|
+
let name = this.config.name.toLowerCase();
|
|
435
|
+
// 目录名,为前缀加下划线加后缀
|
|
436
|
+
return prefix + '_' + name;
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* 获取所有目录下的文件
|
|
441
|
+
* @param {string} dir 目录路径
|
|
442
|
+
* @returns {Array} 文件路径数组
|
|
443
|
+
*/
|
|
444
|
+
Manager.prototype._getAllDirFiles = async function (dir) {
|
|
445
|
+
var dirs = await $.dir.getAllAsync(dir, this.getDirName());
|
|
446
|
+
var filename = this.config.filename;
|
|
447
|
+
var results = await Promise.all(dirs.map((d) => $.file.getAllAsync(d, filename)));
|
|
448
|
+
var files = [];
|
|
449
|
+
for (var i = 0; i < results.length; i++) {
|
|
450
|
+
if (results[i].length > 0) {
|
|
451
|
+
files.push(...results[i]);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return files;
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* 检索目录下所有文件
|
|
459
|
+
* @private
|
|
460
|
+
* @param {string} dir 目录路径
|
|
461
|
+
* @returns {Array} 文件路径数组
|
|
462
|
+
*/
|
|
463
|
+
Manager.prototype._findFiles = async function (dir) {
|
|
464
|
+
// 检查目录是否存在
|
|
465
|
+
if (!dir) {
|
|
466
|
+
this.log('error', '目录不能为空');
|
|
467
|
+
return [];
|
|
468
|
+
}
|
|
469
|
+
// 检查目录是否存在
|
|
470
|
+
if (!dir.hasDir()) {
|
|
471
|
+
return [];
|
|
472
|
+
}
|
|
473
|
+
if (this.config.search_way === 'dir') {
|
|
474
|
+
return await this._getAllDirFiles(dir);
|
|
475
|
+
}
|
|
476
|
+
// 检索目录下所有文件
|
|
477
|
+
return await $.file.getAllAsync(dir, this.config.filename);
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* 加载所有模块的脚本
|
|
482
|
+
*/
|
|
483
|
+
Manager.prototype.loadScripts = async function () {
|
|
484
|
+
var promises = [];
|
|
485
|
+
let mods = this.getMods();
|
|
486
|
+
for (let name in mods) {
|
|
487
|
+
let mod = mods[name];
|
|
488
|
+
promises.push(mod.call('loadScript'));
|
|
489
|
+
}
|
|
490
|
+
await Promise.all(promises);
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* 更新配置前的钩子函数
|
|
495
|
+
*/
|
|
496
|
+
Manager.prototype.updateBefore = function () {
|
|
497
|
+
// this.log('info', '更新配置前的钩子函数');
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* 更新配置前的钩子函数
|
|
502
|
+
*/
|
|
503
|
+
Manager.prototype.updateAfter = function () {
|
|
504
|
+
// this.log('info', '更新配置后钩子函数');
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* 更新配置
|
|
509
|
+
* @param {string} dir 检索的路径
|
|
510
|
+
* @param {boolean} clear 是否清除缓存
|
|
511
|
+
*/
|
|
512
|
+
Manager.prototype.update = async function (dir, clear = true) {
|
|
513
|
+
if (clear) {
|
|
514
|
+
this.clearMods();
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// 查找所有json文件
|
|
518
|
+
let files = await this._findFiles(dir || this.config.dir);
|
|
519
|
+
// 批量注册模块
|
|
520
|
+
this.registerMods(files);
|
|
521
|
+
// 更新配置信息
|
|
522
|
+
this.updateInfo();
|
|
523
|
+
if (!this.config.lazy_load) {
|
|
524
|
+
// 批量加载脚本
|
|
525
|
+
await this.loadScripts();
|
|
526
|
+
}
|
|
527
|
+
this.is_loaded = true;
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
// ==== 高性能调用接口 ====
|
|
531
|
+
/**
|
|
532
|
+
* 调用模块的方法(高性能版本)
|
|
533
|
+
* @param {string} name 模块名
|
|
534
|
+
* @param {string} method 方法名
|
|
535
|
+
* @param {...any} params 参数集合
|
|
536
|
+
* @returns {Promise<any>} 执行结果
|
|
537
|
+
*/
|
|
538
|
+
Manager.prototype.main = async function (name, method, ...params) {
|
|
539
|
+
var result = null;
|
|
540
|
+
if (name) {
|
|
541
|
+
let mod = this.getMod(name);
|
|
542
|
+
if (mod && mod.config?.state === 1) {
|
|
543
|
+
result = await this._runMod(mod, method, ...params);
|
|
544
|
+
}
|
|
545
|
+
} else if (name === null) {
|
|
546
|
+
result = await this._runAllEnabled(method, ...params);
|
|
547
|
+
}
|
|
548
|
+
return result;
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* 私有方法:执行所有模块方法
|
|
553
|
+
* @param {string} method 方法名称
|
|
554
|
+
* @param {...any} params 方法参数集合
|
|
555
|
+
* @returns {Promise<any>} 执行结果
|
|
556
|
+
* @private
|
|
557
|
+
*/
|
|
558
|
+
Manager.prototype._runAllEnabled = async function (method, ...params) {
|
|
559
|
+
var result;
|
|
560
|
+
for (let i = 0; i < this.infos.length; i++) {
|
|
561
|
+
let config = this.infos[i];
|
|
562
|
+
let mod = this.getMod(config.name);
|
|
563
|
+
if (mod && mod.config?.state === 1) {
|
|
564
|
+
var ret = null;
|
|
565
|
+
try {
|
|
566
|
+
ret = await this._runMod(mod, method, ...params);
|
|
567
|
+
} catch (err) {
|
|
568
|
+
$.log.error(`执行模块方法失败: `, err);
|
|
569
|
+
}
|
|
570
|
+
if (ret !== null && ret !== undefined) {
|
|
571
|
+
result = ret;
|
|
572
|
+
// 如果结果不为空且有结束标志,则停止迭代
|
|
573
|
+
if (mod.config?.end) {
|
|
574
|
+
break;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return result;
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* 私有方法:执行模块方法
|
|
584
|
+
* @param {object} mod 模块对象
|
|
585
|
+
* @param {string} method 方法名称
|
|
586
|
+
* @param {...any} params 参数集合
|
|
587
|
+
* @returns {Promise<any>} 执行结果
|
|
588
|
+
* @private
|
|
589
|
+
*/
|
|
590
|
+
Manager.prototype._runMod = async function (mod, method, ...params) {
|
|
591
|
+
if (!mod || !method) return null;
|
|
592
|
+
|
|
593
|
+
// 确保模块已加载
|
|
594
|
+
if (!mod.isLoaded()) {
|
|
595
|
+
try {
|
|
596
|
+
await mod.call('loadScript');
|
|
597
|
+
} catch (err) {
|
|
598
|
+
$.log.error(`加载模块脚本失败: `, err);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// 执行方法
|
|
603
|
+
let ret = await mod.call(method, ...params);
|
|
604
|
+
// 根据模式决定是否重载
|
|
605
|
+
if (this.mode >= 4) {
|
|
606
|
+
mod.do('reload');
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return ret;
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* 初始化管理器
|
|
614
|
+
*/
|
|
615
|
+
Manager.prototype._initManager = function () {};
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* 获取公共模块目录
|
|
619
|
+
* @returns {string} 公共模块目录
|
|
620
|
+
*/
|
|
621
|
+
Manager.prototype.getBaseDir = function () {
|
|
622
|
+
return this.config.base_dir;
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* 获取二次开发模块目录
|
|
627
|
+
* @returns {string} 二次开发模块目录
|
|
628
|
+
*/
|
|
629
|
+
Manager.prototype.getDir = function () {
|
|
630
|
+
return this.config.dir || this.getDir();
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* 加载资源
|
|
635
|
+
*/
|
|
636
|
+
Manager.prototype._loadSources = async function () {
|
|
637
|
+
// 通过更新函数加载资源信息
|
|
638
|
+
let base_dir = this.getBaseDir();
|
|
639
|
+
let dir = this.getDir();
|
|
640
|
+
if (base_dir) {
|
|
641
|
+
await this.call('update', base_dir);
|
|
642
|
+
await this.call('update', dir, false);
|
|
643
|
+
} else {
|
|
644
|
+
await this.call('update', dir);
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* 初始化资源
|
|
650
|
+
*/
|
|
651
|
+
Manager.prototype._initSources = async function () {
|
|
652
|
+
// 通过
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* 初始化公共属性
|
|
657
|
+
*/
|
|
658
|
+
Manager.prototype._initCore = async function () {
|
|
659
|
+
// 初始化管理器
|
|
660
|
+
this._initManager();
|
|
661
|
+
// 加载资源
|
|
662
|
+
await this._loadSources();
|
|
663
|
+
// 初始化AI客户端
|
|
664
|
+
await this._initSources();
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* 执行方法 - 内部方法
|
|
669
|
+
* @param {string} mod 模块对象
|
|
670
|
+
* @param {string} method 方法名称
|
|
671
|
+
* @param {...any} params 参数列表
|
|
672
|
+
* @returns {any} 返回执行结果
|
|
673
|
+
*/
|
|
674
|
+
Manager.prototype._exec = async function (mod, method, ...params) {
|
|
675
|
+
if (mod[method]) {
|
|
676
|
+
return await mod[method](...params);
|
|
677
|
+
} else {
|
|
678
|
+
throw new Error(`方法${method}不存在`);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* 执行方法
|
|
684
|
+
* @param {string} name 模块名
|
|
685
|
+
* @param {string} method 方法名称
|
|
686
|
+
* @param {...any} params 参数列表
|
|
687
|
+
* @returns {any} 返回执行结果
|
|
688
|
+
*/
|
|
689
|
+
Manager.prototype.exec = async function (name, method, ...params) {
|
|
690
|
+
let ret;
|
|
691
|
+
try {
|
|
692
|
+
let mod = this.getMod(name);
|
|
693
|
+
if (!mod) {
|
|
694
|
+
throw new Error(`模块${name}不存在`);
|
|
695
|
+
}
|
|
696
|
+
ret = await this._exec(mod, method, ...params);
|
|
697
|
+
} catch (error) {
|
|
698
|
+
this.log('error', `${method}方法执行失败!`, error);
|
|
699
|
+
}
|
|
700
|
+
return ret;
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* 确保所有模块都已加载
|
|
705
|
+
* @returns {Promise} 加载完成
|
|
706
|
+
*/
|
|
707
|
+
Manager.prototype._ensureAllLoaded = async function () {
|
|
708
|
+
var infos = this.getInfos();
|
|
709
|
+
var promises = [];
|
|
710
|
+
|
|
711
|
+
for (var i = 0; i < infos.length; i++) {
|
|
712
|
+
var mod = this.getMod(infos[i].name);
|
|
713
|
+
if (mod && !mod.isLoaded()) {
|
|
714
|
+
((info) => {
|
|
715
|
+
promises.push(
|
|
716
|
+
mod.call('loadScript').catch((err) => {
|
|
717
|
+
this.log('error', `模块${info.name}加载失败`, err);
|
|
718
|
+
})
|
|
719
|
+
);
|
|
720
|
+
})(infos[i]);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (promises.length > 0) {
|
|
724
|
+
await Promise.all(promises);
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* 异步触发事件,按顺序执行等待完成
|
|
730
|
+
* @param {string} method 方法名称
|
|
731
|
+
* @param {...any} params 事件参数
|
|
732
|
+
* @returns {Promise} 事件触发结果
|
|
733
|
+
*/
|
|
734
|
+
Manager.prototype.runWait = async function (method, ...params) {
|
|
735
|
+
// 参数校验
|
|
736
|
+
if (typeof method !== 'string') {
|
|
737
|
+
throw new TypeError('方法名称必须是字符串');
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
let result;
|
|
741
|
+
let infos = this.getInfos();
|
|
742
|
+
|
|
743
|
+
for (let i = 0; i < infos.length; i++) {
|
|
744
|
+
let info = infos[i];
|
|
745
|
+
let mod = this.getMod(info.name);
|
|
746
|
+
if (!mod) {
|
|
747
|
+
continue; // 跳过不存在的模块
|
|
748
|
+
}
|
|
749
|
+
// 确保模块已加载
|
|
750
|
+
if (!mod.isLoaded()) {
|
|
751
|
+
try {
|
|
752
|
+
await mod.call('loadScript');
|
|
753
|
+
} catch (error) {
|
|
754
|
+
this.log('error', `模块${info.name}加载失败`, error);
|
|
755
|
+
continue; // 跳过加载失败的模块
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// 执行方法
|
|
760
|
+
try {
|
|
761
|
+
let ret = await mod.do(method, ...params);
|
|
762
|
+
if (ret !== null && ret !== undefined) {
|
|
763
|
+
result = ret;
|
|
764
|
+
}
|
|
765
|
+
} catch (error) {
|
|
766
|
+
this.log('error', `模块${info.name}执行${method}方法失败`, error);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return result;
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* 异步触发事件,并发执行不等待
|
|
775
|
+
* @param {string} method 方法名称
|
|
776
|
+
* @param {...any} params 事件参数
|
|
777
|
+
* @returns {boolean} 是否成功触发事件
|
|
778
|
+
*/
|
|
779
|
+
Manager.prototype.runAsync = async function (method, ...params) {
|
|
780
|
+
// 参数校验
|
|
781
|
+
if (typeof method !== 'string') {
|
|
782
|
+
throw new TypeError('方法名称必须是字符串');
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// 确保所有模块都已加载
|
|
786
|
+
await this._ensureAllLoaded();
|
|
787
|
+
|
|
788
|
+
let infos = this.getInfos();
|
|
789
|
+
|
|
790
|
+
// 并发执行所有方法,不等待结果
|
|
791
|
+
for (let i = 0; i < infos.length; i++) {
|
|
792
|
+
let info = infos[i];
|
|
793
|
+
let mod = this.getMod(info.name);
|
|
794
|
+
try {
|
|
795
|
+
mod.do(method, ...params);
|
|
796
|
+
} catch (error) {
|
|
797
|
+
this.log('error', `模块${info.name}执行${method}方法失败`, error);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
return true;
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* 异步触发事件,并发执行等待完成
|
|
806
|
+
* @param {string} method 方法名称
|
|
807
|
+
* @param {...any} params 事件参数
|
|
808
|
+
* @returns {Promise} 事件触发结果
|
|
809
|
+
*/
|
|
810
|
+
Manager.prototype.runAll = async function (method, ...params) {
|
|
811
|
+
// 参数校验
|
|
812
|
+
if (typeof method !== 'string') {
|
|
813
|
+
throw new TypeError('方法名称必须是字符串');
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// 确保所有模块都已加载
|
|
817
|
+
await this._ensureAllLoaded();
|
|
818
|
+
|
|
819
|
+
const promises = [];
|
|
820
|
+
let infos = this.getInfos();
|
|
821
|
+
|
|
822
|
+
// 并发执行所有方法
|
|
823
|
+
for (let i = 0; i < infos.length; i++) {
|
|
824
|
+
let info = infos[i];
|
|
825
|
+
let mod = this.getMod(info.name);
|
|
826
|
+
promises.push(
|
|
827
|
+
mod.do(method, ...params).catch((error) => {
|
|
828
|
+
this.log('error', `模块${info.name}执行${method}方法失败`, error);
|
|
829
|
+
return null; // 失败时返回null
|
|
830
|
+
})
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
return await Promise.all(promises);
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* 异步触发事件,竞争执行
|
|
839
|
+
* @param {string} method 方法名称
|
|
840
|
+
* @param {...any} params 事件参数
|
|
841
|
+
* @returns {Promise} 第一个完成的结果
|
|
842
|
+
*/
|
|
843
|
+
Manager.prototype.runRace = async function (method, ...params) {
|
|
844
|
+
// 参数校验
|
|
845
|
+
if (typeof method !== 'string') {
|
|
846
|
+
throw new TypeError('方法名称必须是字符串');
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// 确保所有模块都已加载
|
|
850
|
+
await this._ensureAllLoaded();
|
|
851
|
+
|
|
852
|
+
const promises = [];
|
|
853
|
+
let infos = this.getInfos();
|
|
854
|
+
|
|
855
|
+
// 竞争执行所有方法
|
|
856
|
+
for (let i = 0; i < infos.length; i++) {
|
|
857
|
+
let info = infos[i];
|
|
858
|
+
let mod = this.getMod(info.name);
|
|
859
|
+
promises.push(
|
|
860
|
+
mod.do(method, ...params).catch((error) => {
|
|
861
|
+
this.log('error', `模块${info.name}执行${method}方法失败`, error);
|
|
862
|
+
throw error; // 竞争执行中,失败应该抛出错误
|
|
863
|
+
})
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
return await Promise.race(promises);
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* 异步触发事件,瀑布流执行
|
|
872
|
+
* @param {string} method 方法名称
|
|
873
|
+
* @param {*} result 初始值
|
|
874
|
+
* @param {...any} params 事件参数
|
|
875
|
+
* @returns {Promise} 最后一个事件监听者的结果
|
|
876
|
+
*/
|
|
877
|
+
Manager.prototype.runWaterfall = async function (method, result, ...params) {
|
|
878
|
+
// 参数校验
|
|
879
|
+
if (typeof method !== 'string') {
|
|
880
|
+
throw new TypeError('方法名称必须是字符串');
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
let infos = this.getInfos();
|
|
884
|
+
|
|
885
|
+
for (let i = 0; i < infos.length; i++) {
|
|
886
|
+
let info = infos[i];
|
|
887
|
+
let mod = this.getMod(info.name);
|
|
888
|
+
|
|
889
|
+
// 确保模块已加载
|
|
890
|
+
if (!mod.isLoaded()) {
|
|
891
|
+
try {
|
|
892
|
+
await mod.call('loadScript');
|
|
893
|
+
} catch (error) {
|
|
894
|
+
this.log('error', `模块${info.name}加载失败`, error);
|
|
895
|
+
continue; // 跳过加载失败的模块
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// 执行方法,将前一个结果作为参数传递给下一个
|
|
900
|
+
try {
|
|
901
|
+
let ret = await mod.do(method, result, ...params);
|
|
902
|
+
if (ret !== null && ret !== undefined) {
|
|
903
|
+
result = ret;
|
|
904
|
+
}
|
|
905
|
+
} catch (error) {
|
|
906
|
+
this.log('error', `模块${info.name}执行${method}方法失败`, error);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
return result;
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* 异步触发事件,子模块执行
|
|
915
|
+
* @param {string} name 子模块名称
|
|
916
|
+
* @param {string} method 方法名称
|
|
917
|
+
* @param {...any} params 事件参数
|
|
918
|
+
* @returns {Promise} 事件触发结果
|
|
919
|
+
*/
|
|
920
|
+
Manager.prototype.runSubMod = async function (name, method, ...params) {
|
|
921
|
+
// 参数校验
|
|
922
|
+
if (typeof method !== 'string') {
|
|
923
|
+
throw new TypeError('方法名称必须是字符串');
|
|
924
|
+
}
|
|
925
|
+
let mod = this.getMod(name);
|
|
926
|
+
if (!mod) {
|
|
927
|
+
throw new Error(`模块${name}不存在`);
|
|
928
|
+
}
|
|
929
|
+
return await mod.do(method, ...params);
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* 移除事件监听
|
|
934
|
+
* @param {string} event 事件名
|
|
935
|
+
*/
|
|
936
|
+
Manager.prototype.offEvent = function (event) {
|
|
937
|
+
this.getEventer()?.off(event);
|
|
938
|
+
};
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* 创建模块
|
|
942
|
+
* @param {object} config 模块配置
|
|
943
|
+
* @param {string} file 模块文件路径
|
|
944
|
+
* @returns {string} 创建的模块文件路径
|
|
945
|
+
*/
|
|
946
|
+
Manager.prototype.createFile = function (config, file) {
|
|
947
|
+
if (!config.name) {
|
|
948
|
+
throw new TypeError('模块名称不能为空');
|
|
949
|
+
}
|
|
950
|
+
if (!config.title) {
|
|
951
|
+
throw new TypeError('模块标题不能为空');
|
|
952
|
+
}
|
|
953
|
+
if (!config.description) {
|
|
954
|
+
throw new TypeError('模块描述不能为空');
|
|
955
|
+
}
|
|
956
|
+
if (this.getMod(config.name)) {
|
|
957
|
+
throw new Error(`创建失败,原因:模块${config.name}已存在`);
|
|
958
|
+
}
|
|
959
|
+
let mod = new this.Drive(config, this);
|
|
960
|
+
let f = file;
|
|
961
|
+
if (!f) {
|
|
962
|
+
f = `${config.name}/${this.config.filename}`;
|
|
963
|
+
if (this.config.search_way === 'dir') {
|
|
964
|
+
let dir_name = this.getDirName();
|
|
965
|
+
f = `${dir_name}/${f}`;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
f = f.fullname(this.config.dir);
|
|
969
|
+
mod.createConfigFile(f, config);
|
|
970
|
+
return f;
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* 创建模块
|
|
975
|
+
* @param {object} config 模块配置
|
|
976
|
+
* @param {string} file 模块文件路径
|
|
977
|
+
* @returns {object} 创建的模块实例
|
|
978
|
+
*/
|
|
979
|
+
Manager.prototype.create = function (config, file = '') {
|
|
980
|
+
let f = this.createFile(config, file);
|
|
981
|
+
let mod = this.registerMod(f, config);
|
|
982
|
+
return mod;
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* 删除模块
|
|
987
|
+
* @param {string} name 模块名称
|
|
988
|
+
* @returns {object} 删除的模块实例
|
|
989
|
+
*/
|
|
990
|
+
Manager.prototype.remove = async function (name) {
|
|
991
|
+
let mod = this.getMod(name);
|
|
992
|
+
if (mod) {
|
|
993
|
+
await mod.remove();
|
|
994
|
+
}
|
|
995
|
+
this.unregisterMod(name);
|
|
996
|
+
return mod;
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
module.exports = {
|
|
1000
|
+
Manager,
|
|
1001
|
+
Drive,
|
|
1002
|
+
Mod,
|
|
1003
|
+
// 向后兼容
|
|
1004
|
+
Index: Manager,
|
|
1005
|
+
Item: Drive
|
|
1006
|
+
};
|