@shijiu/jsview-vue 2.0.1021 → 2.0.1073

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.
Files changed (33) hide show
  1. package/package.json +4 -3
  2. package/utils/JsViewEngineWidget/CheckType.js +82 -0
  3. package/utils/JsViewEngineWidget/MetroWidget/AnimationManager.ts +72 -0
  4. package/utils/JsViewEngineWidget/MetroWidget/Const.ts +24 -0
  5. package/utils/JsViewEngineWidget/MetroWidget/ListWidget.vue +295 -0
  6. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +110 -1651
  7. package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +1867 -0
  8. package/utils/JsViewEngineWidget/MetroWidget/PageUpdater.ts +111 -0
  9. package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +153 -0
  10. package/utils/JsViewEngineWidget/MetroWidget/VisibleInfo.ts +43 -0
  11. package/utils/JsViewEngineWidget/MetroWidget/WidgetRectInfo.ts +49 -0
  12. package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +1424 -0
  13. package/utils/JsViewEngineWidget/TemplateParser/Fence.ts +135 -0
  14. package/utils/JsViewEngineWidget/TemplateParser/ListMetroTemplate.ts +177 -0
  15. package/utils/JsViewEngineWidget/TemplateParser/MetroTemplate.ts +334 -0
  16. package/utils/JsViewEngineWidget/TemplateParser/TemplateItemAdder.ts +147 -0
  17. package/utils/JsViewEngineWidget/TemplateParser/index.ts +4 -0
  18. package/utils/JsViewEngineWidget/{WidgetCommon.js → WidgetCommon.ts} +64 -71
  19. package/utils/JsViewEngineWidget/index.js +2 -1
  20. package/utils/JsViewPlugin/JsvAudio/AudioProxy.js +26 -1
  21. package/utils/JsViewPlugin/JsvAudio/JsvAudio.vue +120 -133
  22. package/utils/JsViewPlugin/JsvAudio/JsvAudioBrowser.vue +11 -7
  23. package/utils/JsViewPlugin/JsvPlayer/GetVersion.js +1 -1
  24. package/utils/JsViewPlugin/JsvPlayer/JsvPlayerBrowser.vue +379 -41
  25. package/utils/JsViewPlugin/JsvPlayer/version.mjs +5 -5
  26. package/utils/JsViewVueTools/JsvHashHistory.js +2 -1
  27. package/utils/JsViewVueWidget/JsvRadarChart.vue +220 -0
  28. package/utils/JsViewVueWidget/JsvSystemAudio.vue +76 -44
  29. package/utils/JsViewVueWidget/index.js +1 -0
  30. package/utils/JsViewEngineWidget/MetroWidget/Const.js +0 -11
  31. package/utils/JsViewEngineWidget/MetroWidget/PageUpdater.js +0 -136
  32. package/utils/JsViewEngineWidget/MetroWidget/ToolFunctions.js +0 -18
  33. package/utils/JsViewEngineWidget/TemplateParser.js +0 -2004
