Showing the changes to scripts/tutorials/entity_scripts (1 of 1 file). Show all
Unified · Split
| @@ -27,6 +27,14 @@ · 26 unmodified lines | ||
| 27 | 27 | var DEFAULT_URL = "http://hifi-content.s3.amazonaws.com/ken/samples/forest_ambiX.wav"; |
| 28 | 28 | var DEFAULT_VOLUME = 1.0; |
| 29 | 29 | |
| 30 | + var DEFAULT_USERDATA = { | |
| 31 | + soundURL: DEFAULT_URL, | |
| 32 | + range: DEFAULT_RANGE, | |
| 33 | + maxVolume: DEFAULT_VOLUME, | |
| 34 | + disabled: true, | |
| 35 | + grabbableKey: { wantsTrigger: true }, | |
| 36 | + }; | |
| 37 | + | |
| 30 | 38 | var soundURL = ""; |
| 31 | 39 | var soundOptions = { |
| 32 | 40 | loop: true, |
| @@ -60,7 +68,13 @@ · 27 unmodified lines | ||
| 60 | 68 | var oldSoundURL = soundURL; |
| 61 | 69 | var props = Entities.getEntityProperties(entity, [ "userData" ]); |
| 62 | 70 | if (props.userData) { |
| 63 | − var data = JSON.parse(props.userData); | |
| 71 | + try { | |
| 72 | + var data = JSON.parse(props.userData); | |
| 73 | + } catch(e) { | |
| 74 | + debugPrint("unable to parse userData JSON string: " + props.userData); | |
| 75 | + this.cleanup(); | |
| 76 | + return; | |
| 77 | + } | |
| 64 | 78 | if (data.soundURL && !(soundURL === data.soundURL)) { |
| 65 | 79 | soundURL = data.soundURL; |
| 66 | 80 | debugPrint("Read ambient sound URL: " + soundURL); |
| @@ -125,18 +139,27 @@ · 58 unmodified lines | ||
| 125 | 139 | return; |
| 126 | 140 | } |
| 127 | 141 | var props = Entities.getEntityProperties(entity, [ "userData", "age", "scriptTimestamp" ]); |
| 142 | + if (!props.userData) { | |
| 143 | + debugPrint("userData is empty; ignoring " + hint); | |
| 144 | + this.cleanup(); | |
| 145 | + return; | |
| 146 | + } | |
| 128 | 147 | var data = JSON.parse(props.userData); |
| 129 | 148 | data.disabled = !data.disabled; |
| 130 | 149 | |
| 131 | 150 | debugPrint(hint + " -- triggering ambient sound " + (data.disabled ? "OFF" : "ON") + " (" + soundURL + ")"); |
| 132 | 151 | |
| 133 | 152 | this.cleanup(); |
| 153 | + // Prevent rapid-fire toggling (which seems to sometimes lead to sound injectors becoming unstoppable) | |
| 154 | + this._toggle = this.clickDownOnEntity = function(hint) { debugPrint("ignoring additonal clicks" + hint); }; | |
| 134 | 155 | |
| 135 | − // Save the userData and bump scriptTimestamp, which causes all nearby listeners to apply the state change | |
| 136 | − Entities.editEntity(entity, { | |
| 137 | − userData: JSON.stringify(data), | |
| 138 | − scriptTimestamp: Math.round(props.age * 1000) | |
| 139 | − }); | |
| 156 | + Script.setTimeout(function() { | |
| 157 | + // Save the userData and bump scriptTimestamp, which causes all nearby listeners to apply the state change | |
| 158 | + Entities.editEntity(entity, { | |
| 159 | + userData: JSON.stringify(data), | |
| 160 | + scriptTimestamp: props.scriptTimestamp + 1 | |
| 161 | + }); | |
| 162 | + }, 250); | |
| 140 | 163 | }; |
| 141 | 164 | |
| 142 | 165 | this._updateColor = function(disabled) { |
| @@ -155,21 +178,35 @@ · 12 unmodified lines | ||
| 155 | 178 | |
| 156 | 179 | this.preload = function(entityID) { |
| 157 | 180 | // Load the sound and range from the entity userData fields, and note the position of the entity. |
| 158 | − debugPrint("Ambient sound preload"); | |
| 181 | + debugPrint("Ambient sound preload " + entityID); | |
| 159 | 182 | entity = entityID; |
| 160 | 183 | _this = this; |
| 161 | 184 | |
| 162 | − var props = Entities.getEntityProperties(entity, [ "userData" ]); | |
| 185 | + var props = Entities.getEntityProperties(entity, [ "name", "userData" ]); | |
| 186 | + var data = {}; | |
| 163 | 187 | if (props.userData) { |
| 164 | − var data = JSON.parse(props.userData); | |
| 165 | − this._updateColor(data.disabled); | |
| 166 | − if (data.disabled) { | |
| 167 | − _this.maybeUpdate(); | |
| 168 | − return; | |
| 188 | + data = JSON.parse(props.userData); | |
| 189 | + } | |
| 190 | + var changed = false; | |
| 191 | + for(var p in DEFAULT_USERDATA) { | |
| 192 | + if (!(p in data)) { | |
| 193 | + data[p] = DEFAULT_USERDATA[p]; | |
| 194 | + changed = true; | |
| 169 | 195 | } |
| 170 | 196 | } |
| 171 | − | |
| 172 | − checkTimer = Script.setInterval(_this.maybeUpdate, UPDATE_INTERVAL_MSECS); | |
| 197 | + if (!data.grabbableKey.wantsTrigger) { | |
| 198 | + data.grabbableKey.wantsTrigger = true; | |
| 199 | + changed = true; | |
| 200 | + } | |
| 201 | + if (changed) { | |
| 202 | + debugPrint("applying default values to userData"); | |
| 203 | + Entities.editEntity(entity, { userData: JSON.stringify(data) }); | |
| 204 | + } | |
| 205 | + this._updateColor(data.disabled); | |
| 206 | + this.updateSettings(); | |
| 207 | + if (!data.disabled) { | |
| 208 | + checkTimer = Script.setInterval(_this.maybeUpdate, UPDATE_INTERVAL_MSECS); | |
| 209 | + } | |
| 173 | 210 | }; |
| 174 | 211 | |
| 175 | 212 | this.maybeUpdate = function() { |