diff --git a/src/loaders/Cache.js b/src/loaders/Cache.js index 9f63c8dfc67a7f..6bbf2081b10048 100644 --- a/src/loaders/Cache.js +++ b/src/loaders/Cache.js @@ -1,46 +1,78 @@ /** * @author mrdoob / http://mrdoob.com/ + * @author vladgaidukov / vlad@meliar.ru */ var Cache = { - enabled: false, + enabled: false, - files: {}, + objects: {}, - add: function ( key, file ) { + addObject: function ( key, obj ) { + + if ( this.enabled === false ) return; - if ( this.enabled === false ) return; + this.objects[ key ] = { + loaded: false, + object: obj, + callbacks: [] + }; - // console.log( 'THREE.Cache', 'Adding key:', key ); + }, - this.files[ key ] = file; + addCallback: function ( key, callback ) { + + if ( this.enabled === false ) return; - }, + this.objects[ key ].callbacks.push( callback ); - get: function ( key ) { + }, - if ( this.enabled === false ) return; + isCached: function ( key ) { - // console.log( 'THREE.Cache', 'Checking key:', key ); + if ( this.objects [ key ] ) return true; - return this.files[ key ]; + return false; - }, + }, - remove: function ( key ) { + getObject: function ( key ) { + + if ( this.enabled === false ) return; - delete this.files[ key ]; + return this.objects[ key ]; - }, + }, - clear: function () { + loaded: function ( key, obj ) { - this.files = {}; + if ( !this.objects[ key ] ) return; - } + this.objects[ key ].object = obj; + this.objects[ key ].loaded = true; -}; + }, + + isLoaded: function ( key ) { + + if ( !this.objects[ key ] ) return false; + + return this.objects[ key ].loaded; + + }, + + remove: function ( key ) { + delete this.objects[ key ]; + + }, + + clear: function () { + + this.objects = {}; + + } +}; export { Cache }; diff --git a/src/loaders/FileLoader.js b/src/loaders/FileLoader.js index 83fca983285acc..dd55a49c88db8e 100644 --- a/src/loaders/FileLoader.js +++ b/src/loaders/FileLoader.js @@ -1,5 +1,6 @@ /** * @author mrdoob / http://mrdoob.com/ + * @author vladgaidukov / vlad@meliar.ru */ import { Cache } from './Cache'; @@ -21,19 +22,25 @@ Object.assign( FileLoader.prototype, { var scope = this; - var cached = Cache.get( url ); - - if ( cached !== undefined ) { + if ( Cache.isLoaded( url ) ) { + + var cached = Cache.getObject( url ).object; scope.manager.itemStart( url ); - setTimeout( function () { + if ( onLoad ) { + + setTimeout ( function () { + + onLoad( cached ); + scope.manager.itemEnd( url ); - if ( onLoad ) onLoad( cached ); + }, 0); + } else { scope.manager.itemEnd( url ); - }, 0 ); + } return cached; @@ -129,72 +136,105 @@ Object.assign( FileLoader.prototype, { var request = new XMLHttpRequest(); request.open( 'GET', url, true ); + + if ( Cache.isCached( url ) ) { - request.addEventListener( 'load', function ( event ) { + Cache.addCallback( url, onLoad ); - var response = event.target.response; + } else { - Cache.add( url, response ); + Cache.addObject( url ); + + Cache.addCallback( url, onLoad ); - if ( this.status === 200 ) { + request.addEventListener( 'load', function ( event ) { - if ( onLoad ) onLoad( response ); + var response = event.target.response; - scope.manager.itemEnd( url ); + if ( this.status === 200 ) { - } else if ( this.status === 0 ) { + if ( Cache.enabled ) { + + Cache.loaded ( url, response ); + var cached = Cache.getObject ( url ); - // Some browsers return HTTP Status 0 when using non-http protocol - // e.g. 'file://' or 'data://'. Handle as success. + for ( var i = 0; i < cached.callbacks.length; i ++ ) { - console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); + if ( cached.callbacks[ i ] ) { - if ( onLoad ) onLoad( response ); + cached.callbacks[ i ]( response ); - scope.manager.itemEnd( url ); + } - } else { + scope.manager.itemEnd( url ); - if ( onError ) onError( event ); + } + } else { + + if ( onLoad ) onLoad( response ); + + scope.manager.itemEnd( url ); + + } - scope.manager.itemError( url ); + } else if ( this.status === 0 ) { - } + // Some browsers return HTTP Status 0 when using non-http protocol + // e.g. 'file://' or 'data://'. Handle as success. - }, false ); + console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); - if ( onProgress !== undefined ) { + if ( onLoad ) onLoad( response ); - request.addEventListener( 'progress', function ( event ) { + scope.manager.itemEnd( url ); - onProgress( event ); + } else { - }, false ); + Cache.remove ( url ); - } + if ( onError ) onError( event ); - request.addEventListener( 'error', function ( event ) { + scope.manager.itemError( url ); - if ( onError ) onError( event ); + } - scope.manager.itemError( url ); + }, false ); - }, false ); + if ( onProgress !== undefined ) { - if ( this.responseType !== undefined ) request.responseType = this.responseType; - if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; + request.addEventListener( 'progress', function ( event ) { - if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); + onProgress( event ); - for ( var header in this.requestHeader ) { + + }, false ); + + } + + request.addEventListener( 'error', function ( event ) { + + if ( onError ) onError( event ); + + scope.manager.itemError( url ); + + }, false ); + + if ( this.responseType !== undefined ) request.responseType = this.responseType; + if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; + + if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); + + for ( var header in this.requestHeader ) { request.setRequestHeader( header, this.requestHeader[ header ] ); - } + } - request.send( null ); + request.send( null ); + + } - } + } scope.manager.itemStart( url );