corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, openmetaverse.org
3 * All rights reserved.
4 *
5 * - Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * - Neither the name of the openmetaverse.org nor the names
11 * of its contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26  
27 using System;
28 using System.Collections.Generic;
29 using OpenMetaverse.Packets;
30  
31 namespace OpenMetaverse
32 {
33 /// <summary>
34 ///
35 /// </summary>
36 public class SoundManager
37 {
38 #region Private Members
39 private readonly GridClient Client;
40 #endregion
41  
42 #region Event Handling
43 /// <summary>The event subscribers, null of no subscribers</summary>
44 private EventHandler<AttachedSoundEventArgs> m_AttachedSound;
45  
46 ///<summary>Raises the AttachedSound Event</summary>
47 /// <param name="e">A AttachedSoundEventArgs object containing
48 /// the data sent from the simulator</param>
49 protected virtual void OnAttachedSound(AttachedSoundEventArgs e)
50 {
51 EventHandler<AttachedSoundEventArgs> handler = m_AttachedSound;
52 if (handler != null)
53 handler(this, e);
54 }
55  
56 /// <summary>Thread sync lock object</summary>
57 private readonly object m_AttachedSoundLock = new object();
58  
59 /// <summary>Raised when the simulator sends us data containing
60 /// sound</summary>
61 public event EventHandler<AttachedSoundEventArgs> AttachedSound
62 {
63 add { lock (m_AttachedSoundLock) { m_AttachedSound += value; } }
64 remove { lock (m_AttachedSoundLock) { m_AttachedSound -= value; } }
65 }
66  
67 /// <summary>The event subscribers, null of no subscribers</summary>
68 private EventHandler<AttachedSoundGainChangeEventArgs> m_AttachedSoundGainChange;
69  
70 ///<summary>Raises the AttachedSoundGainChange Event</summary>
71 /// <param name="e">A AttachedSoundGainChangeEventArgs object containing
72 /// the data sent from the simulator</param>
73 protected virtual void OnAttachedSoundGainChange(AttachedSoundGainChangeEventArgs e)
74 {
75 EventHandler<AttachedSoundGainChangeEventArgs> handler = m_AttachedSoundGainChange;
76 if (handler != null)
77 handler(this, e);
78 }
79  
80 /// <summary>Thread sync lock object</summary>
81 private readonly object m_AttachedSoundGainChangeLock = new object();
82  
83 /// <summary>Raised when the simulator sends us data containing
84 /// ...</summary>
85 public event EventHandler<AttachedSoundGainChangeEventArgs> AttachedSoundGainChange
86 {
87 add { lock (m_AttachedSoundGainChangeLock) { m_AttachedSoundGainChange += value; } }
88 remove { lock (m_AttachedSoundGainChangeLock) { m_AttachedSoundGainChange -= value; } }
89 }
90  
91 /// <summary>The event subscribers, null of no subscribers</summary>
92 private EventHandler<SoundTriggerEventArgs> m_SoundTrigger;
93  
94 ///<summary>Raises the SoundTrigger Event</summary>
95 /// <param name="e">A SoundTriggerEventArgs object containing
96 /// the data sent from the simulator</param>
97 protected virtual void OnSoundTrigger(SoundTriggerEventArgs e)
98 {
99 EventHandler<SoundTriggerEventArgs> handler = m_SoundTrigger;
100 if (handler != null)
101 handler(this, e);
102 }
103  
104 /// <summary>Thread sync lock object</summary>
105 private readonly object m_SoundTriggerLock = new object();
106  
107 /// <summary>Raised when the simulator sends us data containing
108 /// ...</summary>
109 public event EventHandler<SoundTriggerEventArgs> SoundTrigger
110 {
111 add { lock (m_SoundTriggerLock) { m_SoundTrigger += value; } }
112 remove { lock (m_SoundTriggerLock) { m_SoundTrigger -= value; } }
113 }
114  
115 /// <summary>The event subscribers, null of no subscribers</summary>
116 private EventHandler<PreloadSoundEventArgs> m_PreloadSound;
117  
118 ///<summary>Raises the PreloadSound Event</summary>
119 /// <param name="e">A PreloadSoundEventArgs object containing
120 /// the data sent from the simulator</param>
121 protected virtual void OnPreloadSound(PreloadSoundEventArgs e)
122 {
123 EventHandler<PreloadSoundEventArgs> handler = m_PreloadSound;
124 if (handler != null)
125 handler(this, e);
126 }
127  
128 /// <summary>Thread sync lock object</summary>
129 private readonly object m_PreloadSoundLock = new object();
130  
131 /// <summary>Raised when the simulator sends us data containing
132 /// ...</summary>
133 public event EventHandler<PreloadSoundEventArgs> PreloadSound
134 {
135 add { lock (m_PreloadSoundLock) { m_PreloadSound += value; } }
136 remove { lock (m_PreloadSoundLock) { m_PreloadSound -= value; } }
137 }
138  
139 #endregion
140  
141 /// <summary>
142 /// Construct a new instance of the SoundManager class, used for playing and receiving
143 /// sound assets
144 /// </summary>
145 /// <param name="client">A reference to the current GridClient instance</param>
146 public SoundManager(GridClient client)
147 {
148 Client = client;
149  
150 Client.Network.RegisterCallback(PacketType.AttachedSound, AttachedSoundHandler);
151 Client.Network.RegisterCallback(PacketType.AttachedSoundGainChange, AttachedSoundGainChangeHandler);
152 Client.Network.RegisterCallback(PacketType.PreloadSound, PreloadSoundHandler);
153 Client.Network.RegisterCallback(PacketType.SoundTrigger, SoundTriggerHandler);
154 }
155  
156 #region public methods
157  
158 /// <summary>
159 /// Plays a sound in the current region at full volume from avatar position
160 /// </summary>
161 /// <param name="soundID">UUID of the sound to be played</param>
162 public void PlaySound(UUID soundID)
163 {
164 SendSoundTrigger(soundID, Client.Self.SimPosition, 1.0f);
165 }
166  
167 /// <summary>
168 /// Plays a sound in the current region at full volume
169 /// </summary>
170 /// <param name="soundID">UUID of the sound to be played.</param>
171 /// <param name="position">position for the sound to be played at. Normally the avatar.</param>
172 public void SendSoundTrigger(UUID soundID, Vector3 position)
173 {
174 SendSoundTrigger(soundID, Client.Self.SimPosition, 1.0f);
175 }
176  
177 /// <summary>
178 /// Plays a sound in the current region
179 /// </summary>
180 /// <param name="soundID">UUID of the sound to be played.</param>
181 /// <param name="position">position for the sound to be played at. Normally the avatar.</param>
182 /// <param name="gain">volume of the sound, from 0.0 to 1.0</param>
183 public void SendSoundTrigger(UUID soundID, Vector3 position, float gain)
184 {
185 SendSoundTrigger(soundID, Client.Network.CurrentSim.Handle, position, gain);
186 }
187 /// <summary>
188 /// Plays a sound in the specified sim
189 /// </summary>
190 /// <param name="soundID">UUID of the sound to be played.</param>
191 /// <param name="sim">UUID of the sound to be played.</param>
192 /// <param name="position">position for the sound to be played at. Normally the avatar.</param>
193 /// <param name="gain">volume of the sound, from 0.0 to 1.0</param>
194 public void SendSoundTrigger(UUID soundID, Simulator sim, Vector3 position, float gain)
195 {
196 SendSoundTrigger(soundID, sim.Handle, position, gain);
197 }
198  
199 /// <summary>
200 /// Play a sound asset
201 /// </summary>
202 /// <param name="soundID">UUID of the sound to be played.</param>
203 /// <param name="handle">handle id for the sim to be played in.</param>
204 /// <param name="position">position for the sound to be played at. Normally the avatar.</param>
205 /// <param name="gain">volume of the sound, from 0.0 to 1.0</param>
206 public void SendSoundTrigger(UUID soundID, ulong handle, Vector3 position, float gain)
207 {
208 SoundTriggerPacket soundtrigger = new SoundTriggerPacket();
209 soundtrigger.SoundData = new SoundTriggerPacket.SoundDataBlock();
210 soundtrigger.SoundData.SoundID = soundID;
211 soundtrigger.SoundData.ObjectID = UUID.Zero;
212 soundtrigger.SoundData.OwnerID = UUID.Zero;
213 soundtrigger.SoundData.ParentID = UUID.Zero;
214 soundtrigger.SoundData.Handle = handle;
215 soundtrigger.SoundData.Position = position;
216 soundtrigger.SoundData.Gain = gain;
217  
218 Client.Network.SendPacket(soundtrigger);
219 }
220  
221 #endregion
222 #region Packet Handlers
223  
224  
225 /// <summary>Process an incoming packet and raise the appropriate events</summary>
226 /// <param name="sender">The sender</param>
227 /// <param name="e">The EventArgs object containing the packet data</param>
228 protected void AttachedSoundHandler(object sender, PacketReceivedEventArgs e)
229 {
230 if (m_AttachedSound != null)
231 {
232 AttachedSoundPacket sound = (AttachedSoundPacket)e.Packet;
233  
234 OnAttachedSound(new AttachedSoundEventArgs(e.Simulator, sound.DataBlock.SoundID, sound.DataBlock.OwnerID, sound.DataBlock.ObjectID,
235 sound.DataBlock.Gain, (SoundFlags)sound.DataBlock.Flags));
236 }
237 }
238  
239 /// <summary>Process an incoming packet and raise the appropriate events</summary>
240 /// <param name="sender">The sender</param>
241 /// <param name="e">The EventArgs object containing the packet data</param>
242 protected void AttachedSoundGainChangeHandler(object sender, PacketReceivedEventArgs e)
243 {
244 if (m_AttachedSoundGainChange != null)
245 {
246 AttachedSoundGainChangePacket change = (AttachedSoundGainChangePacket)e.Packet;
247 OnAttachedSoundGainChange(new AttachedSoundGainChangeEventArgs(e.Simulator, change.DataBlock.ObjectID, change.DataBlock.Gain));
248 }
249 }
250  
251 /// <summary>Process an incoming packet and raise the appropriate events</summary>
252 /// <param name="sender">The sender</param>
253 /// <param name="e">The EventArgs object containing the packet data</param>
254 protected void PreloadSoundHandler(object sender, PacketReceivedEventArgs e)
255 {
256 if (m_PreloadSound != null)
257 {
258 PreloadSoundPacket preload = (PreloadSoundPacket)e.Packet;
259  
260 foreach (PreloadSoundPacket.DataBlockBlock data in preload.DataBlock)
261 {
262 OnPreloadSound(new PreloadSoundEventArgs(e.Simulator, data.SoundID, data.OwnerID, data.ObjectID));
263 }
264 }
265 }
266  
267 /// <summary>Process an incoming packet and raise the appropriate events</summary>
268 /// <param name="sender">The sender</param>
269 /// <param name="e">The EventArgs object containing the packet data</param>
270 protected void SoundTriggerHandler(object sender, PacketReceivedEventArgs e)
271 {
272 if (m_SoundTrigger != null)
273 {
274 SoundTriggerPacket trigger = (SoundTriggerPacket)e.Packet;
275 OnSoundTrigger(new SoundTriggerEventArgs(e.Simulator,
276 trigger.SoundData.SoundID,
277 trigger.SoundData.OwnerID,
278 trigger.SoundData.ObjectID,
279 trigger.SoundData.ParentID,
280 trigger.SoundData.Gain,
281 trigger.SoundData.Handle,
282 trigger.SoundData.Position));
283 }
284 }
285  
286 #endregion
287 }
288 #region EventArgs
289  
290 /// <summary>Provides data for the <see cref="SoundManager.AttachedSound"/> event</summary>
291 /// <remarks>The <see cref="SoundManager.AttachedSound"/> event occurs when the simulator sends
292 /// the sound data which emits from an agents attachment</remarks>
293 /// <example>
294 /// The following code example shows the process to subscribe to the <see cref="SoundManager.AttachedSound"/> event
295 /// and a stub to handle the data passed from the simulator
296 /// <code>
297 /// // Subscribe to the AttachedSound event
298 /// Client.Sound.AttachedSound += Sound_AttachedSound;
299 ///
300 /// // process the data raised in the event here
301 /// private void Sound_AttachedSound(object sender, AttachedSoundEventArgs e)
302 /// {
303 /// // ... Process AttachedSoundEventArgs here ...
304 /// }
305 /// </code>
306 /// </example>
307 public class AttachedSoundEventArgs : EventArgs
308 {
309 private readonly Simulator m_Simulator;
310 private readonly UUID m_SoundID;
311 private readonly UUID m_OwnerID;
312 private readonly UUID m_ObjectID;
313 private readonly float m_Gain;
314 private readonly SoundFlags m_Flags;
315  
316 /// <summary>Simulator where the event originated</summary>
317 public Simulator Simulator { get { return m_Simulator; } }
318 /// <summary>Get the sound asset id</summary>
319 public UUID SoundID { get { return m_SoundID; } }
320 /// <summary>Get the ID of the owner</summary>
321 public UUID OwnerID { get { return m_OwnerID; } }
322 /// <summary>Get the ID of the Object</summary>
323 public UUID ObjectID { get { return m_ObjectID; } }
324 /// <summary>Get the volume level</summary>
325 public float Gain { get { return m_Gain; } }
326 /// <summary>Get the <see cref="SoundFlags"/></summary>
327 public SoundFlags Flags { get { return m_Flags; } }
328  
329 /// <summary>
330 /// Construct a new instance of the SoundTriggerEventArgs class
331 /// </summary>
332 /// <param name="sim">Simulator where the event originated</param>
333 /// <param name="soundID">The sound asset id</param>
334 /// <param name="ownerID">The ID of the owner</param>
335 /// <param name="objectID">The ID of the object</param>
336 /// <param name="gain">The volume level</param>
337 /// <param name="flags">The <see cref="SoundFlags"/></param>
338 public AttachedSoundEventArgs(Simulator sim, UUID soundID, UUID ownerID, UUID objectID, float gain, SoundFlags flags)
339 {
340 this.m_Simulator = sim;
341 this.m_SoundID = soundID;
342 this.m_OwnerID = ownerID;
343 this.m_ObjectID = objectID;
344 this.m_Gain = gain;
345 this.m_Flags = flags;
346 }
347 }
348  
349 /// <summary>Provides data for the <see cref="SoundManager.AttachedSoundGainChange"/> event</summary>
350 /// <remarks>The <see cref="SoundManager.AttachedSoundGainChange"/> event occurs when an attached sound
351 /// changes its volume level</remarks>
352 public class AttachedSoundGainChangeEventArgs : EventArgs
353 {
354 private readonly Simulator m_Simulator;
355 private readonly UUID m_ObjectID;
356 private readonly float m_Gain;
357  
358 /// <summary>Simulator where the event originated</summary>
359 public Simulator Simulator { get { return m_Simulator; } }
360 /// <summary>Get the ID of the Object</summary>
361 public UUID ObjectID { get { return m_ObjectID; } }
362 /// <summary>Get the volume level</summary>
363 public float Gain { get { return m_Gain; } }
364  
365 /// <summary>
366 /// Construct a new instance of the AttachedSoundGainChangedEventArgs class
367 /// </summary>
368 /// <param name="sim">Simulator where the event originated</param>
369 /// <param name="objectID">The ID of the Object</param>
370 /// <param name="gain">The new volume level</param>
371 public AttachedSoundGainChangeEventArgs(Simulator sim, UUID objectID, float gain)
372 {
373 this.m_Simulator = sim;
374 this.m_ObjectID = objectID;
375 this.m_Gain = gain;
376 }
377 }
378  
379 /// <summary>Provides data for the <see cref="SoundManager.SoundTrigger"/> event</summary>
380 /// <remarks><para>The <see cref="SoundManager.SoundTrigger"/> event occurs when the simulator forwards
381 /// a request made by yourself or another agent to play either an asset sound or a built in sound</para>
382 ///
383 /// <para>Requests to play sounds where the <see cref="SoundTriggerEventArgs.SoundID"/> is not one of the built-in
384 /// <see cref="Sounds"/> will require sending a request to download the sound asset before it can be played</para>
385 /// </remarks>
386 /// <example>
387 /// The following code example uses the <see cref="SoundTriggerEventArgs.OwnerID"/>, <see cref="SoundTriggerEventArgs.SoundID"/>
388 /// and <see cref="SoundTriggerEventArgs.Gain"/>
389 /// properties to display some information on a sound request on the <see cref="Console"/> window.
390 /// <code>
391 /// // subscribe to the event
392 /// Client.Sound.SoundTrigger += Sound_SoundTrigger;
393 ///
394 /// // play the pre-defined BELL_TING sound
395 /// Client.Sound.SendSoundTrigger(Sounds.BELL_TING);
396 ///
397 /// // handle the response data
398 /// private void Sound_SoundTrigger(object sender, SoundTriggerEventArgs e)
399 /// {
400 /// Console.WriteLine("{0} played the sound {1} at volume {2}",
401 /// e.OwnerID, e.SoundID, e.Gain);
402 /// }
403 /// </code>
404 /// </example>
405 public class SoundTriggerEventArgs : EventArgs
406 {
407 private readonly Simulator m_Simulator;
408 private readonly UUID m_SoundID;
409 private readonly UUID m_OwnerID;
410 private readonly UUID m_ObjectID;
411 private readonly UUID m_ParentID;
412 private readonly float m_Gain;
413 private readonly ulong m_RegionHandle;
414 private readonly Vector3 m_Position;
415  
416 /// <summary>Simulator where the event originated</summary>
417 public Simulator Simulator { get { return m_Simulator; } }
418 /// <summary>Get the sound asset id</summary>
419 public UUID SoundID { get { return m_SoundID; } }
420 /// <summary>Get the ID of the owner</summary>
421 public UUID OwnerID { get { return m_OwnerID; } }
422 /// <summary>Get the ID of the Object</summary>
423 public UUID ObjectID { get { return m_ObjectID; } }
424 /// <summary>Get the ID of the objects parent</summary>
425 public UUID ParentID { get { return m_ParentID; } }
426 /// <summary>Get the volume level</summary>
427 public float Gain { get { return m_Gain; } }
428 /// <summary>Get the regionhandle</summary>
429 public ulong RegionHandle { get { return m_RegionHandle; } }
430 /// <summary>Get the source position</summary>
431 public Vector3 Position { get { return m_Position; } }
432  
433 /// <summary>
434 /// Construct a new instance of the SoundTriggerEventArgs class
435 /// </summary>
436 /// <param name="sim">Simulator where the event originated</param>
437 /// <param name="soundID">The sound asset id</param>
438 /// <param name="ownerID">The ID of the owner</param>
439 /// <param name="objectID">The ID of the object</param>
440 /// <param name="parentID">The ID of the objects parent</param>
441 /// <param name="gain">The volume level</param>
442 /// <param name="regionHandle">The regionhandle</param>
443 /// <param name="position">The source position</param>
444 public SoundTriggerEventArgs(Simulator sim, UUID soundID, UUID ownerID, UUID objectID, UUID parentID, float gain, ulong regionHandle, Vector3 position)
445 {
446 this.m_Simulator = sim;
447 this.m_SoundID = soundID;
448 this.m_OwnerID = ownerID;
449 this.m_ObjectID = objectID;
450 this.m_ParentID = parentID;
451 this.m_Gain = gain;
452 this.m_RegionHandle = regionHandle;
453 this.m_Position = position;
454 }
455 }
456  
457 /// <summary>Provides data for the <see cref="AvatarManager.AvatarAppearance"/> event</summary>
458 /// <remarks>The <see cref="AvatarManager.AvatarAppearance"/> event occurs when the simulator sends
459 /// the appearance data for an avatar</remarks>
460 /// <example>
461 /// The following code example uses the <see cref="AvatarAppearanceEventArgs.AvatarID"/> and <see cref="AvatarAppearanceEventArgs.VisualParams"/>
462 /// properties to display the selected shape of an avatar on the <see cref="Console"/> window.
463 /// <code>
464 /// // subscribe to the event
465 /// Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance;
466 ///
467 /// // handle the data when the event is raised
468 /// void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e)
469 /// {
470 /// Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] &gt; 0) : "male" ? "female")
471 /// }
472 /// </code>
473 /// </example>
474 public class PreloadSoundEventArgs : EventArgs
475 {
476 private readonly Simulator m_Simulator;
477 private readonly UUID m_SoundID;
478 private readonly UUID m_OwnerID;
479 private readonly UUID m_ObjectID;
480  
481 /// <summary>Simulator where the event originated</summary>
482 public Simulator Simulator { get { return m_Simulator; } }
483 /// <summary>Get the sound asset id</summary>
484 public UUID SoundID { get { return m_SoundID; } }
485 /// <summary>Get the ID of the owner</summary>
486 public UUID OwnerID { get { return m_OwnerID; } }
487 /// <summary>Get the ID of the Object</summary>
488 public UUID ObjectID { get { return m_ObjectID; } }
489  
490 /// <summary>
491 /// Construct a new instance of the PreloadSoundEventArgs class
492 /// </summary>
493 /// <param name="sim">Simulator where the event originated</param>
494 /// <param name="soundID">The sound asset id</param>
495 /// <param name="ownerID">The ID of the owner</param>
496 /// <param name="objectID">The ID of the object</param>
497 public PreloadSoundEventArgs(Simulator sim, UUID soundID, UUID ownerID, UUID objectID)
498 {
499 this.m_Simulator = sim;
500 this.m_SoundID = soundID;
501 this.m_OwnerID = ownerID;
502 this.m_ObjectID = objectID;
503 }
504 }
505 #endregion
506 }