1 /**
  2  * The Render Engine
  3  * SoundResourceLoader
  4  *
  5  * @fileoverview A resource loader for sounds.
  6  *
  7  * @author: Brett Fattori (brettf@renderengine.com)
  8  * @author: $Author: bfattori $
  9  * @version: $Revision: 1555 $
 10  *
 11  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 12  *
 13  * Permission is hereby granted, free of charge, to any person obtaining a copy
 14  * of this software and associated documentation files (the "Software"), to deal
 15  * in the Software without restriction, including without limitation the rights
 16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 17  * copies of the Software, and to permit persons to whom the Software is
 18  * furnished to do so, subject to the following conditions:
 19  *
 20  * The above copyright notice and this permission notice shall be included in
 21  * all copies or substantial portions of the Software.
 22  *
 23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 28  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 29  * THE SOFTWARE.
 30  *
 31  */
 32 
 33 // The class this file defines and its required classes
 34 R.Engine.define({
 35     "class":"R.resources.loaders.SoundLoader",
 36     "requires":[
 37         "R.resources.loaders.RemoteLoader",
 38         "R.lang.Timeout"
 39     ]
 40 });
 41 
 42 /**
 43  * @class Loads sounds and stores the reference to them using the provided sound
 44  *          system.  Sounds resource that are loaded are cached with the loader.
 45  *
 46  * @constructor
 47  * @param soundSystem {R.sound.AbstractSoundSystem} A sound system instance, either {@link R.sound.SM2} or
 48  *     {@link R.sound.HTML5}.
 49  * @extends R.resources.loaders.RemoteLoader
 50  */
 51 R.resources.loaders.SoundLoader = function () {
 52     return R.resources.loaders.RemoteLoader.extend(/** @scope R.resources.loaders.SoundLoader.prototype */{
 53 
 54         queuedSounds:null,
 55         checkReady:null,
 56         soundSystem:null,
 57         queueingSounds:true,
 58         loadingSounds:0,
 59 
 60         /** @private */
 61         constructor:function (soundSystem) {
 62             this.base("SoundLoader");
 63             this.init = false;
 64             this.queuedSounds = [];
 65             this.queueingSounds = true;
 66             this.loadingSounds = 0;
 67             this.soundSystem = soundSystem;
 68         },
 69 
 70         /**
 71          * Destroy the sound loader and shut down the sound system
 72          */
 73         destroy:function () {
 74             if (this.soundSystem) {
 75                 this.soundSystem.shutdown();
 76                 this.soundSystem = null;
 77             }
 78         },
 79 
 80         /**
 81          * Load a sound resource from a URL. If the sound system does not initialize, for whatever
 82          * reason, you can still call the sound's methods.
 83          *
 84          * @param name {String} The name of the resource
 85          * @param url {String} The URL where the resource is located
 86          */
 87         load:function (name, url) {
 88             var soundObj = this.soundSystem.loadSound(this, name, url);
 89 
 90             // We'll need to periodically check a sound's "readyState" for success
 91             // to know when the sound is ready for usage.
 92             this.loadingSounds++;
 93             if (!this.checkReady) {
 94                 var self = this;
 95                 this.checkReady = true;
 96 
 97                 R.lang.Timeout.create("waitForSounds", 500, function () {
 98                     var sounds = self.getResources();
 99                     for (var s in sounds) {
100                         if (!self.isReady(sounds[s]) && self.get(sounds[s]).getReadyState()) {
101                             self.setReady(sounds[s], true);
102                             self.loadingSounds--;
103                         }
104                     }
105 
106                     if (self.loadingSounds != 0) {
107                         // There are still sounds loading
108                         this.restart();
109                     }
110                     else {
111                         self.checkReady = false;
112                         this.destroy();
113                     }
114                 });
115             }
116 
117             if (!this.init) {
118                 this.init = true;
119             }
120 
121             this.base(name, url, soundObj);
122         },
123 
124         /**
125          * Unload a sound, calling the proper methods in the sound system.
126          *
127          * @param sound {String} The name of the sound to unload
128          */
129         unload:function (sound) {
130             var s = this.get(sound).destroy();
131             this.base(sound);
132         },
133 
134         /**
135          * Creates a {@link R.resources.types.Sound} object representing the named sound.
136          *
137          * @param sound {String} The name of the sound from the resource
138          * @return {R.resources.types.Sound} A {@link R.resources.types.Sound} instance
139          */
140         getSound:function (sound) {
141             return this.get(sound);
142         },
143 
144         /**
145          * Get the specific sound resource by name.
146          * @param name {String} The name of the resource
147          * @return {R.resources.types.Sound}
148          */
149         getResourceObject:function (name) {
150             return this.getSound(name);
151         },
152 
153         /**
154          * The name of the resource this loader will get.
155          * @return {String} The string "sound"
156          */
157         getResourceType:function () {
158             return "sound";
159         }
160 
161     }, /** @scope R.resources.loaders.SoundLoader.prototype */ {
162         /**
163          * Get the class name of this object
164          * @return {String} The string "R.resources.loaders.SoundLoader"
165          */
166         getClassName:function () {
167             return "R.resources.loaders.SoundLoader";
168         }
169     });
170 
171 };
172