1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { BaseElement, element } from '../../../base-ui/BaseElement'; 17import '../../../base-ui/select/LitSelectV'; 18import '../../../base-ui/select/LitSelect'; 19 20import '../../../base-ui/switch/lit-switch'; 21import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; 22import { LitSelectV } from '../../../base-ui/select/LitSelectV'; 23import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; 24import { SpSdkConfigHtml } from './SpSdkConfig.html'; 25 26@element('sp-sdk-config') 27export class SpSdkConfig extends BaseElement { 28 private worker: Worker | undefined; 29 private sdkConfigList: unknown; 30 private customConfig: HTMLDivElement | undefined | null; 31 private selectConfig: LitSelectV | undefined | null; 32 private list: Array<HTMLElement> | undefined; 33 private pluginName: string = ''; 34 private sampleInterval: number = 5000; 35 36 static get observedAttributes(): string[] { 37 return ['configName', 'value', 'type']; 38 } 39 40 get show(): boolean { 41 return this.hasAttribute('show'); 42 } 43 44 set show(sdkConfigShow: boolean) { 45 if (sdkConfigShow) { 46 this.setAttribute('show', ''); 47 } else { 48 this.removeAttribute('show'); 49 } 50 } 51 52 set startSamp(sdkConfigStart: boolean) { 53 if (sdkConfigStart) { 54 this.setAttribute('startSamp', ''); 55 } else { 56 this.removeAttribute('startSamp'); 57 } 58 } 59 60 get startSamp(): boolean { 61 return this.hasAttribute('startSamp'); 62 } 63 64 set configName(configName: string) { 65 if (configName !== '') { 66 this.setAttribute('configName', configName); 67 } else { 68 this.removeAttribute('configName'); 69 } 70 } 71 72 get configName(): string { 73 return this.getAttribute('configName') || ''; 74 } 75 76 get type(): string { 77 return this.getAttribute('type') || ''; 78 } 79 80 set type(type: string) { 81 if (type !== '') { 82 this.setAttribute('type', type); 83 } else { 84 this.removeAttribute('type'); 85 } 86 } 87 88 private wasmMap: Map<string, unknown> = new Map<string, unknown>(); 89 private wasmList: Array<string> = []; 90 91 private changGpu(gpuName: string): void { 92 let config = this.wasmMap.get(gpuName); 93 //@ts-ignore 94 this.pluginName = config?.pluginName; 95 //@ts-ignore 96 this.sampleInterval = config?.sampleInterval; 97 let pam = { 98 action: 'open', 99 //@ts-ignore 100 componentId: config.componentId, 101 //@ts-ignore 102 wasmJsName: config.wasmJsName, 103 //@ts-ignore 104 WasmName: config.wasmName, 105 }; 106 this.worker!.postMessage(pam); 107 this.worker!.onmessage = (event: MessageEvent): void => { 108 let results = event.data.results; 109 this.sdkConfigList = results.settingConfig; 110 this.initConfig(); 111 }; 112 } 113 114 getPlugName(): string { 115 return this.pluginName; 116 } 117 118 getSampleInterval(): number { 119 return this.sampleInterval; 120 } 121 122 getGpuConfig(): {} { 123 let configVal = this.shadowRoot?.querySelectorAll<HTMLElement>('.config'); 124 let gpuConfig = {}; 125 for (let i = 0; i < configVal!.length; i++) { 126 let configName = configVal![i].getAttribute('configName'); 127 let type = configVal![i].getAttribute('type'); 128 if (type === 'enum') { 129 let enumValue = configVal![i].getAttribute('value'); 130 if (enumValue !== undefined && enumValue !== 'undefined') { 131 // @ts-ignore 132 gpuConfig[configName!] = enumValue; 133 } 134 } else if (type === 'number' || type === 'integer' || type === 'num') { 135 // @ts-ignore 136 gpuConfig[configName!] = Number(configVal![i].value); 137 } else if (type === 'boolean') { 138 let attribute = configVal![i].getAttribute('value'); 139 // @ts-ignore 140 gpuConfig[configName!] = attribute === 'true'; 141 } else { 142 // @ts-ignore 143 gpuConfig[configName!] = configVal![i].value; 144 } 145 } 146 return gpuConfig; 147 } 148 149 private initSdkWasm(): void { 150 try { 151 let spApplication = document.querySelector<HTMLElement>('sp-application'); 152 let wasmJsonUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; 153 if (spApplication!.hasAttribute('vs')) { 154 wasmJsonUrl = `http://${window.location.host.split(':')[0]}:${window.location.port}/wasm.json`; 155 } 156 fetch(wasmJsonUrl) 157 .then((res): void => { 158 if (res.ok) { 159 res.text().then((text) => { 160 this.wasmMap = new Map(); 161 this.wasmList = []; 162 let wasmJson = JSON.parse(text); 163 let wasmFiles = wasmJson.WasmFiles; 164 wasmFiles.forEach((wasmFile: unknown) => { 165 //@ts-ignore 166 this.wasmMap.set(wasmFile.disPlayName, wasmFile); 167 //@ts-ignore 168 this.wasmList.push(wasmFile.disPlayName); 169 }); 170 }); 171 } 172 }) 173 .catch(() => { }); 174 if (this.worker === null) { 175 // @ts-ignore 176 if (window.useWb) { 177 return; 178 } 179 this.worker = new Worker(new URL('../../database/ConfigWorker', import.meta.url)); 180 } 181 } catch (e) { } 182 } 183 184 initElements(): void { 185 this.initSdkWasm(); 186 this.customConfig = this.shadowRoot?.querySelector<HTMLDivElement>('.configList'); 187 let switchButton = this.shadowRoot?.querySelector('.config_switch') as LitSwitch; 188 switchButton.addEventListener('change', (event: CustomEventInit<LitSwitchChangeEvent>) => { 189 let detail = event.detail; 190 if (detail!.checked) { 191 this.startSamp = true; 192 this.isAbleShowConfig(false); 193 } else { 194 this.startSamp = false; 195 this.isAbleShowConfig(true); 196 } 197 }); 198 this.selectConfig = this.shadowRoot?.querySelector<LitSelectV>('lit-select-v'); 199 let inputDiv = this.selectConfig?.shadowRoot?.querySelector('input') as HTMLDivElement; 200 inputDiv.addEventListener('mousedown', () => { 201 if (this.startSamp) { 202 inputDiv!.removeAttribute('readonly'); 203 this.selectConfig!.dataSource(this.wasmList, '', true); 204 } else { 205 inputDiv!.setAttribute('readonly', 'readonly'); 206 return; 207 } 208 }); 209 this.list = []; 210 this.list.push(this.selectConfig!); 211 this.isAbleShowConfig(true); 212 } 213 214 private sdkConfigByBooleanType(key: string, sdkConfigSwitch: LitSwitch, sdkConfigHeadDiv: HTMLDivElement): void { 215 sdkConfigSwitch.className = 'switch1 config'; 216 sdkConfigSwitch.setAttribute('configName', key); 217 //@ts-ignore 218 sdkConfigSwitch.setAttribute('type', this.sdkConfigList.configuration[key].type); 219 //@ts-ignore 220 if (this.sdkConfigList.configuration[key].default === 'true') { 221 sdkConfigSwitch.setAttribute('checked', ''); 222 sdkConfigSwitch.setAttribute('value', 'true'); 223 } else { 224 sdkConfigSwitch.removeAttribute('checked'); 225 sdkConfigSwitch.setAttribute('value', 'false'); 226 } 227 sdkConfigHeadDiv.appendChild(sdkConfigSwitch); 228 this.list!.push(sdkConfigSwitch); 229 } 230 231 private sdkConfigByIntegerType(key: string, sdkConfigDiv: HTMLDivElement, sdkConfigTitle: HTMLSpanElement): void { 232 let input = document.createElement('input'); 233 input.className = 'sdk-config-input config'; 234 //@ts-ignore 235 if (this.sdkConfigList.configuration[key].default) { 236 //@ts-ignore 237 input.value = this.sdkConfigList.configuration[key].default; 238 } 239 input.setAttribute('configName', key); 240 //@ts-ignore 241 input.setAttribute('type', this.sdkConfigList.configuration[key].type); 242 input.oninput = (): void => { 243 input.value = this.checkIntegerInput(input.value); 244 sdkConfigTitle.setAttribute('value', input.value); 245 }; 246 sdkConfigDiv.appendChild(input); 247 this.list!.push(input); 248 } 249 250 private sdkConfigByNumberType(key: string, sdkConfigDiv: HTMLDivElement): void { 251 let numberInput = document.createElement('input'); 252 numberInput.className = 'sdk-config-input config'; 253 //@ts-ignore 254 if (this.sdkConfigList.configuration[key].default) { 255 //@ts-ignore 256 numberInput.value = this.sdkConfigList.configuration[key].default; 257 } 258 numberInput.setAttribute('configName', key); 259 numberInput.setAttribute('type', 'num'); 260 numberInput.oninput = (): void => { 261 numberInput.value = this.checkFloatInput(numberInput.value); 262 }; 263 sdkConfigDiv.appendChild(numberInput); 264 this.list!.push(numberInput); 265 } 266 267 private sdkConfigByStringType(key: string, sdkConfigDiv: HTMLDivElement): void { 268 let html = ''; 269 //@ts-ignore 270 if (this.sdkConfigList.configuration[key].enum) { 271 let placeholder = ''; 272 //@ts-ignore 273 if (this.sdkConfigList.configuration[key].default) { 274 //@ts-ignore 275 placeholder = this.sdkConfigList.configuration[key].default; 276 } 277 //@ts-ignore 278 html += `<lit-select-v id="${key}" type="${this.sdkConfigList.configuration[key].type}" 279default-value="" rounded="" class="sdk-config-select config" mode="multiple" canInsert="" 280rounded placement = "bottom" configName ="${key}" placeholder="${placeholder}"></lit-select-v>`; 281 sdkConfigDiv.innerHTML = sdkConfigDiv.innerHTML + html; 282 } else { 283 let inputElement = document.createElement('input'); 284 inputElement.className = 'sdk-config-input config'; 285 //@ts-ignore 286 if (this.sdkConfigList.configuration[key].default) { 287 //@ts-ignore 288 inputElement.value = this.sdkConfigList.configuration[key].default; 289 } 290 inputElement.setAttribute('configName', key); 291 //@ts-ignore 292 inputElement.setAttribute('type', this.sdkConfigList.configuration[key].type); 293 sdkConfigDiv.appendChild(inputElement); 294 this.list!.push(inputElement); 295 } 296 } 297 298 initConfig(): void { 299 this.customConfig!.innerHTML = ''; 300 this.list = []; 301 this.list.push(this.selectConfig!); 302 let sdkConfigSwitch = document.createElement('lit-switch') as LitSwitch; 303 //@ts-ignore 304 for (let key in this.sdkConfigList.configuration) { 305 let sdkConfigDiv = document.createElement('div'); 306 sdkConfigDiv.className = 'sdk-config-div'; 307 let sdkConfigHeadDiv = document.createElement('div'); 308 sdkConfigDiv.appendChild(sdkConfigHeadDiv); 309 let sdkConfigTitle = document.createElement('span'); 310 sdkConfigTitle.className = 'sdk-config-title'; 311 sdkConfigTitle.textContent = key; 312 sdkConfigHeadDiv.appendChild(sdkConfigTitle); 313 let sdkConfigDes = document.createElement('span'); 314 //@ts-ignore 315 sdkConfigDes.textContent = this.sdkConfigList.configuration[key].description; 316 sdkConfigDes.className = 'sdk-config-des'; 317 sdkConfigHeadDiv.appendChild(sdkConfigDes); 318 //@ts-ignore 319 switch (this.sdkConfigList.configuration[key].type) { 320 case 'string': 321 this.sdkConfigByStringType(key, sdkConfigDiv); 322 break; 323 case 'number': 324 this.sdkConfigByNumberType(key, sdkConfigDiv); 325 break; 326 case 'integer': 327 this.sdkConfigByIntegerType(key, sdkConfigDiv, sdkConfigTitle); 328 break; 329 case 'boolean': 330 this.sdkConfigByBooleanType(key, sdkConfigSwitch, sdkConfigHeadDiv); 331 break; 332 } 333 this.customConfig!.appendChild(sdkConfigDiv); 334 //@ts-ignore 335 if (this.sdkConfigList.configuration[key].enum) { 336 let select = this.shadowRoot!.querySelector<LitSelectV>(`#${key}`); 337 select!.setAttribute('type', 'enum'); 338 //@ts-ignore 339 select!.setAttribute('value', this.sdkConfigList.configuration.key.default); 340 //@ts-ignore 341 select!.dataSource(this.sdkConfigList.configuration.key.enum, ''); 342 this.list.push(select!); 343 select!.addEventListener('click', () => { 344 select!.setAttribute('value', select!.value); 345 }); 346 } 347 } 348 sdkConfigSwitch.addEventListener('change', () => { 349 sdkConfigSwitch.setAttribute('value', `${sdkConfigSwitch.hasAttribute('checked')}`); 350 }); 351 } 352 353 checkIntegerInput(value: string): string { 354 let inputValue = value 355 .replace(/[^\-\d]|\-{2,}/g, '') 356 .replace(/(\d)\-|-(0+)|^0+(\d)/g, '$1') 357 .replace(/(-?\d{15})\d*/, '$1'); 358 return inputValue; 359 } 360 361 checkFloatInput(value: string): string { 362 let inputValue = value 363 .replace(/[^\d.]/g, '') 364 .replace(/^\.|^0+(\d)/g, '') 365 .replace(/(\.\d+)\.|(-)\.|(\d+|\.)-/g, '$1') 366 .replace(/(-?\d{9})\d*/, '$1'); 367 return inputValue.replace(/\.{2,}|-(0){2,}|(-)0+(\d+)/g, '.'); 368 } 369 370 isAbleShowConfig(isAbleShow: boolean): void { 371 if (this.list!) { 372 if (isAbleShow) { 373 this.list!.forEach((item) => { 374 item.setAttribute('disabled', ''); 375 }); 376 } else { 377 this.list!.forEach((item) => { 378 item.removeAttribute('disabled'); 379 }); 380 } 381 } 382 } 383 384 initHtml(): string { 385 return SpSdkConfigHtml; 386 } 387} 388