@@ -0,0 +1,135 @@
1
+ interface GapInfo {
2
+ readonly GapStart: number,
3
+ readonly GapEnd: number,
4
+ }
5
+
6
+ class Fence {
7
+ /**
8
+ * MetroLayout用于计算使用区域的Fence(栅栏)
9
+ *
10
+ * @private
11
+ * @constructor _Fence
12
+ * @memberof Forge.MetroLayout
13
+ * @param {int} takenStartPos 栅栏使用区域的起始位置
14
+ * @param {int} width 栅栏使用区域的宽度
15
+ * @param {int} fenceWidth 栅栏的总宽度
16
+ * @param {int} offsetAhead 栅栏的横向位置
17
+ * */
18
+ private Gaps: Array<GapInfo>;
19
+ private FenceTotalWidth: number;
20
+ private AheadOffsetInner: number;
21
+
22
+ constructor(takenStartPos: number, width: number, fenceWidth: number, offsetAhead: number) {
23
+ this.Gaps = [{ GapStart: 0, GapEnd: fenceWidth - 1 }];
24
+ this.FenceTotalWidth = fenceWidth;
25
+ this.AheadOffsetInner = offsetAhead;
26
+ if (width > 0) this.SplitGap(0, takenStartPos, width);
27
+ }
28
+
29
+ get AheadOffset(): number {
30
+ return this.AheadOffsetInner;
31
+ }
32
+
33
+ /**
34
+ * 查询栅栏是否能放下给定宽度的方块
35
+ *
36
+ * @public
37
+ * @func HasGapFor
38
+ * @memberof Forge.MetroLayout._Fence
39
+ * @instance
40
+ * @param {int} width
41
+ * @return {Object} 格式为{startPos: 栅栏空隙的起始位置},null为没有能容下的空隙。
42
+ * */
43
+ HasGapFor(width: number): GapInfo | null {
44
+ for (let i = 0; i < this.Gaps.length; i++) {
45
+ if (this.Gaps[i].GapEnd - this.Gaps[i].GapStart + 1 >= width) {
46
+ return this.Gaps[i];
47
+ }
48
+ }
49
+
50
+ return null;
51
+ }
52
+
53
+ /**
54
+ * 标记栅栏空隙被占用
55
+ *
56
+ * @public
57
+ * @func MarkGapUsed
58
+ * @memberof Forge.MetroLayout._Fence
59
+ * @instance
60
+ * @param {int} startPos 占用块的起始位置
61
+ * @param {int} width 占用快的宽度
62
+ * @return {int} 剩余栅栏的个数
63
+ * */
64
+ MarkGapUsed(startPos: number, width: number): number {
65
+ if (width <= 0) return this.Gaps.length;
66
+
67
+ const end_pos = startPos + width - 1;
68
+ let gapIdx = -1;
69
+ for (let i = 0; i < this.Gaps.length; i++) {
70
+ if (
71
+ this.Gaps[i].GapStart <= startPos &&
72
+ this.Gaps[i].GapEnd >= end_pos
73
+ ) {
74
+ gapIdx = i;
75
+ break;
76
+ }
77
+ }
78
+
79
+ if (gapIdx === -1) {
80
+ return 0; // 区域完全重复,无法找到新区域
81
+ }
82
+
83
+ this.SplitGap(gapIdx, startPos, width);
84
+
85
+ return this.Gaps.length;
86
+ }
87
+
88
+ private SplitGap(gapIdx: number, takerStartPos: number, takerWidth: number) {
89
+ const editGap = this.Gaps.splice(gapIdx, 1)[0];
90
+ const takerEndPos = takerStartPos + takerWidth - 1;
91
+
92
+ if (
93
+ takerStartPos < editGap.GapStart ||
94
+ takerEndPos > editGap.GapEnd
95
+ ) {
96
+ console.log("ERROR in split Fence Gap, range overflow");
97
+ }
98
+
99
+ // Insert end side gap
100
+ if (takerEndPos !== editGap.GapEnd) {
101
+ this.Gaps.splice(gapIdx, 0, {
102
+ GapStart: takerEndPos + 1,
103
+ GapEnd: editGap.GapEnd,
104
+ });
105
+ }
106
+
107
+ // Insert start side gap
108
+ if (takerStartPos !== editGap.GapStart) {
109
+ this.Gaps.splice(gapIdx, 0, {
110
+ GapStart: editGap.GapStart,
111
+ GapEnd: takerStartPos - 1,
112
+ });
113
+ }
114
+ }
115
+
116
+ /**
117
+ * 标记栅栏空隙被占用
118
+ *
119
+ * @public
120
+ * @func Fork
121
+ * @memberof Forge.MetroLayout._Fence
122
+ * @instance
123
+ * @param {int} new_ahead_offset 新栅栏的起点位置
124
+ * @return {Forge.MetroLayout._Fence} 复制出来的Fence
125
+ * */
126
+ Fork(new_ahead_offset: number): Fence {
127
+ const newFence = new Fence(0, 0, 0, 0);
128
+ newFence.Gaps = JSON.parse(JSON.stringify(this.Gaps));
129
+ newFence.FenceTotalWidth = this.FenceTotalWidth;
130
+ newFence.AheadOffsetInner = new_ahead_offset;
131
+
132
+ return newFence;
133
+ }
134
+ }
135
+ export { Fence, GapInfo }
@@ -0,0 +1,177 @@
1
+ import { MetroTemplate, TemplateItem, MeasureInfo } from "./MetroTemplate"
2
+ import { VERTICAL, HORIZONTAL, FocusMoveType } from "../WidgetCommon";
3
+
4
+ const TAG = "ListMetroTemplate";
5
+
6
+ /** 单行/单列 */
7
+ class ListMetroTemplate extends MetroTemplate {
8
+ constructor(direction: Symbol, lineMax: number, pageSize: number, layoutType: string) {
9
+ super(direction, lineMax, pageSize, layoutType, false);
10
+ }
11
+
12
+ public calculateNeighborWhenAddStop(): void { }
13
+
14
+ public addItem(itemObj: MeasureInfo): TemplateItem {
15
+ const templateItem = MetroTemplate.getTemplateItem(itemObj);
16
+ this._addTemplateItem(templateItem);
17
+ return templateItem;
18
+ }
19
+
20
+ private _addTemplateItem(templateItem: TemplateItem): void {
21
+ let sizeKey = this.direction == VERTICAL ? "width" : "height";
22
+ if (templateItem[sizeKey] > this.lineMax) {
23
+ throw new Error(`item size is ${templateItem.width}x${templateItem.height}, large than lineMax ${this.lineMax}`);
24
+ }
25
+
26
+ const preItem = this.getItemByIndex(this.size - 1);
27
+ this.addTemplateItem(templateItem);
28
+
29
+ if (this.direction == VERTICAL) {
30
+ //position
31
+ if (this.layoutType == "relative") {
32
+ templateItem.left = 0;
33
+ templateItem.top = preItem ? preItem.top + preItem.height + preItem.marginBottom : 0;
34
+ }
35
+ //neighbor
36
+ if (preItem) {
37
+ templateItem.neighborIndexList.top.push(preItem.index);
38
+ preItem.neighborIndexList.bottom.push(templateItem.index);
39
+ }
40
+ } else {
41
+ if (this.layoutType == "relative") {
42
+ templateItem.top = 0;
43
+ templateItem.left = preItem ? preItem.left + preItem.width + preItem.marginRight : 0;
44
+ }
45
+ if (preItem) {
46
+ templateItem.neighborIndexList.left.push(preItem.index);
47
+ preItem.neighborIndexList.right.push(templateItem.index);
48
+ }
49
+ }
50
+ templateItem.centerXPos = Math.floor(templateItem.left + templateItem.width / 2) - 1;
51
+ templateItem.centerYPos = Math.floor(templateItem.top + templateItem.height / 2) - 1;
52
+
53
+ //分页相关的计算
54
+ let curPageNumber = 0;
55
+ let curPageHeadIndex = 0;
56
+ if (preItem) {
57
+ curPageNumber = preItem.pageNumber;
58
+ curPageHeadIndex = preItem.pageHeadIndex;
59
+ let positionKey = "left";
60
+ let sizeKey = "width";
61
+ if (this.direction === VERTICAL) {
62
+ positionKey = "top";
63
+ sizeKey = "height";
64
+ }
65
+ const curPageStart =
66
+ this.templateList[curPageHeadIndex][positionKey];
67
+ if (
68
+ templateItem[positionKey] + templateItem[sizeKey] >
69
+ curPageStart + this.pageSize
70
+ ) {
71
+ //新的页
72
+ curPageNumber++;
73
+ curPageHeadIndex = templateItem.index;
74
+ }
75
+ }
76
+
77
+ templateItem.pageNumber = curPageNumber;
78
+ templateItem.pageHeadIndex = curPageHeadIndex;
79
+ }
80
+
81
+ public getNextItem(baseId: number, vOffset: number,
82
+ hOffset: number, moveType: number): TemplateItem | null {
83
+ const item = this.getItemById(baseId);
84
+ if (item) {
85
+ let neighborDirection: string | null = null;
86
+ if (this.direction == VERTICAL) {
87
+ if (vOffset > 0) {
88
+ neighborDirection = "bottom";
89
+ } else if (vOffset < 0) {
90
+ neighborDirection = "top";
91
+ }
92
+ } else {
93
+ if (hOffset > 0) {
94
+ neighborDirection = "right";
95
+ } else if (hOffset < 0) {
96
+ neighborDirection = "left";
97
+ }
98
+ }
99
+ if (!neighborDirection) return null;
100
+ let target = this.getItemByIndex(item.neighborIndexList[neighborDirection]?.[0]);
101
+ while (target) {
102
+ if (target.focusable) {
103
+ break;
104
+ } else {
105
+ target = this.getItemByIndex(item.neighborIndexList[neighborDirection]?.[0]);
106
+ }
107
+ }
108
+ return target;
109
+ }
110
+ return null;
111
+ }
112
+
113
+ public getVisibleItemList(visibleStart: number, visibleEnd: number,
114
+ baseId: number): [number, number] {
115
+ const positionKey = this.direction == VERTICAL ? "top" : "left";
116
+ const sizeKey = this.direction == VERTICAL ? "height" : "width";
117
+ //template is empty
118
+ if (this.size == 0) { return [-1, -1]; }
119
+ const lastItem = this.templateList[this.templateList.length - 1];
120
+ // invalid visible range
121
+ if (visibleStart >= visibleEnd || visibleEnd < 0 || visibleStart >= lastItem[positionKey] + lastItem[sizeKey]) {
122
+ return [-1, -1]
123
+ }
124
+
125
+
126
+
127
+ let item = this.getItemById(baseId);
128
+ const startIndex = item ? item.index : Math.round(this.size / 2);
129
+ let start = -1, end = -1;
130
+ let index = startIndex;
131
+
132
+ //forward
133
+ while (index >= 0) {
134
+ const item = this.getItemByIndex(index);
135
+ if (!item) break;
136
+ if (item[positionKey] + item[sizeKey] > visibleStart) {
137
+ start = item.index;
138
+ }
139
+ if (end < 0 && item[positionKey] <= visibleEnd) {
140
+ end = item.index;
141
+ }
142
+ --index;
143
+ }
144
+ //backward
145
+ index = startIndex;
146
+ const s = this.size;
147
+ while (index < s) {
148
+ const item = this.getItemByIndex(index);
149
+ if (!item) break;
150
+ if (item[positionKey] <= visibleEnd) {
151
+ end = item.index;
152
+ }
153
+ if (start < 0 && item[positionKey] + item[sizeKey] > visibleStart) {
154
+ start = item.index;
155
+ }
156
+ ++index;
157
+ }
158
+ return [start, end];
159
+ }
160
+
161
+ public updateItemSize(index: number, newSize: { width: number, height: number }): void {
162
+ const needChangeList = this.templateList.splice(index);
163
+ needChangeList[0].width = newSize.width;
164
+ needChangeList[0].height = newSize.height;
165
+ for (let i of needChangeList) {
166
+ if (i.id >= 0) {
167
+ this.idsMap.splice(i.id);
168
+ break;
169
+ }
170
+ }
171
+ for (let i of needChangeList) {
172
+ this._addTemplateItem(i);
173
+ }
174
+ }
175
+ }
176
+
177
+ export { ListMetroTemplate };
@@ -0,0 +1,334 @@
1
+ import { checkType, toRawType, getTypeName } from "../CheckType.js";
2
+
3
+ const TAG = "MetroTemplate";
4
+
5
+ const measureObjectDefine = {
6
+ left: {
7
+ type: Number,
8
+ default: 0,
9
+ validator(value: number, errorLogger: Function) {
10
+ if (Math.round(value) != value) {
11
+ errorLogger(`prop left value expected integer, got float. value is ${value}`);
12
+ return false;
13
+ }
14
+ return true;
15
+ }
16
+ },
17
+ top: {
18
+ type: Number,
19
+ default: 0,
20
+ validator(value: number, errorLogger: Function) {
21
+ if (Math.round(value) != value) {
22
+ errorLogger(`prop top value expected integer, got float. value is ${value}`);
23
+ return false;
24
+ }
25
+ return true;
26
+ }
27
+ },
28
+ width: {
29
+ type: Number,
30
+ validator(value: number, errorLogger: Function) {
31
+ const _v = Math.round(value);
32
+ if (_v != value) {
33
+ errorLogger(`prop width value expected integer, got float. value is ${value}`);
34
+ return false;
35
+ }
36
+ if (_v <= 0) {
37
+ errorLogger(`prop width value must be larger than 0. value is ${value}`);
38
+ return false;
39
+ }
40
+ return true;
41
+ }
42
+ },
43
+ height: {
44
+ type: Number,
45
+ validator(value: number, errorLogger: Function) {
46
+ const _v = Math.round(value);
47
+ if (_v != value) {
48
+ errorLogger(`prop height value expected integer, got float. value is ${value}`);
49
+ return false;
50
+ }
51
+ if (_v <= 0) {
52
+ errorLogger(`prop height value must be larger than 0. value is ${value}`);
53
+ return false;
54
+ }
55
+ return true;
56
+ }
57
+ },
58
+ marginRight: {
59
+ type: Number,
60
+ default: 0,
61
+ validator(value: number, errorLogger: Function) {
62
+ if (Math.round(value) != value) {
63
+ errorLogger(`prop marginRight value expected integer, got float. value is ${value}`);
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+ },
69
+ marginBottom: {
70
+ type: Number,
71
+ default: 0,
72
+ validator(value: number, errorLogger: Function) {
73
+ if (Math.round(value) != value) {
74
+ errorLogger(`prop marginBottom value expected integer, got float. value is ${value}`);
75
+ return false;
76
+ }
77
+ return true;
78
+ }
79
+ },
80
+ focusable: {
81
+ type: Boolean,
82
+ default: true,
83
+ },
84
+ findNextAnchor: {
85
+ type: [Object, null],
86
+ default: null,
87
+ validator(value, errorLogger) {
88
+ if (value) {
89
+ if (!checkType(value.left, Number)) {
90
+ errorLogger(`findNextAnchor.left expected integer, got ${toRawType(value.left)}. value is ${value.left}`)
91
+ return false;
92
+ }
93
+ if (!checkType(value.top, Number)) {
94
+ errorLogger(`findNextAnchor.top expected integer, got ${toRawType(value.top)}. value is ${value.top}`)
95
+ return false;
96
+ }
97
+ if (!checkType(value.right, Number)) {
98
+ errorLogger(`findNextAnchor.right expected integer, got ${toRawType(value.right)}. value is ${value.right}`)
99
+ return false;
100
+ }
101
+ if (!checkType(value.bottom, Number)) {
102
+ errorLogger(`findNextAnchor.bottom expected integer, got ${toRawType(value.bottom)}. value is ${value.bottom}`)
103
+ return false;
104
+ }
105
+ }
106
+ return true;
107
+ }
108
+ },
109
+ doSlide: {
110
+ type: Boolean,
111
+ default: true,
112
+ },
113
+ permanent: {
114
+ type: Boolean,
115
+ default: false,
116
+ },
117
+ zIndex: {
118
+ type: Number,
119
+ default: -1,
120
+ },
121
+ }
122
+
123
+ interface NeighborInfo {
124
+ left: Array<number>,
125
+ top: Array<number>,
126
+ bottom: Array<number>,
127
+ right: Array<number>,
128
+ }
129
+
130
+ interface FindNextAnchor {
131
+ left: number,
132
+ top: number,
133
+ right: number,
134
+ bottom: number,
135
+ }
136
+
137
+ interface TemplateItem {
138
+ id: number,
139
+ index: number,
140
+ left: number,
141
+ top: number,
142
+ width: number,
143
+ height: number,
144
+ marginRight: number,
145
+ marginBottom: number,
146
+ focusable: boolean,
147
+
148
+ centerXPos: number,
149
+ centerYPos: number,
150
+ pageNumber: number,
151
+ pageHeadIndex: number,
152
+ neighborIndexList: NeighborInfo,
153
+ tmpNeighborIndexList: NeighborInfo,
154
+ pathHistory: {
155
+ left: number,
156
+ right: number,
157
+ top: number,
158
+ bottom: number,
159
+ }
160
+ findNextAnchor: FindNextAnchor | null,
161
+ }
162
+
163
+ interface MeasureInfo {
164
+ left?: number,
165
+ top?: number,
166
+ width: number,
167
+ height: number,
168
+ marginRight?: number,
169
+ marginBottom?: number,
170
+ focusable?: boolean,
171
+
172
+ findNextAnchor?: FindNextAnchor | null,
173
+ doSlide?: boolean,
174
+ permanent?: boolean,
175
+ zIndex?: number | object,
176
+ }
177
+
178
+ abstract class MetroTemplate {
179
+ protected supportHistoryPath: boolean;
180
+ protected idsMap: Array<number>;
181
+ public templateList: Array<TemplateItem>;
182
+ public readonly direction: Symbol;
183
+ public readonly lineMax: number;
184
+ public readonly pageSize: number;
185
+ public readonly layoutType: string;
186
+
187
+ constructor(direction: Symbol, lineMax: number, pageSize: number, layoutType: string, supportHistoryPath: boolean) {
188
+ this.idsMap = [];
189
+ this.templateList = [];
190
+ this.direction = direction;
191
+ this.lineMax = lineMax;
192
+ this.layoutType = layoutType
193
+ this.pageSize = pageSize;
194
+ this.supportHistoryPath = supportHistoryPath;
195
+ }
196
+
197
+ get size(): number {
198
+ return this.templateList.length;
199
+ }
200
+
201
+ get focusableSize(): number {
202
+ return this.idsMap.length;
203
+ }
204
+
205
+ protected addTemplateItem(item: TemplateItem) {
206
+ this.templateList.push(item);
207
+ item.index = this.templateList.length - 1;
208
+ if (item.focusable) {
209
+ this.idsMap.push(item.index);
210
+ item.id = this.idsMap.length - 1;
211
+ } else {
212
+ item.id = -1;
213
+ }
214
+ }
215
+
216
+ public index2Id(index: number): number {
217
+ const item = this.templateList[index];
218
+ if (typeof item == "undefined") {
219
+ console.warn(TAG, "index not exist", index, ", template length", this.templateList.length);
220
+ return -1;
221
+ } else {
222
+ return item.id
223
+ }
224
+ }
225
+
226
+ public id2Index(id: number): number {
227
+ const index = this.idsMap[id];
228
+ if (typeof index == "undefined") {
229
+ console.warn(TAG, "id not exist", id);
230
+ return -1;
231
+ }
232
+ return index;
233
+ }
234
+
235
+ public getItemById(id: number): TemplateItem | null {
236
+ return this.getItemByIndex(this.id2Index(id));
237
+ }
238
+
239
+ public getItemByIndex(index: number): TemplateItem | null {
240
+ const item = index >= 0
241
+ ? this.templateList[index]
242
+ : this.templateList[this.templateList.length + index];
243
+ return item ? item : null;
244
+ }
245
+
246
+ public abstract calculateNeighborWhenAddStop(): void;
247
+
248
+ public abstract addItem(itemObj: MeasureInfo): TemplateItem;
249
+
250
+ public abstract getNextItem(baseId: number, hOffset: number, vOffset: number, moveType: number): TemplateItem | null;
251
+
252
+ public abstract getVisibleItemList(visibleStart: number, visibleEnd: number, baseId: number): [number, number];
253
+
254
+ public abstract updateItemSize(index: number,
255
+ newSize: { width: number, height: number }): void;
256
+
257
+ protected static getTemplateItem(itemObj: MeasureInfo): TemplateItem {
258
+ const valid = this.checkMeasureObject(itemObj);
259
+ if (!valid) {
260
+ throw new Error("check measure object failed.");
261
+ }
262
+
263
+ return {
264
+ id: -1,
265
+ index: -1,
266
+ centerXPos: 0, // Set after template be layout
267
+ centerYPos: 0, // Set after template be layout
268
+ pageNumber: 0,
269
+ pageHeadIndex: 0,
270
+
271
+ width: itemObj.width,
272
+ height: itemObj.height,
273
+ left: itemObj.left ? itemObj.left : 0,
274
+ top: itemObj.top ? itemObj.top : 0,
275
+ marginRight: itemObj.marginRight ? itemObj.marginRight : 0,
276
+ marginBottom: itemObj.marginBottom ? itemObj.marginBottom : 0,
277
+ focusable: itemObj.focusable ? itemObj.focusable : true,
278
+ findNextAnchor: itemObj.findNextAnchor ? itemObj.findNextAnchor : null,
279
+
280
+ neighborIndexList: {
281
+ left: [],
282
+ top: [],
283
+ right: [],
284
+ bottom: [],
285
+ },
286
+ tmpNeighborIndexList: {
287
+ left: [],
288
+ top: [],
289
+ right: [],
290
+ bottom: [],
291
+ },
292
+ pathHistory: {
293
+ left: -1,
294
+ right: -1,
295
+ top: -1,
296
+ bottom: -1,
297
+ },
298
+ }
299
+ }
300
+
301
+ private static checkMeasureObject(obj: object): boolean {
302
+ let result = true;
303
+ const errorLog = (errorInfo) => {
304
+ console.error(TAG, "measure obj check error: ", errorInfo, ". raw object", obj);
305
+ }
306
+ for (let key in measureObjectDefine) {
307
+ const defineInfo = measureObjectDefine[key];
308
+ if (typeof obj[key] == "undefined") {
309
+ if (typeof defineInfo.default != "undefined") {
310
+ obj[key] = typeof defineInfo.default == "function" ? defineInfo.default() : defineInfo.default;
311
+ }
312
+ }
313
+ if (checkType(obj[key], defineInfo.type)) {
314
+ if (typeof defineInfo.validator != "undefined") {
315
+ if (!defineInfo.validator(obj[key], errorLog)) {
316
+ result = false;
317
+ break;
318
+ }
319
+ }
320
+ } else {
321
+ result = false;
322
+ errorLog(`prop ${key} expected ${getTypeName(defineInfo.type)} value, got ${toRawType(obj[key])}`)
323
+ break;
324
+ }
325
+ }
326
+ return result;
327
+ }
328
+ }
329
+
330
+ export {
331
+ MeasureInfo,
332
+ MetroTemplate,
333
+ TemplateItem,
334
+ }