mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Display emulation execution time
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
import { EmulationStatus } from "@/emulator";
|
||||
import { TextTooltip } from "./text-tooltip";
|
||||
import { BarChartSteps, CpuFill, FloppyFill } from "react-bootstrap-icons";
|
||||
import {
|
||||
BarChartSteps,
|
||||
CpuFill,
|
||||
FloppyFill,
|
||||
StopwatchFill,
|
||||
} from "react-bootstrap-icons";
|
||||
import React from "react";
|
||||
|
||||
export interface EmulationSummaryProps {
|
||||
status?: EmulationStatus;
|
||||
executionTimeFetcher: () => number;
|
||||
}
|
||||
|
||||
function formatMemory(value: BigInt): string {
|
||||
@@ -20,27 +27,75 @@ function formatMemory(value: BigInt): string {
|
||||
return num.toFixed(2) + " " + abbr[index];
|
||||
}
|
||||
|
||||
export function EmulationSummary(props: EmulationSummaryProps) {
|
||||
if (!props.status) {
|
||||
return <></>;
|
||||
function formatTime(seconds: number): string {
|
||||
const hrs = Math.floor(seconds / 3600);
|
||||
const mins = Math.floor((seconds % 3600) / 60);
|
||||
const secs = Math.floor(seconds % 60);
|
||||
|
||||
const secsString = secs < 10 ? "0" + secs : secs.toString();
|
||||
|
||||
if (hrs > 0) {
|
||||
const minsString = mins < 10 ? "0" + mins : mins.toString();
|
||||
return `${hrs.toString()}:${minsString}:${secsString}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="emulation-summary terminal-glass items-center absolute z-49 right-0 m-6 rounded-xl min-w-[150px] p-3 text-white cursor-default font-medium text-right text-sm whitespace-nowrap leading-6 font-mono">
|
||||
<TextTooltip tooltip={"Active threads"}>
|
||||
{props.status.activeThreads}
|
||||
<BarChartSteps className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
<br />
|
||||
<TextTooltip tooltip={"Application memory"}>
|
||||
{formatMemory(props.status.committedMemory)}
|
||||
<FloppyFill className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
<br />
|
||||
<TextTooltip tooltip={"Executed instructions"}>
|
||||
{props.status.executedInstructions.toLocaleString()}
|
||||
<CpuFill className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
</div>
|
||||
);
|
||||
return `${mins.toString()}:${secsString}`;
|
||||
}
|
||||
|
||||
export class EmulationSummary extends React.Component<
|
||||
EmulationSummaryProps,
|
||||
{}
|
||||
> {
|
||||
private timer: NodeJS.Timeout | undefined = undefined;
|
||||
|
||||
constructor(props: EmulationSummaryProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
||||
this.timer = setInterval(() => {
|
||||
this.forceUpdate();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.status) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="emulation-summary terminal-glass items-center absolute z-49 right-0 m-6 rounded-xl min-w-[150px] p-3 text-white cursor-default font-medium text-right text-sm whitespace-nowrap leading-6 font-mono">
|
||||
<TextTooltip tooltip={"Active Threads"}>
|
||||
{this.props.status.activeThreads}
|
||||
<BarChartSteps className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
<br />
|
||||
<TextTooltip tooltip={"Application Memory"}>
|
||||
{formatMemory(this.props.status.committedMemory)}
|
||||
<FloppyFill className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
<br />
|
||||
<TextTooltip tooltip={"Executed Instructions"}>
|
||||
{this.props.status.executedInstructions.toLocaleString()}
|
||||
<CpuFill className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
<br />
|
||||
<TextTooltip tooltip={"Execution Time"}>
|
||||
{formatTime(this.props.executionTimeFetcher() / 1000)}
|
||||
<StopwatchFill className="inline ml-3" />
|
||||
</TextTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,9 @@ export class Emulator {
|
||||
worker: Worker;
|
||||
state: EmulationState = EmulationState.Stopped;
|
||||
exit_status: number | null = null;
|
||||
start_time: Date = new Date();
|
||||
pause_time: Date | null = null;
|
||||
paused_time: number = 0;
|
||||
|
||||
constructor(
|
||||
logHandler: LogHandler,
|
||||
@@ -109,6 +112,9 @@ export class Emulator {
|
||||
}
|
||||
|
||||
async start(settings: Settings, file: string) {
|
||||
this.start_time = new Date();
|
||||
this.pause_time = null;
|
||||
this.paused_time = 0;
|
||||
this._setState(EmulationState.Running);
|
||||
this.stautsUpdateHandler(createDefaultEmulationStatus());
|
||||
|
||||
@@ -184,6 +190,12 @@ export class Emulator {
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
getExecutionTime() {
|
||||
const endTime = this.pause_time ? this.pause_time : new Date();
|
||||
const totalTime = endTime.getTime() - this.start_time.getTime();
|
||||
return totalTime - this.paused_time;
|
||||
}
|
||||
|
||||
logError(message: string) {
|
||||
this.logHandler([`<span class="terminal-red">${message}</span>`]);
|
||||
}
|
||||
@@ -233,6 +245,14 @@ export class Emulator {
|
||||
|
||||
_setState(state: EmulationState) {
|
||||
this.state = state;
|
||||
|
||||
if (isFinalState(this.state) || this.state === EmulationState.Paused) {
|
||||
this.pause_time = new Date();
|
||||
} else if (this.state == EmulationState.Running && this.pause_time) {
|
||||
this.paused_time += new Date().getTime() - this.pause_time.getTime();
|
||||
this.pause_time = null;
|
||||
}
|
||||
|
||||
this.stateChangeHandler(this.state);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ export class Playground extends React.Component<
|
||||
this.start = this.start.bind(this);
|
||||
this.resetFilesys = this.resetFilesys.bind(this);
|
||||
this.startEmulator = this.startEmulator.bind(this);
|
||||
this.fetchExecutionTime = this.fetchExecutionTime.bind(this);
|
||||
this.toggleEmulatorState = this.toggleEmulatorState.bind(this);
|
||||
|
||||
this.state = {
|
||||
@@ -162,6 +163,10 @@ export class Playground extends React.Component<
|
||||
});
|
||||
}
|
||||
|
||||
fetchExecutionTime() {
|
||||
return this.state.emulator ? this.state.emulator.getExecutionTime() : 0;
|
||||
}
|
||||
|
||||
async resetFilesys() {
|
||||
if (!this.state.filesystem) {
|
||||
return;
|
||||
@@ -440,7 +445,10 @@ export class Playground extends React.Component<
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex flex-1">
|
||||
<EmulationSummary status={this.state.emulationStatus} />
|
||||
<EmulationSummary
|
||||
status={this.state.emulationStatus}
|
||||
executionTimeFetcher={this.fetchExecutionTime}
|
||||
/>
|
||||
<div className="flex flex-1 flex-col pl-1 overflow-auto">
|
||||
<Output ref={this.output} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user