add lots of changes to make autorefresh work with infinite loop checking
This commit is contained in:
parent
f78fc37d68
commit
4d834ed16d
6 changed files with 75 additions and 79 deletions
|
@ -1,23 +1,8 @@
|
||||||
import * as ActionTypes from '../../../constants';
|
import * as ActionTypes from '../../../constants';
|
||||||
|
|
||||||
export function startSketchRefresh() {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.START_SKETCH_REFRESH
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function endSketchRefresh() {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.END_SKETCH_REFRESH
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function startSketch() {
|
export function startSketch() {
|
||||||
return (dispatch) => {
|
return {
|
||||||
dispatch({
|
type: ActionTypes.START_SKETCH
|
||||||
type: ActionTypes.START_SKETCH
|
|
||||||
});
|
|
||||||
dispatch(startSketchRefresh());
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +12,25 @@ export function stopSketch() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function startRefreshSketch() {
|
||||||
|
return {
|
||||||
|
type: ActionTypes.START_SKETCH_REFRESH
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startSketchAndRefresh() {
|
||||||
|
return (dispatch) => {
|
||||||
|
dispatch(startSketch());
|
||||||
|
dispatch(startRefreshSketch());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function endSketchRefresh() {
|
||||||
|
return {
|
||||||
|
type: ActionTypes.END_SKETCH_REFRESH
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function startTextOutput() {
|
export function startTextOutput() {
|
||||||
return {
|
return {
|
||||||
type: ActionTypes.START_TEXT_OUTPUT
|
type: ActionTypes.START_TEXT_OUTPUT
|
||||||
|
|
|
@ -69,8 +69,8 @@ class Editor extends React.Component {
|
||||||
this.props.setUnsavedChanges(true);
|
this.props.setUnsavedChanges(true);
|
||||||
this.props.updateFileContent(this.props.file.name, this._cm.getValue());
|
this.props.updateFileContent(this.props.file.name, this._cm.getValue());
|
||||||
this.checkForInfiniteLoop((infiniteLoop, prevs) => {
|
this.checkForInfiniteLoop((infiniteLoop, prevs) => {
|
||||||
if (!infiniteLoop && prevs) {
|
if (!infiniteLoop && prevs && this.props.autorefresh) {
|
||||||
this.props.startSketch();
|
this.props.startRefreshSketch();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
@ -145,7 +145,6 @@ class Editor extends React.Component {
|
||||||
const prevIsplaying = this.props.isPlaying;
|
const prevIsplaying = this.props.isPlaying;
|
||||||
let infiniteLoop = false;
|
let infiniteLoop = false;
|
||||||
let prevLine;
|
let prevLine;
|
||||||
this.props.stopSketch();
|
|
||||||
this.props.resetInfiniteLoops();
|
this.props.resetInfiniteLoops();
|
||||||
let iframe;
|
let iframe;
|
||||||
|
|
||||||
|
@ -156,9 +155,12 @@ class Editor extends React.Component {
|
||||||
|
|
||||||
loopProtect.alias = 'protect';
|
loopProtect.alias = 'protect';
|
||||||
|
|
||||||
|
let foundInfiniteLoop = false;
|
||||||
loopProtect.hit = (line) => {
|
loopProtect.hit = (line) => {
|
||||||
|
foundInfiniteLoop = true;
|
||||||
if (line !== prevLine) {
|
if (line !== prevLine) {
|
||||||
this.props.detectInfiniteLoops();
|
this.props.detectInfiniteLoops();
|
||||||
|
this.props.stopSketch();
|
||||||
infiniteLoop = true;
|
infiniteLoop = true;
|
||||||
callback(infiniteLoop, prevIsplaying);
|
callback(infiniteLoop, prevIsplaying);
|
||||||
const msg = document.createElement('div');
|
const msg = document.createElement('div');
|
||||||
|
@ -172,36 +174,42 @@ class Editor extends React.Component {
|
||||||
|
|
||||||
const processed = loopProtect(this.props.file.content);
|
const processed = loopProtect(this.props.file.content);
|
||||||
|
|
||||||
const iframeForLoop = document.getElementById('iframeForLoop');
|
let iframeForLoop = document.getElementById('iframeForLoop');
|
||||||
if (iframeForLoop === null) {
|
if (iframeForLoop === null) {
|
||||||
iframe = document.createElement('iframe');
|
iframe = document.createElement('iframe');
|
||||||
iframe.id = 'iframeForLoop';
|
iframe.id = 'iframeForLoop';
|
||||||
iframe.style.display = 'none';
|
iframe.style.display = 'none';
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
|
iframeForLoop = iframe;
|
||||||
} else {
|
} else {
|
||||||
iframeForLoop.srcdoc = '';
|
iframeForLoop.srcdoc = '';
|
||||||
const win = iframeForLoop.contentWindow;
|
|
||||||
const doc = win.document;
|
|
||||||
doc.open();
|
|
||||||
|
|
||||||
win.protect = loopProtect;
|
|
||||||
|
|
||||||
doc.write(`<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/addons/p5.dom.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script>
|
|
||||||
${processed}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>`);
|
|
||||||
win.onerror = () => true;
|
|
||||||
doc.close();
|
|
||||||
}
|
}
|
||||||
callback(infiniteLoop, prevIsplaying, prevLine);
|
const win = iframeForLoop.contentWindow;
|
||||||
|
const doc = win.document;
|
||||||
|
doc.open();
|
||||||
|
|
||||||
|
win.protect = loopProtect;
|
||||||
|
|
||||||
|
doc.write(`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/addons/p5.dom.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
${processed}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>`);
|
||||||
|
win.onerror = () => true;
|
||||||
|
doc.close();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!foundInfiniteLoop) {
|
||||||
|
callback(infiniteLoop, prevIsplaying, prevLine);
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cm: CodeMirror.Editor
|
_cm: CodeMirror.Editor
|
||||||
|
@ -272,10 +280,11 @@ Editor.propTypes = {
|
||||||
infiniteLoop: PropTypes.bool.isRequired,
|
infiniteLoop: PropTypes.bool.isRequired,
|
||||||
detectInfiniteLoops: PropTypes.func.isRequired,
|
detectInfiniteLoops: PropTypes.func.isRequired,
|
||||||
resetInfiniteLoops: PropTypes.func.isRequired,
|
resetInfiniteLoops: PropTypes.func.isRequired,
|
||||||
stopSketch: PropTypes.func.isRequired,
|
startRefreshSketch: PropTypes.func.isRequired,
|
||||||
startSketch: PropTypes.func.isRequired,
|
autorefresh: PropTypes.bool.isRequired,
|
||||||
isPlaying: PropTypes.bool.isRequired,
|
isPlaying: PropTypes.bool.isRequired,
|
||||||
theme: PropTypes.string.isRequired
|
theme: PropTypes.string.isRequired,
|
||||||
|
stopSketch: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Editor;
|
export default Editor;
|
||||||
|
|
|
@ -117,9 +117,7 @@ class PreviewFrame extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
// if previously the sketch was not playing, render sketch
|
// if sketch starts or stops playing, want to rerender
|
||||||
// if playing, and autorun is on
|
|
||||||
// if content has changed or files have changed
|
|
||||||
if (this.props.isPlaying !== prevProps.isPlaying) {
|
if (this.props.isPlaying !== prevProps.isPlaying) {
|
||||||
this.renderSketch();
|
this.renderSketch();
|
||||||
return;
|
return;
|
||||||
|
@ -131,14 +129,8 @@ class PreviewFrame extends React.Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.isPlaying && this.props.autorefresh) {
|
// small bug - if autorefresh is on, and the usr changes files
|
||||||
// if the content of the file changes
|
// in the sketch, preview will reload
|
||||||
// or the set of files changes
|
|
||||||
if (this.props.content !== prevProps.content
|
|
||||||
|| this.props.files[0].id !== prevProps.files[0].id) {
|
|
||||||
this.renderSketch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -215,11 +207,6 @@ class PreviewFrame extends React.Component {
|
||||||
|
|
||||||
renderSketch() {
|
renderSketch() {
|
||||||
const doc = ReactDOM.findDOMNode(this);
|
const doc = ReactDOM.findDOMNode(this);
|
||||||
if (this.props.infiniteLoop) {
|
|
||||||
this.props.resetInfiniteLoops();
|
|
||||||
doc.srcdoc = '';
|
|
||||||
srcDoc.set(doc, ' ');
|
|
||||||
}
|
|
||||||
if (this.props.isPlaying && !this.props.infiniteLoop) {
|
if (this.props.isPlaying && !this.props.infiniteLoop) {
|
||||||
srcDoc.set(doc, this.injectLocalFiles());
|
srcDoc.set(doc, this.injectLocalFiles());
|
||||||
this.props.endSketchRefresh();
|
this.props.endSketchRefresh();
|
||||||
|
|
|
@ -53,13 +53,16 @@ class Toolbar extends React.Component {
|
||||||
<img className="toolbar__logo" src={logoUrl} alt="p5js Logo" />
|
<img className="toolbar__logo" src={logoUrl} alt="p5js Logo" />
|
||||||
<button
|
<button
|
||||||
className="toolbar__play-sketch-button"
|
className="toolbar__play-sketch-button"
|
||||||
onClick={() => { this.props.startTextOutput(); this.props.startSketch(); }}
|
onClick={() => {
|
||||||
|
this.props.startTextOutput();
|
||||||
|
this.props.startSketchAndRefresh();
|
||||||
|
}}
|
||||||
aria-label="play sketch"
|
aria-label="play sketch"
|
||||||
disabled={this.props.infiniteLoop}
|
disabled={this.props.infiniteLoop}
|
||||||
>
|
>
|
||||||
<InlineSVG src={playUrl} alt="Play Sketch" />
|
<InlineSVG src={playUrl} alt="Play Sketch" />
|
||||||
</button>
|
</button>
|
||||||
<button className={playButtonClass} onClick={this.props.startSketch} aria-label="play only visual sketch" disabled={this.props.infiniteLoop} >
|
<button className={playButtonClass} onClick={this.props.startSketchAndRefresh} aria-label="play only visual sketch" disabled={this.props.infiniteLoop} >
|
||||||
<InlineSVG src={playUrl} alt="Play only visual Sketch" />
|
<InlineSVG src={playUrl} alt="Play only visual Sketch" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
@ -145,7 +148,8 @@ Toolbar.propTypes = {
|
||||||
hideEditProjectName: PropTypes.func.isRequired,
|
hideEditProjectName: PropTypes.func.isRequired,
|
||||||
infiniteLoop: PropTypes.bool.isRequired,
|
infiniteLoop: PropTypes.bool.isRequired,
|
||||||
autorefresh: PropTypes.bool.isRequired,
|
autorefresh: PropTypes.bool.isRequired,
|
||||||
setAutorefresh: PropTypes.func.isRequired
|
setAutorefresh: PropTypes.func.isRequired,
|
||||||
|
startSketchAndRefresh: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Toolbar;
|
export default Toolbar;
|
||||||
|
|
|
@ -146,7 +146,7 @@ class IDEView extends React.Component {
|
||||||
} else if (e.key === 'Enter' && ((e.metaKey && this.isMac) || (e.ctrlKey && !this.isMac))) {
|
} else if (e.key === 'Enter' && ((e.metaKey && this.isMac) || (e.ctrlKey && !this.isMac))) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.props.startSketch();
|
this.props.startSketchAndRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +195,7 @@ class IDEView extends React.Component {
|
||||||
infiniteLoop={this.props.ide.infiniteLoop}
|
infiniteLoop={this.props.ide.infiniteLoop}
|
||||||
autorefresh={this.props.preferences.autorefresh}
|
autorefresh={this.props.preferences.autorefresh}
|
||||||
setAutorefresh={this.props.setAutorefresh}
|
setAutorefresh={this.props.setAutorefresh}
|
||||||
|
startSketchAndRefresh={this.props.startSketchAndRefresh}
|
||||||
/>
|
/>
|
||||||
<Preferences
|
<Preferences
|
||||||
isVisible={this.props.ide.preferencesIsVisible}
|
isVisible={this.props.ide.preferencesIsVisible}
|
||||||
|
@ -279,10 +280,11 @@ class IDEView extends React.Component {
|
||||||
infiniteLoop={this.props.ide.infiniteLoop}
|
infiniteLoop={this.props.ide.infiniteLoop}
|
||||||
detectInfiniteLoops={this.props.detectInfiniteLoops}
|
detectInfiniteLoops={this.props.detectInfiniteLoops}
|
||||||
resetInfiniteLoops={this.props.resetInfiniteLoops}
|
resetInfiniteLoops={this.props.resetInfiniteLoops}
|
||||||
stopSketch={this.props.stopSketch}
|
|
||||||
startSketch={this.props.startSketch}
|
|
||||||
isPlaying={this.props.ide.isPlaying}
|
isPlaying={this.props.ide.isPlaying}
|
||||||
theme={this.props.preferences.theme}
|
theme={this.props.preferences.theme}
|
||||||
|
startRefreshSketch={this.props.startRefreshSketch}
|
||||||
|
stopSketch={this.props.stopSketch}
|
||||||
|
autorefresh={this.props.preferences.autorefresh}
|
||||||
/>
|
/>
|
||||||
<Console
|
<Console
|
||||||
consoleEvent={this.props.ide.consoleEvent}
|
consoleEvent={this.props.ide.consoleEvent}
|
||||||
|
@ -318,17 +320,11 @@ class IDEView extends React.Component {
|
||||||
isTextOutputPlaying={this.props.ide.isTextOutputPlaying}
|
isTextOutputPlaying={this.props.ide.isTextOutputPlaying}
|
||||||
textOutput={this.props.preferences.textOutput}
|
textOutput={this.props.preferences.textOutput}
|
||||||
dispatchConsoleEvent={this.props.dispatchConsoleEvent}
|
dispatchConsoleEvent={this.props.dispatchConsoleEvent}
|
||||||
<<<<<<< HEAD
|
|
||||||
infiniteLoop={this.props.ide.infiniteLoop}
|
infiniteLoop={this.props.ide.infiniteLoop}
|
||||||
resetInfiniteLoops={this.props.resetInfiniteLoops}
|
resetInfiniteLoops={this.props.resetInfiniteLoops}
|
||||||
=======
|
|
||||||
autorefresh={this.props.preferences.autorefresh}
|
autorefresh={this.props.preferences.autorefresh}
|
||||||
<<<<<<< HEAD
|
|
||||||
>>>>>>> did stuff
|
|
||||||
=======
|
|
||||||
previewIsRefreshing={this.props.ide.previewIsRefreshing}
|
previewIsRefreshing={this.props.ide.previewIsRefreshing}
|
||||||
endSketchRefresh={this.props.endSketchRefresh}
|
endSketchRefresh={this.props.endSketchRefresh}
|
||||||
>>>>>>> add previewIsRefreshing to redux state
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SplitPane>
|
</SplitPane>
|
||||||
|
@ -433,11 +429,8 @@ IDEView.propTypes = {
|
||||||
editorOptionsVisible: PropTypes.bool.isRequired,
|
editorOptionsVisible: PropTypes.bool.isRequired,
|
||||||
keyboardShortcutVisible: PropTypes.bool.isRequired,
|
keyboardShortcutVisible: PropTypes.bool.isRequired,
|
||||||
unsavedChanges: PropTypes.bool.isRequired,
|
unsavedChanges: PropTypes.bool.isRequired,
|
||||||
<<<<<<< HEAD
|
|
||||||
infiniteLoop: PropTypes.bool.isRequired,
|
infiniteLoop: PropTypes.bool.isRequired,
|
||||||
=======
|
|
||||||
previewIsRefreshing: PropTypes.bool.isRequired
|
previewIsRefreshing: PropTypes.bool.isRequired
|
||||||
>>>>>>> add previewIsRefreshing to redux state
|
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
startSketch: PropTypes.func.isRequired,
|
startSketch: PropTypes.func.isRequired,
|
||||||
stopSketch: PropTypes.func.isRequired,
|
stopSketch: PropTypes.func.isRequired,
|
||||||
|
@ -533,7 +526,9 @@ IDEView.propTypes = {
|
||||||
setUnsavedChanges: PropTypes.func.isRequired,
|
setUnsavedChanges: PropTypes.func.isRequired,
|
||||||
setTheme: PropTypes.func.isRequired,
|
setTheme: PropTypes.func.isRequired,
|
||||||
setAutorefresh: PropTypes.func.isRequired,
|
setAutorefresh: PropTypes.func.isRequired,
|
||||||
|
startSketchAndRefresh: PropTypes.func.isRequired,
|
||||||
endSketchRefresh: PropTypes.func.isRequired,
|
endSketchRefresh: PropTypes.func.isRequired,
|
||||||
|
startRefreshSketch: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
|
|
|
@ -73,17 +73,14 @@ const ide = (state = initialState, action) => {
|
||||||
return Object.assign({}, state, { keyboardShortcutVisible: false });
|
return Object.assign({}, state, { keyboardShortcutVisible: false });
|
||||||
case ActionTypes.SET_UNSAVED_CHANGES:
|
case ActionTypes.SET_UNSAVED_CHANGES:
|
||||||
return Object.assign({}, state, { unsavedChanges: action.value });
|
return Object.assign({}, state, { unsavedChanges: action.value });
|
||||||
<<<<<<< HEAD
|
|
||||||
case ActionTypes.DETECT_INFINITE_LOOPS:
|
case ActionTypes.DETECT_INFINITE_LOOPS:
|
||||||
return Object.assign({}, state, { infiniteLoop: true });
|
return Object.assign({}, state, { infiniteLoop: true });
|
||||||
case ActionTypes.RESET_INFINITE_LOOPS:
|
case ActionTypes.RESET_INFINITE_LOOPS:
|
||||||
return Object.assign({}, state, { infiniteLoop: false });
|
return Object.assign({}, state, { infiniteLoop: false });
|
||||||
=======
|
|
||||||
case ActionTypes.START_SKETCH_REFRESH:
|
case ActionTypes.START_SKETCH_REFRESH:
|
||||||
return Object.assign({}, state, { previewIsRefreshing: true });
|
return Object.assign({}, state, { previewIsRefreshing: true });
|
||||||
case ActionTypes.END_SKETCH_REFRESH:
|
case ActionTypes.END_SKETCH_REFRESH:
|
||||||
return Object.assign({}, state, { previewIsRefreshing: false });
|
return Object.assign({}, state, { previewIsRefreshing: false });
|
||||||
>>>>>>> add previewIsRefreshing to redux state
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue