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