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.js'; 17import '../../../base-ui/select/LitSelectV.js'; 18import '../../../base-ui/select/LitSelect.js'; 19 20import '../../../base-ui/switch/lit-switch.js'; 21import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch.js'; 22import { LitSelectV } from '../../../base-ui/select/LitSelectV.js'; 23import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js'; 24 25@element('sp-sdk-config') 26export class SpSdkConfig extends BaseElement { 27 private worker: Worker | undefined; 28 private sdkConfigList: any; 29 private customConfig: HTMLDivElement | undefined | null; 30 private selectConfig: LitAllocationSelect | undefined | null; 31 private list: Array<HTMLElement> | undefined; 32 private pluginName: string = ''; 33 private sampleInterval: number = 5000; 34 35 static get observedAttributes() { 36 return ['configName', 'value', 'type']; 37 } 38 39 get show(): boolean { 40 return this.hasAttribute('show'); 41 } 42 43 set show(sdkConfigShow: boolean) { 44 if (sdkConfigShow) { 45 this.setAttribute('show', ''); 46 } else { 47 this.removeAttribute('show'); 48 } 49 } 50 51 set startSamp(sdkConfigStart: boolean) { 52 if (sdkConfigStart) { 53 this.setAttribute('startSamp', ''); 54 } else { 55 this.removeAttribute('startSamp'); 56 } 57 } 58 59 get startSamp(): boolean { 60 return this.hasAttribute('startSamp'); 61 } 62 63 set configName(configName: string) { 64 if (configName != '') { 65 this.setAttribute('configName', configName); 66 } else { 67 this.removeAttribute('configName'); 68 } 69 } 70 71 get configName(): string { 72 return this.getAttribute('configName') || ''; 73 } 74 75 get type(): string { 76 return this.getAttribute('type') || ''; 77 } 78 79 set type(type: string) { 80 if (type != '') { 81 this.setAttribute('type', type); 82 } else { 83 this.removeAttribute('type'); 84 } 85 } 86 87 private wasmMap: Map<string, any> = new Map<string, any>(); 88 private wasmList: Array<string> = []; 89 90 private changGpu(gpuName: string) { 91 let config = this.wasmMap.get(gpuName); 92 this.pluginName = config?.pluginName; 93 this.sampleInterval = config?.sampleInterval; 94 let pam = { 95 action: 'open', 96 componentId: config.componentId, 97 wasmJsName: config.wasmJsName, 98 WasmName: config.wasmName, 99 }; 100 this.worker!.postMessage(pam); 101 this.worker!.onmessage = (event: MessageEvent) => { 102 let results = event.data.results; 103 this.sdkConfigList = results.settingConfig; 104 this.initConfig(); 105 }; 106 } 107 108 getPlugName(): string { 109 return this.pluginName; 110 } 111 112 getSampleInterval(): number { 113 return this.sampleInterval; 114 } 115 116 getGpuConfig(): {} { 117 let configVal = this.shadowRoot?.querySelectorAll<HTMLElement>('.config'); 118 let gpuConfig = {}; 119 for (let i = 0; i < configVal!.length; i++) { 120 let configName = configVal![i].getAttribute('configName'); 121 let type = configVal![i].getAttribute('type'); 122 if (type == 'enum') { 123 let enumValue = configVal![i].getAttribute('value'); 124 if (enumValue != undefined && enumValue != 'undefined') { 125 // @ts-ignore 126 gpuConfig[configName!] = enumValue; 127 } 128 } else if (type == 'number' || type == 'integer' || type == 'num') { 129 // @ts-ignore 130 gpuConfig[configName!] = Number(configVal![i].value); 131 } else if (type == 'boolean') { 132 let attribute = configVal![i].getAttribute('value'); 133 // @ts-ignore 134 gpuConfig[configName!] = attribute == 'true'; 135 } else { 136 // @ts-ignore 137 gpuConfig[configName!] = configVal![i].value; 138 } 139 } 140 return gpuConfig; 141 } 142 143 initElements(): void { 144 try { 145 let spApplication = document.querySelector<HTMLElement>('sp-application'); 146 let wasmJsonUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; 147 if (spApplication!.hasAttribute('vs')) { 148 wasmJsonUrl = `http://${window.location.host.split(':')[0]}:${window.location.port}/wasm.json`; 149 } 150 fetch(wasmJsonUrl) 151 .then((res) => { 152 if (res.ok) { 153 res.text().then((text) => { 154 this.wasmMap = new Map(); 155 this.wasmList = []; 156 let wasmJson = JSON.parse(text); 157 let wasmFiles = wasmJson.WasmFiles; 158 wasmFiles.forEach((wasmFile: any) => { 159 this.wasmMap.set(wasmFile.disPlayName, wasmFile); 160 this.wasmList.push(wasmFile.disPlayName); 161 }); 162 }); 163 } 164 }) 165 .catch((err) => {}); 166 if (this.worker == null) { 167 // @ts-ignore 168 if (window.useWb) { 169 return; 170 } 171 this.worker = new Worker('trace/database/ConfigWorker.js'); 172 } 173 } catch (e) {} 174 this.customConfig = this.shadowRoot?.querySelector<HTMLDivElement>('.configList'); 175 let switchButton = this.shadowRoot?.querySelector('.config_switch') as LitSwitch; 176 switchButton.addEventListener('change', (event: CustomEventInit<LitSwitchChangeEvent>) => { 177 let detail = event.detail; 178 if (detail!.checked) { 179 this.startSamp = true; 180 this.isAbleShowConfig(false); 181 } else { 182 this.startSamp = false; 183 this.isAbleShowConfig(true); 184 } 185 }); 186 this.selectConfig = this.shadowRoot?.querySelector<LitAllocationSelect>('lit-allocation-select'); 187 let inputDiv = this.selectConfig?.shadowRoot?.querySelector('.multipleSelect') as HTMLDivElement; 188 let input = this.selectConfig?.shadowRoot?.querySelector<HTMLInputElement>('#singleInput'); 189 if (input) { 190 inputDiv.addEventListener('inputClick', () => { 191 this.selectConfig!.processData = this.wasmList; 192 this.selectConfig!.initData(); 193 }); 194 inputDiv.addEventListener('valuable', (ev) => { 195 this.changGpu(input!.value); 196 }); 197 } 198 this.list = []; 199 this.list.push(this.selectConfig!); 200 this.isAbleShowConfig(true); 201 } 202 203 initConfig() { 204 this.customConfig!.innerHTML = ''; 205 this.list = []; 206 this.list.push(this.selectConfig!); 207 let sdkConfigSwitch = document.createElement('lit-switch') as LitSwitch; 208 for (let key in this.sdkConfigList.configuration) { 209 let html = ''; 210 let sdkConfigDiv = document.createElement('div'); 211 sdkConfigDiv.className = 'sdk-config-div'; 212 let sdkConfigHeadDiv = document.createElement('div'); 213 sdkConfigDiv.appendChild(sdkConfigHeadDiv); 214 let sdkConfigTitle = document.createElement('span'); 215 sdkConfigTitle.className = 'sdk-config-title'; 216 sdkConfigTitle.textContent = key; 217 sdkConfigHeadDiv.appendChild(sdkConfigTitle); 218 let sdkConfigDes = document.createElement('span'); 219 sdkConfigDes.textContent = this.sdkConfigList.configuration[key].description; 220 sdkConfigDes.className = 'sdk-config-des'; 221 sdkConfigHeadDiv.appendChild(sdkConfigDes); 222 switch (this.sdkConfigList.configuration[key].type) { 223 case 'string': 224 if (this.sdkConfigList.configuration[key].enum) { 225 let placeholder = ''; 226 if (this.sdkConfigList.configuration[key].default) { 227 placeholder = this.sdkConfigList.configuration[key].default; 228 } 229 html += `<lit-select-v id="${key}" type="${this.sdkConfigList.configuration[key].type}" default-value="" rounded="" class="sdk-config-select config" mode="multiple" canInsert="" rounded placement = "bottom" configName ="${key}" placeholder="${placeholder}"></lit-select-v>`; 230 sdkConfigDiv.innerHTML = sdkConfigDiv.innerHTML + html; 231 } else { 232 let inputElement = document.createElement('input'); 233 inputElement.className = 'sdk-config-input config'; 234 if (this.sdkConfigList.configuration[key].default) { 235 inputElement.value = this.sdkConfigList.configuration[key].default; 236 } 237 inputElement.setAttribute('configName', key); 238 inputElement.setAttribute('type', this.sdkConfigList.configuration[key].type); 239 sdkConfigDiv.appendChild(inputElement); 240 this.list.push(inputElement); 241 } 242 break; 243 case 'number': 244 let numberInput = document.createElement('input'); 245 numberInput.className = 'sdk-config-input config'; 246 if (this.sdkConfigList.configuration[key].default) { 247 numberInput.value = this.sdkConfigList.configuration[key].default; 248 } 249 numberInput.setAttribute('configName', key); 250 numberInput.setAttribute('type', 'num'); 251 numberInput.oninput = (ev) => { 252 let inputValue = this.checkFloatInput(numberInput.value); 253 numberInput.value = inputValue; 254 }; 255 sdkConfigDiv.appendChild(numberInput); 256 this.list.push(numberInput); 257 break; 258 case 'integer': 259 let input = document.createElement('input'); 260 input.className = 'sdk-config-input config'; 261 if (this.sdkConfigList.configuration[key].default) { 262 input.value = this.sdkConfigList.configuration[key].default; 263 } 264 input.setAttribute('configName', key); 265 input.setAttribute('type', this.sdkConfigList.configuration[key].type); 266 input.oninput = (ev) => { 267 let inputValue = this.checkIntegerInput(input.value); 268 input.value = inputValue; 269 sdkConfigTitle.setAttribute('value', input.value); 270 }; 271 sdkConfigDiv.appendChild(input); 272 this.list.push(input); 273 break; 274 case 'boolean': 275 sdkConfigSwitch.className = 'switch1 config'; 276 sdkConfigSwitch.setAttribute('configName', key); 277 sdkConfigSwitch.setAttribute('type', this.sdkConfigList.configuration[key].type); 278 if (this.sdkConfigList.configuration[key].default == 'true') { 279 sdkConfigSwitch.setAttribute('checked', ''); 280 sdkConfigSwitch.setAttribute('value', 'true'); 281 } else { 282 sdkConfigSwitch.removeAttribute('checked'); 283 sdkConfigSwitch.setAttribute('value', 'false'); 284 } 285 sdkConfigHeadDiv.appendChild(sdkConfigSwitch); 286 this.list.push(sdkConfigSwitch); 287 break; 288 } 289 this.customConfig!.appendChild(sdkConfigDiv); 290 if (this.sdkConfigList.configuration[key].enum) { 291 let select = this.shadowRoot!.querySelector<LitSelectV>(`#${key}`); 292 select!.setAttribute('type', 'enum'); 293 select!.setAttribute('value', this.sdkConfigList.configuration[key].default); 294 select!.dataSource(this.sdkConfigList.configuration[key].enum, ''); 295 this.list.push(select!); 296 select!.addEventListener('click', () => { 297 select!.setAttribute('value', select!.value); 298 }); 299 } 300 } 301 sdkConfigSwitch.addEventListener('change', () => { 302 if (sdkConfigSwitch.hasAttribute('checked')) { 303 sdkConfigSwitch.setAttribute('value', 'true'); 304 } else { 305 sdkConfigSwitch.setAttribute('value', 'false'); 306 } 307 }); 308 } 309 310 checkIntegerInput(value: string): string { 311 let inputValue = value 312 .replace(/[^\-\d]|\-{2,}/g, '') 313 .replace(/(\d)\-|-(0+)|^0+(\d)/g, '$1') 314 .replace(/(-?\d{15})\d*/, '$1'); 315 return inputValue; 316 } 317 318 checkFloatInput(value: string): string { 319 let inputValue = value 320 .replace(/[^\d.]/g, '') 321 .replace(/^\.|^0+(\d)/g, '') 322 .replace(/(\.\d+)\.|(-)\.|(\d+|\.)-/g, '$1') 323 .replace(/(-?\d{9})\d*/, '$1'); 324 return inputValue.replace(/\.{2,}|-(0){2,}|(-)0+(\d+)/g, '.'); 325 } 326 327 isAbleShowConfig(isAbleShow: boolean) { 328 if (this.list!) { 329 if (isAbleShow) { 330 this.list!.forEach((item) => { 331 item.setAttribute('disabled', ''); 332 }); 333 } else { 334 this.list!.forEach((item) => { 335 item.removeAttribute('disabled'); 336 }); 337 } 338 } 339 } 340 341 initHtml(): string { 342 return ` 343 <style> 344 .sdk-config-div { 345 flex-direction: column; 346 width: 80%; 347 display: flex; 348 gap: 15px; 349 } 350 :host{ 351 display: inline-block; 352 width: 100%; 353 height: 100%; 354 background: var(--dark-background3,#FFFFFF); 355 border-radius: 0px 16px 16px 0px; 356 } 357 .root { 358 font-size:16px; 359 padding-left: 54px; 360 margin-right: 30px; 361 padding-top: 30px; 362 margin-bottom: 30px; 363 } 364 :host([show]) .sdk-config-div { 365 display: flex; 366 flex-direction: column; 367 margin-bottom: 1vh; 368 } 369 370 :host(:not([show])) .sdk-config-div { 371 margin-top: 5vh; 372 margin-bottom: 5vh; 373 gap: 25px; 374 } 375 376 :host(:not([show])) .hidden { 377 display: none; 378 } 379 380 .sdk-config-title { 381 opacity: 0.9; 382 line-height: 40px; 383 font-family: Helvetica-Bold; 384 font-size: 18px; 385 text-align: center; 386 font-weight: 700; 387 margin-right: 10px; 388 } 389 390 .sdk-config-des { 391 opacity: 0.6; 392 font-family: Helvetica; 393 font-size: 14px; 394 text-align: center; 395 line-height: 35px; 396 font-weight: 400; 397 } 398 399 .sdk-config-select { 400 border-radius: 15px; 401 } 402 403 input { 404 height: 25px; 405 outline:none; 406 border-radius: 16px; 407 text-indent:2% 408 } 409 input::-webkit-input-placeholder{ 410 color:var(--bark-prompt,#999999); 411 } 412 lit-switch { 413 display:inline; 414 float: right; 415 height: 38px; 416 margin-top: 10px; 417 } 418 .sdk-config-input { 419 border: 1px solid var(--dark-background5,#ccc); 420 font-family: Helvetica; 421 font-size: 14px; 422 color: var(--dark-color1,#212121); 423 text-align: left; 424 line-height: 20px; 425 font-weight: 400; 426 } 427 428 :host([startSamp]) .sdk-config-input { 429 background: var(--dark-background5,#FFFFFF); 430 } 431 432 :host(:not([startSamp])) .sdk-config-input { 433 color: var(--dark-color1,#212121); 434 } 435 436 </style> 437 <div class="root"> 438 <div class="sdk-config-div"> 439 <div> 440 <span class="sdk-config-title">Start Custom Config</span> 441 <lit-switch class="config_switch" ></lit-switch> 442 </div> 443 </div> 444 <div class="sdk-config-div" id="select_config"> 445 <lit-allocation-select show-search class="processSelect" rounded default-value="" id="pid" placement="bottom" style="width:100%"></lit-allocation-select> 446 </div> 447 <div class="configList"> 448 </div> 449 </div> 450 `; 451 } 452} 453