Browse Source

Editor: New scripting system working \o/

Mr.doob 10 years ago
parent
commit
e1461e8e09
6 changed files with 128 additions and 37 deletions
  1. 2 1
      editor/css/main.css
  2. 1 0
      editor/index.html
  3. 21 17
      editor/js/Sidebar.Script.js
  4. 72 13
      editor/js/libs/app.js
  5. 14 6
      editor/js/libs/ui.editor.js
  6. 18 0
      editor/js/libs/ui.js

+ 2 - 1
editor/css/main.css

@@ -19,6 +19,7 @@ button {
 }
 }
 
 
 textarea {
 textarea {
+	tab-size: 4;
 	white-space: pre;
 	white-space: pre;
 	word-wrap: normal;
 	word-wrap: normal;
 }
 }
@@ -121,4 +122,4 @@ textarea, input { outline: none; } /* osx */
 
 
 .MeshPhongMaterial {
 .MeshPhongMaterial {
 	color: #ffaa88;
 	color: #ffaa88;
-}
+}

+ 1 - 0
editor/index.html

@@ -174,6 +174,7 @@
 				signals.objectRemoved.add( saveState );
 				signals.objectRemoved.add( saveState );
 				signals.materialChanged.add( saveState );
 				signals.materialChanged.add( saveState );
 				signals.sceneGraphChanged.add( saveState );
 				signals.sceneGraphChanged.add( saveState );
