Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/prefetching #435

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions examples/src/Components/CacheAndStreamingLogs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useState } from "react";
import { CacheLog } from "../../../src";

interface StreamingReadoutProps {
playbackPlayingState: boolean;
isStreamingState: boolean;
cacheLog: CacheLog;
playbackFrame: number;
totalDuration: number;
}

const CacheAndStreamingLogs: React.FC<StreamingReadoutProps> = ({
playbackPlayingState,
isStreamingState,
cacheLog,
playbackFrame,
totalDuration,
}) => {
const [isOpen, setIsOpen] = useState(false);

const { size, enabled, maxSize, firstFrameNumber, lastFrameNumber } =
cacheLog;
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen
? "Hide Cache and Streaming Info"
: "Show Cache and Streaming Info"}
</button>

{isOpen && (
<>
<div>
Playback State:{" "}
{playbackPlayingState === true ? "playing" : "paused"}
</div>
<div>
Streaming State:{" "}
{isStreamingState == true
? "streaming"
: "not streaming"}
</div>
<div>Cache Size: {size}</div>
<div>Cache Enabled: {enabled ? "Yes" : "No"}</div>
<div>Max Size: {maxSize}</div>
<div>First Frame Number: {firstFrameNumber}</div>
<div>Last Frame Number: {lastFrameNumber}</div>
<div>Current playback frame: {playbackFrame}</div>
<div>Total Duration: {totalDuration}</div>
</>
)}
</div>
);
};

export default CacheAndStreamingLogs;
150 changes: 114 additions & 36 deletions examples/src/Viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import SimulariumViewer, {
ErrorLevel,
NetConnectionParams,
TrajectoryFileInfo,
CacheLog,
} from "../../src/index";
import { nullAgent, TrajectoryType } from "../../src/constants";

Expand Down Expand Up @@ -57,9 +58,7 @@ import {
UI_TEMPLATE_DOWNLOAD_URL_ROOT,
UI_TEMPLATE_URL_ROOT,
} from "./api-settings";

import "../../style/style.css";
import "./style.css";
import CacheAndStreamingLogs from "./Components/CacheAndStreamingLogs";

let playbackFile = "TEST_LIVEMODE_API";
let queryStringFile = "";
Expand Down Expand Up @@ -98,6 +97,9 @@ interface ViewerState {
initialPlay: boolean;
firstFrameTime: number;
followObjectData: AgentData;
cacheLog: CacheLog;
playbackPlaying: boolean;
streaming: boolean;
}

const simulariumController = new SimulariumController({});
Expand Down Expand Up @@ -131,6 +133,18 @@ const initialState: ViewerState = {
initialPlay: true,
firstFrameTime: 0,
followObjectData: nullAgent(),
cacheLog: {
size: 0,
numFrames: 0,
maxSize: 0,
enabled: false,
firstFrameNumber: 0,
firstFrameTime: 0,
lastFrameNumber: 0,
lastFrameTime: 0,
},
playbackPlaying: false,
streaming: false,
};

class Viewer extends React.Component<InputParams, ViewerState> {
Expand Down Expand Up @@ -392,7 +406,7 @@ class Viewer extends React.Component<InputParams, ViewerState> {
}
this.setState({ currentFrame, currentTime });
if (currentFrame < 0) {
simulariumController.pause();
this.handlePauseStreaming();
}
}

