import { Fragment } from "react"; import { Component } from "react"; import { ToggleField, SliderField, Field, SingleDropdownOption, Dropdown, PanelSectionRow, staticClasses, } from "decky-frontend-lib"; import * as backend from "../backend"; import { tr } from "usdpl-front"; import { LIMITS_INFO, SMT_CPU, CLOCK_MAX_CPU, CLOCK_MIN_CPU, CLOCK_MIN_MAX_CPU, ONLINE_CPUS, ONLINE_STATUS_CPUS, GOVERNOR_CPU, } from "../consts"; import { set_value, get_value } from "usdpl-front"; interface CpuState { reloadThingy: string; advancedCpu: number; advancedMode: boolean; } export class Cpus extends Component<{}, CpuState> { constructor(props: {}) { super(props); this.state = { reloadThingy: "/shrug", advancedCpu: 1, advancedMode: false, }; } render() { const reloadGUI = (x: string) => this.setState((state) => { return { reloadThingy: x, advancedCpu: state.advancedCpu, advancedMode: state.advancedMode, }; }); const total_cpus = (get_value(LIMITS_INFO) as backend.SettingsLimits | null)?.cpu.count ?? 8; const advancedCpuIndex = this.state.advancedCpu - 1; const advancedCpu = this.state.advancedCpu; const advancedMode = this.state.advancedMode; const smtAllowed = (get_value(LIMITS_INFO) as backend.SettingsLimits | null)?.cpu.smt_capable ?? true; const governorOptions: SingleDropdownOption[] = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].governors.map((elem) => {return { data: elem, label: {elem}, };}); return ( {/* CPU */}
{tr("CPU")}
{ //advancedMode = advanced; this.setState((state) => { return { reloadThingy: state.reloadThingy, advancedCpu: state.advancedCpu, advancedMode: advanced, }; }); }} /> {/* CPU plebeian mode */} {!advancedMode && smtAllowed && { backend.log(backend.LogLevel.Debug, "SMT is now " + smt.toString()); //const cpus = get_value(ONLINE_CPUS); const smtNow = smt && smtAllowed; backend.resolve(backend.setCpuSmt(smtNow), (statii: boolean[]) => { set_value(SMT_CPU, smtNow); set_value(ONLINE_STATUS_CPUS, statii); const count = countCpus(statii); set_value(ONLINE_CPUS, count); reloadGUI("SMT"); }); }} /> } {!advancedMode && { backend.log(backend.LogLevel.Debug, "CPU slider is now " + cpus.toString()); const onlines = get_value(ONLINE_CPUS); if (cpus != onlines) { set_value(ONLINE_CPUS, cpus); const smtNow = get_value(SMT_CPU); let onlines: boolean[] = []; for (let i = 0; i < total_cpus; i++) { const online = smtNow? i < cpus : (i % 2 == 0) && (i < cpus * 2); onlines.push(online); } backend.resolve(backend.setCpuOnlines(onlines), (statii: boolean[]) => { set_value(ONLINE_STATUS_CPUS, statii); const count = countCpus(statii); set_value(ONLINE_CPUS, count); reloadGUI("CPUs"); }); reloadGUI("CPUsImmediate"); } }} /> } {!advancedMode && { if (value) { if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits != null) { set_value(CLOCK_MIN_CPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits!.min); } if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits != null) { set_value(CLOCK_MAX_CPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits!.max); } syncPlebClockToAdvanced(); reloadGUI("CPUFreqToggle"); } else { set_value(CLOCK_MIN_CPU, null); set_value(CLOCK_MAX_CPU, null); for (let i = 0; i < total_cpus; i++) { backend.resolve(backend.unsetCpuClockLimits(i), (_idc: any[]) => {}); } backend.resolve(backend.waitForComplete(), (_: boolean) => { reloadGUI("CPUUnsetFreq"); }); syncPlebClockToAdvanced(); } }} /> } {!advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_min_limits != null && {get_value(CLOCK_MIN_CPU) != null && { backend.log(backend.LogLevel.Debug, "Min freq slider is now " + freq.toString()); const freqNow = get_value(CLOCK_MIN_CPU); if (freq != freqNow) { set_value(CLOCK_MIN_CPU, freq); for (let i = 0; i < total_cpus; i++) { backend.resolve(backend.setCpuClockLimits(i, freq, get_value(CLOCK_MAX_CPU)), (limits: number[]) => { set_value(CLOCK_MIN_CPU, limits[0]); set_value(CLOCK_MAX_CPU, limits[1]); syncPlebClockToAdvanced(); }); } backend.resolve(backend.waitForComplete(), (_: boolean) => { reloadGUI("CPUMinFreq"); }); reloadGUI("CPUMinFreqImmediate"); } }} />} } {!advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[0].clock_max_limits != null && {get_value(CLOCK_MAX_CPU) != null && { backend.log(backend.LogLevel.Debug, "Max freq slider is now " + freq.toString()); const freqNow = get_value(CLOCK_MAX_CPU); if (freq != freqNow) { set_value(CLOCK_MAX_CPU, freq); for (let i = 0; i < total_cpus; i++) { backend.resolve(backend.setCpuClockLimits(i, get_value(CLOCK_MIN_CPU), freq), (limits: number[]) => { set_value(CLOCK_MIN_CPU, limits[0]); set_value(CLOCK_MAX_CPU, limits[1]); syncPlebClockToAdvanced(); }); } backend.resolve(backend.waitForComplete(), (_: boolean) => { reloadGUI("CPUMaxFreq"); }); reloadGUI("CPUMaxFreqImmediate"); } }} />} } {/* CPU advanced mode */} {advancedMode && { this.setState((state) => { return { reloadThingy: state.reloadThingy, advancedCpu: cpuNum, advancedMode: state.advancedMode, }; }); }} /> } {advancedMode && { backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString()); if (!get_value(SMT_CPU)) { backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => { set_value(SMT_CPU, true); }); } backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => { const onlines = get_value(ONLINE_STATUS_CPUS); onlines[advancedCpuIndex] = newVal; set_value(ONLINE_STATUS_CPUS, onlines); }); }} /> } {advancedMode && { if (value) { const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits != null) { clocks[advancedCpuIndex].min = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.min; } if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits != null) { clocks[advancedCpuIndex].max = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.max; } set_value(CLOCK_MIN_MAX_CPU, clocks); reloadGUI("CPUFreqToggle"); } else { const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; clocks[advancedCpuIndex].min = null; clocks[advancedCpuIndex].max = null; set_value(CLOCK_MIN_MAX_CPU, clocks); backend.resolve(backend.unsetCpuClockLimits(advancedCpuIndex), (_idc: any[]) => { reloadGUI("CPUUnsetFreq"); }); } }} /> } {advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits != null && {get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].min != null && { backend.log(backend.LogLevel.Debug, "Min freq slider for " + advancedCpu.toString() + " is now " + freq.toString()); const freqNow = get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex] as MinMax; if (freq != freqNow.min) { backend.resolve(backend.setCpuClockLimits(advancedCpuIndex, freq, freqNow.max!), (limits: number[]) => { const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; clocks[advancedCpuIndex].min = limits[0]; clocks[advancedCpuIndex].max = limits[1]; set_value(CLOCK_MIN_MAX_CPU, clocks); reloadGUI("CPUMinFreq"); }); } }} />} } {advancedMode && (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits != null && {get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex].max != null && { backend.log(backend.LogLevel.Debug, "Max freq slider for " + advancedCpu.toString() + " is now " + freq.toString()); const freqNow = get_value(CLOCK_MIN_MAX_CPU)[advancedCpuIndex] as MinMax; if (freq != freqNow.max) { backend.resolve(backend.setCpuClockLimits(advancedCpuIndex, freqNow.min!, freq), (limits: number[]) => { const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; clocks[advancedCpuIndex].min = limits[0]; clocks[advancedCpuIndex].max = limits[1]; set_value(CLOCK_MIN_MAX_CPU, clocks); reloadGUI("CPUMaxFreq"); }); } }} />} } {advancedMode && governorOptions.length != 0 && { backend.log(backend.LogLevel.Debug, "POWERTOOLS: array item " + val.toString()); backend.log(backend.LogLevel.Debug, "POWERTOOLS: looking for data " + get_value(GOVERNOR_CPU)[advancedCpuIndex].toString()); return val.data == get_value(GOVERNOR_CPU)[advancedCpuIndex]; })} strDefaultLabel={get_value(GOVERNOR_CPU)[advancedCpuIndex]} onChange={(elem: SingleDropdownOption) => { backend.log(backend.LogLevel.Debug, "Governor dropdown selected " + elem.data.toString()); backend.resolve(backend.setCpuGovernor(advancedCpuIndex, elem.data as string), (gov: string) => { const governors = get_value(GOVERNOR_CPU); governors[advancedCpuIndex] = gov; set_value(GOVERNOR_CPU, governors); reloadGUI("CPUGovernor"); }); }} /> }
); } } function countCpus(statii: boolean[]): number { let count = 0; for (let i = 0; i < statii.length; i++) { if (statii[i]) { count += 1; } } return count; } type MinMax = { min: number | null; max: number | null; } function syncPlebClockToAdvanced() { const cpuCount = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.count; const minClock = get_value(CLOCK_MIN_CPU); const maxClock = get_value(CLOCK_MAX_CPU); let clockArr = []; for (let i = 0; i < cpuCount; i++) { clockArr.push({ min: minClock, max: maxClock, } as MinMax); } set_value(CLOCK_MIN_MAX_CPU, clockArr); }