浏览代码

First go at LoadingManager. See #3442.

Mr.doob 12 年之前
父节点
当前提交
8ed5ffc2ec

+ 11 - 27
examples/js/loaders/OBJLoader.js

@@ -2,46 +2,30 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.OBJLoader = function () {};
+THREE.OBJLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
 
 THREE.OBJLoader.prototype = {
 
 	constructor: THREE.OBJLoader,
 
-	addEventListener: THREE.EventDispatcher.prototype.addEventListener,
-	hasEventListener: THREE.EventDispatcher.prototype.hasEventListener,
-	removeEventListener: THREE.EventDispatcher.prototype.removeEventListener,
-	dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent,
-
 	load: function ( url, callback ) {
 
 		var scope = this;
-		var request = new XMLHttpRequest();
-
-		request.addEventListener( 'load', function ( event ) {
-
-			var response = scope.parse( event.target.responseText );
 
-			scope.dispatchEvent( { type: 'load', content: response } );
+		this.manager.add( url, 'text', function ( event ) {
 
-			if ( callback ) callback( response );
+			if ( callback !== undefined ) {
 
-		}, false );
+				var geometry = scope.parse( event.target.responseText );
+				callback( geometry );
 
-		request.addEventListener( 'progress', function ( event ) {
-
-			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
-
-		}, false );
-
-		request.addEventListener( 'error', function () {
-
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
-
-		}, false );
+			}
 
-		request.open( 'GET', url, true );
-		request.send( null );
+		} );
 
 	},
 

+ 18 - 10
examples/webgl_loader_obj.html

@@ -73,23 +73,32 @@
 
 				// texture
 
+				var manager = new THREE.LoadingManager();
+				manager.addEventListener( 'load', function ( event ) {
+
+					console.log( 'loading', event.loaded / event.total );
+
+				} );
+				manager.addEventListener( 'complete', function ( event ) {
+
+					console.log( 'loading complete' );
+
+				} );
+
 				var texture = new THREE.Texture();
 
-				var loader = new THREE.ImageLoader();
-				loader.addEventListener( 'load', function ( event ) {
+				var loader = new THREE.ImageLoader( manager );
+				loader.load( 'textures/ash_uvgrid01.jpg', function ( image ) {
 
-					texture.image = event.content;
+					texture.image = image;
 					texture.needsUpdate = true;
 
 				} );
-				loader.load( 'textures/ash_uvgrid01.jpg' );
 
 				// model
 
-				var loader = new THREE.OBJLoader();
-				loader.addEventListener( 'load', function ( event ) {
-
-					var object = event.content;
+				var loader = new THREE.OBJLoader( manager );
+				loader.load( 'obj/male02/male02.obj', function ( object ) {
 
 					object.traverse( function ( child ) {
 
@@ -104,8 +113,7 @@
 					object.position.y = - 80;
 					scene.add( object );
 
-				});
-				loader.load( 'obj/male02/male02.obj' );
+				} );
 
 				//
 

+ 13 - 26
src/loaders/GeometryLoader.js

@@ -2,43 +2,30 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.GeometryLoader = function () {};
-THREE.GeometryLoader.prototype = {
-
-	constructor: THREE.GeometryLoader,
+THREE.GeometryLoader = function ( manager ) {
 
-	addEventListener: THREE.EventDispatcher.prototype.addEventListener,
-	hasEventListener: THREE.EventDispatcher.prototype.hasEventListener,
-	removeEventListener: THREE.EventDispatcher.prototype.removeEventListener,
-	dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent,
-
-	load: function ( url ) {
-
-		var scope = this;
-		var request = new XMLHttpRequest();
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
-		request.addEventListener( 'load', function ( event ) {
-
-			var response = scope.parse( JSON.parse( event.target.responseText ) );
+};
 
-			scope.dispatchEvent( { type: 'load', content: response } );
+THREE.GeometryLoader.prototype = {
 
-		}, false );
+	constructor: THREE.GeometryLoader,
 
-		request.addEventListener( 'progress', function ( event ) {
+	load: function ( url, callback ) {
 
-			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
+		var scope = this;
 
-		}, false );
+		this.manager.add( url, 'text', function ( event ) {
 
-		request.addEventListener( 'error', function () {
+			if ( callback !== undefined ) {
 
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+				var geometry = scope.parse( JSON.parse( event.target.responseText ) );
+				callback( geometry );
 
-		}, false );
+			}
 
-		request.open( 'GET', url, true );
-		request.send( null );
+		} );
 
 	},
 

+ 8 - 21
src/loaders/ImageLoader.js

@@ -2,9 +2,9 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.ImageLoader = function () {
+THREE.ImageLoader = function ( manager ) {
 
-	this.crossOrigin = null;
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 };
 
@@ -12,32 +12,19 @@ THREE.ImageLoader.prototype = {
 
 	constructor: THREE.ImageLoader,
 
-	addEventListener: THREE.EventDispatcher.prototype.addEventListener,
-	hasEventListener: THREE.EventDispatcher.prototype.hasEventListener,
-	removeEventListener: THREE.EventDispatcher.prototype.removeEventListener,
-	dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent,
-
-	load: function ( url, image ) {
+	load: function ( url, callback ) {
 
 		var scope = this;
 
-		if ( image === undefined ) image = new Image();
-
-		image.addEventListener( 'load', function () {
-
-			scope.dispatchEvent( { type: 'load', content: image } );
-
-		}, false );
-
-		image.addEventListener( 'error', function () {
+		this.manager.add( url, 'image', function ( image ) {
 
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+			if ( callback !== undefined ) {
 
-		}, false );
+				callback( image );
 
-		if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
+			}
 
-		image.src = url;
+		} );
 
 	}
 

+ 148 - 0
src/loaders/LoadingManager.js

@@ -0,0 +1,148 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.LoadingManager = function () {
+
+	var scope = this;
+
+	var list = [], cache = {};
+
+	var isLoading = false;
+	var loaded = 0, total = 0;
+
+	var crossOrigin = null;
+
+	var load = function () {
+
+		var item = list[ 0 ];
+
+		if ( cache[ item.url ] === undefined ) {
+
+			switch ( item.type ) {
+
+				case 'image':
+
+					var image = document.createElement( 'img' );
+
+					image.addEventListener( 'load', function ( event ) {
+
+						if ( item.onLoad !== undefined ) {
+
+							item.onLoad( this );
+
+						}
+
+						cache[ item.url ] = this;
+
+						onLoad( item );
+
+					}, false );
+
+					if ( crossOrigin !== null ) image.crossOrigin = crossOrigin;
+
+					image.src = item.url;
+
+					break;
+
+				default:
+
+					var request = new XMLHttpRequest();
+
+					request.addEventListener( 'load', function ( event ) {
+
+						if ( item.onLoad !== undefined ) {
+
+							item.onLoad( event );
+
+						}
+
+						cache[ item.url ] = event;
+
+						onLoad( item );
+
+					}, false );
+
+					request.open( 'GET', item.url, true );
+					request.send( null );
+
+					break;
+
+			}
+
+		} else {
+
+			if ( item.onLoad !== undefined ) {
+
+				item.onLoad( cache[ item.url ] );
+
+			}
+
+			onLoad( item );
+
+		}
+
+		list.shift();
+
+	};
+
+	var onLoad = function ( item ) {
+
+		loaded ++;
+
+		scope.dispatchEvent( { type: 'load', item: item, loaded: loaded, total: total } );
+
+		if ( loaded === total ) {
+
+			isLoading = false;
+			scope.dispatchEvent( { type: 'complete' } );
+
+		} else {
+
+			load();
+
+		}
+
+	};
+
+	this.add = function ( url, type, onLoad, onProgress, onError ) {
+
+		total ++;
+
+		list.push( {
+			url: url,
+			type: type,
+			onLoad: onLoad,
+			onProgress: onProgress,
+			onError: onError
+		} );
+
+		if ( isLoading === false ) {
+
+			isLoading = true;
+			load();
+
+		}
+
+	};
+
+	this.setCrossOrigin = function ( value ) {
+
+		crossOrigin = value;
+
+	};
+
+};
+
+THREE.LoadingManager.prototype = {
+
+	constructor: THREE.LoadingManager,
+
+	addEventListener: THREE.EventDispatcher.prototype.addEventListener,
+	hasEventListener: THREE.EventDispatcher.prototype.hasEventListener,
+	removeEventListener: THREE.EventDispatcher.prototype.removeEventListener,
+	dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent
+
+};
+
+THREE.DefaultLoadingManager = new THREE.LoadingManager();

+ 0 - 45
src/loaders/LoadingMonitor.js

@@ -1,45 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-THREE.LoadingMonitor = function () {
-
-	var scope = this;
-
-	var loaded = 0;
-	var total = 0;
-
-	var onLoad = function ( event ) {
-
-		loaded ++;
-
-		scope.dispatchEvent( { type: 'progress', loaded: loaded, total: total } );
-
-		if ( loaded === total ) {
-
-			scope.dispatchEvent( { type: 'load' } );
-
-		}
-
-	};
-
-	this.add = function ( loader ) {
-
-		total ++;
-
-		loader.addEventListener( 'load', onLoad, false );
-
-	};
-
-};
-
-THREE.LoadingMonitor.prototype = {
-
-	constructor: THREE.LoadingMonitor,
-
-	addEventListener: THREE.EventDispatcher.prototype.addEventListener,
-	hasEventListener: THREE.EventDispatcher.prototype.hasEventListener,
-	removeEventListener: THREE.EventDispatcher.prototype.removeEventListener,
-	dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent
-
-};

+ 12 - 26
src/loaders/MaterialLoader.js

@@ -2,44 +2,30 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.MaterialLoader = function () {};
+THREE.MaterialLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
 
 THREE.MaterialLoader.prototype = {
 
 	constructor: THREE.MaterialLoader,
 
-	addEventListener: THREE.EventDispatcher.prototype.addEventListener,
-	hasEventListener: THREE.EventDispatcher.prototype.hasEventListener,
-	removeEventListener: THREE.EventDispatcher.prototype.removeEventListener,
-	dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent,
-
-	load: function ( url ) {
+	load: function ( url, callback ) {
 
 		var scope = this;
-		var request = new XMLHttpRequest();
-
-		request.addEventListener( 'load', function ( event ) {
-
-			var response = scope.parse( JSON.parse( event.target.responseText ) );
-
-			scope.dispatchEvent( { type: 'load', content: response } );
-
-		}, false );
-
-		request.addEventListener( 'progress', function ( event ) {
-
-			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 
-		}, false );
+		this.manager.add( url, 'text', function ( event ) {
 
-		request.addEventListener( 'error', function () {
+			if ( callback !== undefined ) {
 
-			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+				var material = scope.parse( JSON.parse( event.target.responseText ) );
+				callback( material );
 
-		}, false );
+			}
 
-		request.open( 'GET', url, true );
-		request.send( null );
+		} );
 
 	},
 

+ 1 - 1
utils/build/includes/common.json

@@ -41,7 +41,7 @@
 	"src/loaders/Loader.js",
 	"src/loaders/ImageLoader.js",
 	"src/loaders/JSONLoader.js",
-	"src/loaders/LoadingMonitor.js",
+	"src/loaders/LoadingManager.js",
 	"src/loaders/GeometryLoader.js",
 	"src/loaders/MaterialLoader.js",
 	"src/loaders/SceneLoader.js",