Expand Down Expand Up @@ -444,7 +458,8 @@ class Viewer extends React.Component<InputParams, ViewerState> {
public handleTrajectoryInfo(data: TrajectoryFileInfo): void {
console.log("Trajectory info arrived", data);
// NOTE: Currently incorrectly assumes initial time of 0
const totalDuration = (data.totalSteps - 1) * data.timeStepSize;
// const totalDuration = (data.totalSteps - 1) * data.timeStepSize;
const totalDuration = data.totalSteps;
this.setState({
totalDuration,
timeStep: data.timeStepSize,
Expand All @@ -454,8 +469,29 @@ class Viewer extends React.Component<InputParams, ViewerState> {
});
}

public handlePlay(): void {
simulariumController.resumePlayback();
if (!simulariumController.isStreaming()) {
simulariumController.resumeStreaming();
}
}

public handlePause(): void {
simulariumController.pausePlayback();
if (
simulariumController.visData.currentFrameNumber >
simulariumController.visData.frameCache.getFirstFrameNumber()
) {
simulariumController.resumeStreaming();
}
}

public handleScrubTime(event): void {
simulariumController.gotoTime(parseFloat(event.target.value));
simulariumController.movePlaybackTime(parseFloat(event.target.value));
}

public handleScrubFrame(event): void {
simulariumController.movePlaybackFrame(parseInt(event.target.value));
}

public handleUIDisplayData(uiDisplayData: UIDisplayData): void {
Expand Down Expand Up @@ -487,15 +523,16 @@ class Viewer extends React.Component<InputParams, ViewerState> {
}

public gotoNextFrame(): void {
simulariumController.gotoTime(
this.state.currentTime + this.state.timeStep
);
simulariumController.movePlaybackFrame(this.state.currentFrame + 1);
}

public gotoPreviousFrame(): void {
simulariumController.gotoTime(
this.state.currentTime - this.state.timeStep
);
simulariumController.movePlaybackFrame(this.state.currentFrame - 1);
}

public handlePauseStreaming(): void {
simulariumController.pauseStreaming();
this.setState({ streaming: simulariumController.isStreaming() });
}

private translateAgent() {
Expand All @@ -516,8 +553,8 @@ class Viewer extends React.Component<InputParams, ViewerState> {
}

private configureAndLoad() {
simulariumController.configureNetwork(this.netConnectionSettings);
if (playbackFile.startsWith("http")) {
simulariumController.configureNetwork(this.netConnectionSettings);
return this.loadFromUrl(playbackFile);
}
if (playbackFile === "TEST_LIVEMODE_API") {
Expand Down Expand Up @@ -678,6 +715,18 @@ class Viewer extends React.Component<InputParams, ViewerState> {
this.setState({ followObjectData: agentData });
};

public handleCacheUpdate = (log: CacheLog) => {
this.setState({
cacheLog: log,
playbackPlaying: simulariumController.isPlaying(),
streaming: simulariumController.isStreaming(),
});
};

public handleStreamingChange = (streaming: boolean) => {
this.setState({ streaming });
};

public render(): JSX.Element {
if (this.state.filePending) {
const fileType = this.state.filePending.type;
Expand All @@ -694,7 +743,7 @@ class Viewer extends React.Component<InputParams, ViewerState> {
<div className="container" style={{ height: "90%", width: "75%" }}>
<select
onChange={(event) => {
simulariumController.pause();
this.handlePauseStreaming();
playbackFile = event.target.value;
this.configureAndLoad();
}}
Expand Down Expand Up @@ -761,14 +810,16 @@ class Viewer extends React.Component<InputParams, ViewerState> {
Load a smoldyn trajectory
</button>
<br />
<button onClick={() => simulariumController.resume()}>
Play
<button onClick={this.handlePlay.bind(this)}>
Play / resume streaming
</button>
<button onClick={() => simulariumController.pause()}>
Pause
<button onClick={this.handlePause.bind(this)}>
Pause playback
</button>
<button onClick={() => simulariumController.stop()}>
stop
<button
onClick={() => simulariumController.abortRemoteSimulation()}
>
stop / abort sim
</button>
<button onClick={this.gotoPreviousFrame.bind(this)}>
Previous Frame
Expand All @@ -779,14 +830,16 @@ class Viewer extends React.Component<InputParams, ViewerState> {
<input
name="slider"
type="range"
min={this.state.firstFrameTime}
step={this.state.timeStep}
value={this.state.currentTime}
min={0}
step={1}
value={this.state.currentFrame}
max={this.state.totalDuration}
onChange={this.handleScrubTime}
onChange={this.handleScrubFrame}
/>
<label htmlFor="slider">
{this.state.currentTime} / {this.state.totalDuration}
{this.state.currentFrame * this.state.timeStep +
this.state.firstFrameTime}
/ {this.state.totalDuration * this.state.timeStep}
</label>
<br />
{this.state.particleTypeNames.map((id, i) => {
Expand Down Expand Up @@ -947,17 +1000,38 @@ class Viewer extends React.Component<InputParams, ViewerState> {
updateAgentColorArray={this.updateAgentColorArray}
setColorSelectionInfo={this.setColorSelectionInfo}
/>
<RecordMovieComponent
startRecordingHandler={simulariumController.startRecording}
stopRecordingHandler={simulariumController.stopRecording}
setRecordingEnabled={() => {
this.setRecordingEnabled(
!this.state.isRecordingEnabled
);
}}
isRecordingEnabled={this.state.isRecordingEnabled}
/>
<button
onClick={() =>
this.setRecordingEnabled(!this.state.isRecordingEnabled)
}
>
{this.state.isRecordingEnabled ? "Disable" : "Enable"}{" "}
Recording
</button>
{this.state.isRecordingEnabled && (
<RecordMovieComponent
startRecordingHandler={
simulariumController.startRecording
}
stopRecordingHandler={
simulariumController.stopRecording
}
/>
)}
<AgentMetadata agentData={this.state.followObjectData} />
<CacheAndStreamingLogs
playbackPlayingState={this.state.playbackPlaying}
isStreamingState={
this.state.streaming
}
cacheLog={this.state.cacheLog}
playbackFrame={
simulariumController.visData.currentFrameNumber
}
totalDuration={Math.ceil(
this.state.totalDuration / this.state.timeStep
)}
/>
<div className="viewer-container">
<SimulariumViewer
ref={this.viewerRef}
Expand Down Expand Up @@ -991,7 +1065,11 @@ class Viewer extends React.Component<InputParams, ViewerState> {
backgroundColor={[0, 0, 0]}
lockedCamera={false}
disableCache={false}
maxCacheSize={Infinity} // means no limit, provide limits in bytes, 1MB = 1000000, 1GB = 1000000000
maxCacheSize={2e6} // means no limit, provide limits in bytes, 1MB = 1000000, 1GB = 1000000000
onCacheUpdate={this.handleCacheUpdate.bind(this)}
onStreamingChange={(streaming) => {
this.handleStreamingChange(streaming);
}}
/>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ export const nullAgent = (): AgentData => {
export const AGENT_HEADER_SIZE = 3; // frameNumber, time, agentCount

export const BYTE_SIZE_64_BIT_NUM = 8;
export const DEFAULT_PRE_FETCH_RATIO = 0;
Loading
Loading