+				signals.scriptChanged.add( saveState );
 
 
 				var showDialog = function ( content ) {
 				var showDialog = function ( content ) {
 
 

+ 21 - 17
editor/js/Sidebar.Script.js

@@ -18,41 +18,46 @@ Sidebar.Script = function ( editor ) {
 	container.addStatic( new UI.Text( 'Script' ).setTextTransform( 'uppercase' ) );
 	container.addStatic( new UI.Text( 'Script' ).setTextTransform( 'uppercase' ) );
 	container.add( new UI.Break() );
 	container.add( new UI.Break() );
 
 
-	var scripts = new UI.Panel();
-	container.add( scripts );
-
 	//
 	//
 
 
-	var scriptEvent = new UI.Select();
-	scriptEvent.setOptions( {
+	var scriptsContainer = new UI.Panel();
+	container.add( scriptsContainer );
+
+	var eventType = new UI.Select();
+	eventType.setOptions( {
 
 
 		'init': 'init',
 		'init': 'init',
 		'keydown': 'keydown',
 		'keydown': 'keydown',
 		'keyup': 'keyup',
 		'keyup': 'keyup',
+		'mousedown': 'mousedown',
+		'mouseup': 'mouseup',
+		'mousemove': 'mousemove',
 		'update': 'update'
 		'update': 'update'
 
 
 	} );
 	} );
-	container.add( scriptEvent );
+	container.add( eventType );
 
 
-	var addButton = new UI.Button( 'Add' );
-	addButton.onClick( function () {
+	var button = new UI.Button( 'Add' );
+	button.setMarginLeft( '5px' );
+	button.onClick( function () {
 
 
 		var script = new UI.ScriptEditor();
 		var script = new UI.ScriptEditor();
+		script.setValue( { event: eventType.getValue(), source: '' } );
 		script.onChange( function () {
 		script.onChange( function () {
 
 
 			signals.scriptChanged.dispatch();
 			signals.scriptChanged.dispatch();
 
 
 		} );
 		} );
-		scripts.add( script );
+		scriptsContainer.add( script );
 
 
 	} );
 	} );
-	container.add( addButton );
+	container.add( button );
 
 
 	// signals
 	// signals
 
 
 	signals.objectSelected.add( function ( object ) {
 	signals.objectSelected.add( function ( object ) {
 
 
-		scripts.clear();
+		scriptsContainer.clear();
 
 
 		if ( object !== null ) {
 		if ( object !== null ) {
 
 
@@ -64,16 +69,14 @@ Sidebar.Script = function ( editor ) {
 
 
 				for ( var i = 0; i < sources.length; i ++ ) {
 				for ( var i = 0; i < sources.length; i ++ ) {
 
 
-					var source = sources[ i ];
-
 					var script = new UI.ScriptEditor();
 					var script = new UI.ScriptEditor();
-					script.setValue( source );
+					script.setValue( sources[ i ] );
 					script.onChange( function () {
 					script.onChange( function () {
 
 
 						signals.scriptChanged.dispatch();
 						signals.scriptChanged.dispatch();
 
 
 					} );
 					} );
-					scripts.add( script );
+					scriptsContainer.add( script );
 
 
 				}
 				}
 
 
@@ -92,9 +95,10 @@ Sidebar.Script = function ( editor ) {
 		var array = [];
 		var array = [];
 		var object = editor.selected;
 		var object = editor.selected;
 
 
-		for ( var i = 0; i < scripts.children.length; i ++ ) {
+		for ( var i = 0; i < scriptsContainer.children.length; i ++ ) {
+
+			var script = scriptsContainer.children[ i ];
 
 
-			var script = scripts.children[ i ];
 			array.push( script.getValue() );
 			array.push( script.getValue() );
 
 
 		}
 		}

+ 72 - 13
editor/js/libs/app.js

@@ -9,9 +9,7 @@ var APP = {
 		var loader = new THREE.ObjectLoader();
 		var loader = new THREE.ObjectLoader();
 		var camera, scene, renderer;
 		var camera, scene, renderer;
 
 
-		var scripts = {
-			update: []
-		};
+		var scripts = {};
 
 
 		this.dom = undefined;
 		this.dom = undefined;
 
 
@@ -21,27 +19,38 @@ var APP = {
 			renderer.setPixelRatio( window.devicePixelRatio );
 			renderer.setPixelRatio( window.devicePixelRatio );
 
 
 			camera = loader.parse( json.camera );
 			camera = loader.parse( json.camera );
-
 			scene = loader.parse( json.scene );
 			scene = loader.parse( json.scene );
 
 
-			scripts.update = [];
+			scripts = {
+				init: [],
+				keydown: [],
+				keyup: [],
+				mousedown: [],
+				mouseup: [],
+				mousemove: [],
+				update: []
+			};
 
 
 			for ( var uuid in json.scripts ) {
 			for ( var uuid in json.scripts ) {
 
 
 				var object = scene.getObjectByProperty( 'uuid', uuid, true );
 				var object = scene.getObjectByProperty( 'uuid', uuid, true );
+
 				var sources = json.scripts[ uuid ];
 				var sources = json.scripts[ uuid ];
 
 
 				for ( var i = 0; i < sources.length; i ++ ) {
 				for ( var i = 0; i < sources.length; i ++ ) {
 
 
-					var source = sources[ i ];
+					var script = sources[ i ];
 
 
-					var script = ( new Function( 'scene', 'time', source ).bind( object ) );
-					scripts.update.push( script );
+					script.compiled = new Function( 'event', script.source ).bind( object );
+
+					scripts[ script.event ].push( script.compiled );
 
 
 				}
 				}
 
 
 			}
 			}
 
 
+			dispatch( scripts.init, {} );
+
 			this.dom = renderer.domElement;
 			this.dom = renderer.domElement;
 
 
 		};
 		};
@@ -55,17 +64,23 @@ var APP = {
 
 
 		};
 		};
 
 
+		var dispatch = function ( array, event ) {
+
+			for ( var i = 0, l = array.length; i < l; i ++ ) {
+
+				array[ i ]( event );
+
+			}
+
+		};
+
 		var request;
 		var request;
 
 
 		var animate = function ( time ) {
 		var animate = function ( time ) {
 
 
 			request = requestAnimationFrame( animate );
 			request = requestAnimationFrame( animate );
 
 
-			for ( var i = 0, l = scripts.update.length; i < l; i ++ ) {
-
-				scripts.update[ i ]( scene, time );
-
-			}
+			dispatch( scripts.update, { time: time } );
 
 
 			renderer.render( scene, camera );
 			renderer.render( scene, camera );
 
 
@@ -73,16 +88,60 @@ var APP = {
 
 
 		this.play = function () {
 		this.play = function () {
 
 
+			document.addEventListener( 'keydown', onDocumentKeyDown );
+			document.addEventListener( 'keyup', onDocumentKeyUp );
+			document.addEventListener( 'mousedown', onDocumentMouseDown );
+			document.addEventListener( 'mouseup', onDocumentMouseUp );
+			document.addEventListener( 'mousemove', onDocumentMouseMove );
+
 			request = requestAnimationFrame( animate );
 			request = requestAnimationFrame( animate );
 
 
 		};
 		};
 
 
 		this.stop = function () {
 		this.stop = function () {
 
 
+			document.removeEventListener( 'keydown', onDocumentKeyDown );
+			document.removeEventListener( 'keyup', onDocumentKeyUp );
+			document.removeEventListener( 'mousedown', onDocumentMouseDown );
+			document.removeEventListener( 'mouseup', onDocumentMouseUp );
+			document.removeEventListener( 'mousemove', onDocumentMouseMove );
+			
 			cancelAnimationFrame( request );
 			cancelAnimationFrame( request );
 
 
 		};
 		};
 
 
+		//
+
+		var onDocumentKeyDown = function ( event ) {
+
+			dispatch( scripts.keydown, event );
+
+		};
+
+		var onDocumentKeyUp = function ( event ) {
+
+			dispatch( scripts.keyup, event );
+
+		};
+
+		var onDocumentMouseDown = function ( event ) {
+
+			dispatch( scripts.mousedown, event );
+
+		};
+
+		var onDocumentMouseUp = function ( event ) {
+
+			dispatch( scripts.mouseup, event );
+
+		};
+
+		var onDocumentMouseMove = function ( event ) {
+
+			dispatch( scripts.mousemove, event );
+
+		};
+
 	}
 	}
 
 
 };
 };

+ 14 - 6
editor/js/libs/ui.editor.js

@@ -10,8 +10,13 @@ UI.ScriptEditor = function () {
 
 
 	var timeout;
 	var timeout;
 
 
+	var event = new UI.Text( '' );
+	this.add( event );
+
+	this.add( new UI.Break() );
+
 	var textarea = new UI.TextArea();
 	var textarea = new UI.TextArea();
-	textarea.setWidth( '240px' );
+	textarea.setWidth( '100%' );
 	textarea.setHeight( '100px' );
 	textarea.setHeight( '100px' );
 	textarea.onKeyUp( function () {
 	textarea.onKeyUp( function () {
 
 
@@ -20,18 +25,19 @@ UI.ScriptEditor = function () {
 		timeout = setTimeout( function () {
 		timeout = setTimeout( function () {
 
 
 			var object = editor.selected;
 			var object = editor.selected;
-			var source = scope.getValue();
+			var source = textarea.getValue();
 
 
 			try {
 			try {
 
 
-				var script = new Function( 'scene', 'time', source ).bind( object.clone() );
-				script( new THREE.Scene(), 0 );
+				( new Function( 'event', source ).bind( object.clone() ) )( {} );
 
 
 				textarea.dom.classList.add( 'success' );
 				textarea.dom.classList.add( 'success' );
 				textarea.dom.classList.remove( 'fail' );
 				textarea.dom.classList.remove( 'fail' );
 
 
 			} catch ( error ) {
 			} catch ( error ) {
 
 
+				console.error( error );
+
 				textarea.dom.classList.remove( 'success' );
 				textarea.dom.classList.remove( 'success' );
 				textarea.dom.classList.add( 'fail' );
 				textarea.dom.classList.add( 'fail' );
 
 
@@ -50,6 +56,7 @@ UI.ScriptEditor = function () {
 	} );
 	} );
 	this.add( textarea );
 	this.add( textarea );
 
 
+	this.event = event;
 	this.textarea = textarea;
 	this.textarea = textarea;
 
 
 };
 };
@@ -59,13 +66,14 @@ UI.ScriptEditor.prototype.constructor = UI.ScriptEditor;
 
 
 UI.ScriptEditor.prototype.getValue = function () {
 UI.ScriptEditor.prototype.getValue = function () {
 
 
-	return this.textarea.getValue();
+	return { event: this.event.getValue(), source: this.textarea.getValue() };
 
 
 };
 };
 
 
 UI.ScriptEditor.prototype.setValue = function ( value ) {
 UI.ScriptEditor.prototype.setValue = function ( value ) {
 
 
-	this.textarea.setValue( value );
+	this.event.setValue( value.event );
+	this.textarea.setValue( value.source );
 
 
 	return this;
 	return this;
 
 

+ 18 - 0
editor/js/libs/ui.js

@@ -100,6 +100,7 @@ UI.Panel = function () {
 	dom.className = 'Panel';
 	dom.className = 'Panel';
 
 
 	this.dom = dom;
 	this.dom = dom;
+	this.children = [];
 
 
 	return this;
 	return this;
 };
 };
@@ -116,6 +117,7 @@ UI.Panel.prototype.add = function () {
 		if ( argument instanceof UI.Element ) {
 		if ( argument instanceof UI.Element ) {
 
 
 			this.dom.appendChild( argument.dom );
 			this.dom.appendChild( argument.dom );
+			this.children.push( argument );
 
 
 		} else {
 		} else {
 
 
@@ -140,6 +142,14 @@ UI.Panel.prototype.remove = function () {
 
 
 			this.dom.removeChild( argument.dom );
 			this.dom.removeChild( argument.dom );
 
 
+			var index = this.children.indexOf( argument );
+
+			if ( index !== - 1 ) {
+
+				this.children.splice( index, 1 );
+
+			}
+
 		} else {
 		} else {
 
 
 			console.error( 'UI.Panel:', argument, 'is not an instance of UI.Element.' )
 			console.error( 'UI.Panel:', argument, 'is not an instance of UI.Element.' )
@@ -160,6 +170,8 @@ UI.Panel.prototype.clear = function () {
 
 
 	}
 	}
 
 
+	this.children = [];
+
 };
 };
 
 
 
 
@@ -307,6 +319,12 @@ UI.Text = function ( text ) {
 UI.Text.prototype = Object.create( UI.Element.prototype );
 UI.Text.prototype = Object.create( UI.Element.prototype );
 UI.Text.prototype.constructor = UI.Text;
 UI.Text.prototype.constructor = UI.Text;
 
 
+UI.Text.prototype.getValue = function () {
+
+	return this.dom.textContent;
+
+};
+
 UI.Text.prototype.setValue = function ( value ) {
 UI.Text.prototype.setValue = function ( value ) {
 
 
 	if ( value !== undefined ) {
 	if ( value !== undefined ) {