29
									
								
								event-queue/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								event-queue/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
---
 | 
			
		||||
layout: pattern
 | 
			
		||||
title: Event Queue
 | 
			
		||||
folder: event-queue
 | 
			
		||||
permalink: /patterns/event-queue/
 | 
			
		||||
categories: Concurrency
 | 
			
		||||
tags:
 | 
			
		||||
 - Java
 | 
			
		||||
 - Difficulty Intermediate
 | 
			
		||||
 - Queue
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## Intent
 | 
			
		||||
Event Queue is a good pattern if You have a limited accesibility resource (for example: 
 | 
			
		||||
Audio or Database), but You need to handle all the requests that want to use that.
 | 
			
		||||
It puts all the requests in a queue and process them asynchronously.
 | 
			
		||||
Gives the resource for the event when it is the next in the queue and in same time
 | 
			
		||||
removes it from the queue.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## Applicability
 | 
			
		||||
Use the Event Queue pattern when
 | 
			
		||||
 | 
			
		||||
* You have a limited accesibility resource and the asynchronous process is acceptable to reach that
 | 
			
		||||
 | 
			
		||||
## Credits
 | 
			
		||||
 | 
			
		||||
* [Mihaly Kuprivecz - Event Queue] (http://gameprogrammingpatterns.com/event-queue.html)
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								event-queue/etc/Bass-Drum-1.aif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								event-queue/etc/Bass-Drum-1.aif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								event-queue/etc/Bass-Drum-1.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								event-queue/etc/Bass-Drum-1.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								event-queue/etc/Closed-Hi-Hat-1.aif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								event-queue/etc/Closed-Hi-Hat-1.aif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								event-queue/etc/Closed-Hi-Hat-1.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								event-queue/etc/Closed-Hi-Hat-1.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										26
									
								
								event-queue/etc/event-queue.urm.puml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								event-queue/etc/event-queue.urm.puml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
@startuml
 | 
			
		||||
package com.iluwatar.event.queue {
 | 
			
		||||
  class App {
 | 
			
		||||
    + App()
 | 
			
		||||
    + getAudioStream(filePath : String) : AudioInputStream {static}
 | 
			
		||||
    + main(args : String[]) {static}
 | 
			
		||||
  }
 | 
			
		||||
  class Audio {
 | 
			
		||||
    - MAX_PENDING : int {static}
 | 
			
		||||
    - headIndex : int {static}
 | 
			
		||||
    - pendingAudio : PlayMessage[] {static}
 | 
			
		||||
    - tailIndex : int {static}
 | 
			
		||||
    - updateThread : Thread {static}
 | 
			
		||||
    + Audio()
 | 
			
		||||
    + init() {static}
 | 
			
		||||
    + playSound(stream : AudioInputStream, volume : float) {static}
 | 
			
		||||
    + stopService() {static}
 | 
			
		||||
    + update() {static}
 | 
			
		||||
  }
 | 
			
		||||
  class PlayMessage {
 | 
			
		||||
    ~ stream : AudioInputStream
 | 
			
		||||
    ~ volume : float
 | 
			
		||||
    + PlayMessage()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@enduml
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								event-queue/etc/model.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								event-queue/etc/model.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 17 KiB  | 
							
								
								
									
										36
									
								
								event-queue/etc/model.ucls
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								event-queue/etc/model.ucls
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<class-diagram version="1.2.0" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true" 
 | 
			
		||||
  realizations="true" associations="true" dependencies="false" nesting-relationships="true" router="FAN">  
 | 
			
		||||
  <class id="1" language="java" name="com.iluwatar.event.queue.Audio" project="event-queue" 
 | 
			
		||||
    file="/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java" binary="false" corner="BOTTOM_RIGHT">    
 | 
			
		||||
    <position height="-1" width="-1" x="285" y="179"/>    
 | 
			
		||||
    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
 | 
			
		||||
      sort-features="false" accessors="true" visibility="true">      
 | 
			
		||||
      <attributes public="true" package="true" protected="true" private="true" static="true"/>      
 | 
			
		||||
      <operations public="true" package="true" protected="true" private="true" static="true"/>    
 | 
			
		||||
    </display>  
 | 
			
		||||
  </class>  
 | 
			
		||||
  <class id="2" language="java" name="com.iluwatar.event.queue.PlayMessage" project="event-queue" 
 | 
			
		||||
    file="/event-queue/src/main/java/com/iluwatar/event/queue/PlayMessage.java" binary="false" corner="BOTTOM_RIGHT">    
 | 
			
		||||
    <position height="-1" width="-1" x="633" y="179"/>    
 | 
			
		||||
    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
 | 
			
		||||
      sort-features="false" accessors="true" visibility="true">      
 | 
			
		||||
      <attributes public="true" package="true" protected="true" private="true" static="true"/>      
 | 
			
		||||
      <operations public="true" package="true" protected="true" private="true" static="true"/>    
 | 
			
		||||
    </display>  
 | 
			
		||||
  </class>  
 | 
			
		||||
  <association id="3">    
 | 
			
		||||
    <end type="SOURCE" refId="1" navigable="false">      
 | 
			
		||||
      <attribute id="4" name="pendingAudio"/>      
 | 
			
		||||
      <multiplicity id="5" minimum="0" maximum="2147483647"/>    
 | 
			
		||||
    </end>    
 | 
			
		||||
    <end type="TARGET" refId="2" navigable="true"/>    
 | 
			
		||||
    <display labels="true" multiplicity="true"/>  
 | 
			
		||||
  </association>  
 | 
			
		||||
  <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
 | 
			
		||||
    sort-features="false" accessors="true" visibility="true">    
 | 
			
		||||
    <attributes public="true" package="true" protected="true" private="true" static="true"/>    
 | 
			
		||||
    <operations public="true" package="true" protected="true" private="true" static="true"/>  
 | 
			
		||||
  </classifier-display>  
 | 
			
		||||
  <association-display labels="true" multiplicity="true"/>
 | 
			
		||||
</class-diagram>
 | 
			
		||||
							
								
								
									
										43
									
								
								event-queue/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								event-queue/pom.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!--
 | 
			
		||||
 | 
			
		||||
    The MIT License
 | 
			
		||||
    Copyright (c) 2014-2016 Ilkka Sepp<70>l<EFBFBD>
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
    of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
    in the Software without restriction, including without limitation the rights
 | 
			
		||||
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
    copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
    furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be included in
 | 
			
		||||
    all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
    THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
  <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
  <parent>
 | 
			
		||||
    <artifactId>java-design-patterns</artifactId>
 | 
			
		||||
    <groupId>com.iluwatar</groupId>
 | 
			
		||||
    <version>1.16.0-SNAPSHOT</version>
 | 
			
		||||
  </parent>
 | 
			
		||||
  <artifactId>event-queue</artifactId>
 | 
			
		||||
  <dependencies>
 | 
			
		||||
    <dependency>
 | 
			
		||||
      <groupId>junit</groupId>
 | 
			
		||||
      <artifactId>junit</artifactId>
 | 
			
		||||
      <scope>test</scope>
 | 
			
		||||
    </dependency>
 | 
			
		||||
  </dependencies>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										59
									
								
								event-queue/src/main/java/com/iluwatar/event/queue/App.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								event-queue/src/main/java/com/iluwatar/event/queue/App.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/**
 | 
			
		||||
 * The MIT License
 | 
			
		||||
 * Copyright (c) 2014-2016 Ilkka Seppälä
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.event.queue;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
 | 
			
		||||
import javax.sound.sampled.UnsupportedAudioFileException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Event or message queues provide an asynchronous communications protocol, meaning that the sender
 | 
			
		||||
 * and receiver of the message do not need to interact with the message queue at the same time. 
 | 
			
		||||
 * Events or messages placed onto the queue are stored until the recipient retrieves them. Event 
 | 
			
		||||
 * or message queues have implicit or explicit limits on the size of data that may be transmitted
 | 
			
		||||
 * in a single message and the number of messages that may remain outstanding on the queue.
 | 
			
		||||
 * A queue stores a series of notifications or requests in first-in, first-out order.
 | 
			
		||||
 * Sending a notification enqueues the request and returns. The request processor then processes
 | 
			
		||||
 * items from the queue at a later time.
 | 
			
		||||
 */
 | 
			
		||||
public class App {
 | 
			
		||||
  /**
 | 
			
		||||
   * Program entry point.
 | 
			
		||||
   * 
 | 
			
		||||
   * @param args command line args
 | 
			
		||||
   * @throws IOException when there is a problem with the audio file loading
 | 
			
		||||
   * @throws UnsupportedAudioFileException  when the loaded audio file is unsupported 
 | 
			
		||||
   */
 | 
			
		||||
  public static void main(String[] args) throws UnsupportedAudioFileException, IOException {
 | 
			
		||||
    Audio.playSound(Audio.getAudioStream("./etc/Bass-Drum-1.wav"), -10.0f);
 | 
			
		||||
    Audio.playSound(Audio.getAudioStream("./etc/Closed-Hi-Hat-1.wav"), -8.0f);
 | 
			
		||||
    
 | 
			
		||||
    System.out.println("Press Enter key to stop the program...");
 | 
			
		||||
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 | 
			
		||||
    br.read();
 | 
			
		||||
    Audio.stopService();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								event-queue/src/main/java/com/iluwatar/event/queue/Audio.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								event-queue/src/main/java/com/iluwatar/event/queue/Audio.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
/**
 | 
			
		||||
 * The MIT License
 | 
			
		||||
 * Copyright (c) 2014-2016 Ilkka Seppälä
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.event.queue;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import javax.sound.sampled.AudioInputStream;
 | 
			
		||||
import javax.sound.sampled.AudioSystem;
 | 
			
		||||
import javax.sound.sampled.Clip;
 | 
			
		||||
import javax.sound.sampled.LineUnavailableException;
 | 
			
		||||
import javax.sound.sampled.UnsupportedAudioFileException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class implements the Event Queue pattern.
 | 
			
		||||
 * @author mkuprivecz
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class Audio {
 | 
			
		||||
 | 
			
		||||
  private static final int MAX_PENDING = 16;
 | 
			
		||||
 | 
			
		||||
  private static int headIndex;
 | 
			
		||||
 | 
			
		||||
  private static int tailIndex;
 | 
			
		||||
 | 
			
		||||
  private static Thread updateThread = null;
 | 
			
		||||
 | 
			
		||||
  private static PlayMessage[] pendingAudio = new PlayMessage[MAX_PENDING];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method stops the Update Method's thread. 
 | 
			
		||||
   */
 | 
			
		||||
  public static synchronized void stopService() {
 | 
			
		||||
    if (updateThread != null) {
 | 
			
		||||
      updateThread.interrupt();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * This method stops the Update Method's thread. 
 | 
			
		||||
   * @return boolean
 | 
			
		||||
   */
 | 
			
		||||
  public static synchronized boolean isServiceRunning() {
 | 
			
		||||
    if (updateThread != null && updateThread.isAlive() ) {
 | 
			
		||||
      return true;
 | 
			
		||||
    } else {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Starts the thread for the Update Method pattern if it was not started previously.
 | 
			
		||||
   * Also when the thread is is ready initializes the indexes of the queue 
 | 
			
		||||
   */
 | 
			
		||||
  public static void init() {
 | 
			
		||||
    if (updateThread == null) {
 | 
			
		||||
      updateThread = new Thread(new Runnable() {
 | 
			
		||||
        public void run() {
 | 
			
		||||
          while (!Thread.currentThread().isInterrupted()) {
 | 
			
		||||
            Audio.update();
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    startThread();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * This is a synchronized thread starter
 | 
			
		||||
   */
 | 
			
		||||
  public static synchronized void startThread() {
 | 
			
		||||
    if (!updateThread.isAlive()) {
 | 
			
		||||
      updateThread.start();
 | 
			
		||||
      headIndex = 0;
 | 
			
		||||
      tailIndex = 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method adds a new audio into the queue.
 | 
			
		||||
   * @param stream is the AudioInputStream for the method
 | 
			
		||||
   * @param volume is the level of the audio's volume 
 | 
			
		||||
   */
 | 
			
		||||
  public static void playSound(AudioInputStream stream, float volume) {
 | 
			
		||||
    init();
 | 
			
		||||
    // Walk the pending requests.
 | 
			
		||||
    for (int i = headIndex; i != tailIndex; i = (i + 1) % MAX_PENDING) {
 | 
			
		||||
      if (getPendingAudio()[i].getStream() == stream) {
 | 
			
		||||
        // Use the larger of the two volumes.
 | 
			
		||||
        getPendingAudio()[i].setVolume(Math.max(volume, getPendingAudio()[i].getVolume()));
 | 
			
		||||
 | 
			
		||||
        // Don't need to enqueue.
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    getPendingAudio()[tailIndex] = new PlayMessage(stream, volume);
 | 
			
		||||
    tailIndex = (tailIndex + 1) % MAX_PENDING;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * This method uses the Update Method pattern.
 | 
			
		||||
   * It takes the audio from the queue and plays it
 | 
			
		||||
   */
 | 
			
		||||
  public static void update() {
 | 
			
		||||
    // If there are no pending requests, do nothing.
 | 
			
		||||
    if (headIndex == tailIndex) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    Clip clip = null;
 | 
			
		||||
    try {
 | 
			
		||||
      AudioInputStream audioStream = getPendingAudio()[headIndex].getStream();
 | 
			
		||||
      headIndex++;
 | 
			
		||||
      clip = AudioSystem.getClip();
 | 
			
		||||
      clip.open(audioStream);
 | 
			
		||||
      clip.start();
 | 
			
		||||
    } catch (LineUnavailableException e) {
 | 
			
		||||
      System.err.println("Error occoured while loading the audio: The line is unavailable");
 | 
			
		||||
      e.printStackTrace();
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      System.err.println("Input/Output error while loading the audio");
 | 
			
		||||
      e.printStackTrace();
 | 
			
		||||
    } catch (IllegalArgumentException e) {
 | 
			
		||||
      System.err.println("The system doesn't support the sound: " + e.getMessage());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the AudioInputStream of a file
 | 
			
		||||
   * @param filePath is the path of the audio file
 | 
			
		||||
   * @return AudioInputStream
 | 
			
		||||
   * @throws UnsupportedAudioFileException when the audio file is not supported 
 | 
			
		||||
   * @throws IOException when the file is not readable
 | 
			
		||||
   */
 | 
			
		||||
  public static AudioInputStream getAudioStream(String filePath) 
 | 
			
		||||
      throws UnsupportedAudioFileException, IOException {
 | 
			
		||||
    return AudioSystem.getAudioInputStream(new File(filePath).getAbsoluteFile());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns with the message array of the queue 
 | 
			
		||||
   * @return PlayMessage[]
 | 
			
		||||
   */
 | 
			
		||||
  public static PlayMessage[] getPendingAudio() {
 | 
			
		||||
    return pendingAudio;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,59 @@
 | 
			
		||||
/**
 | 
			
		||||
 * The MIT License
 | 
			
		||||
 * Copyright (c) 2014-2016 Ilkka Seppälä
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.event.queue;
 | 
			
		||||
 | 
			
		||||
import javax.sound.sampled.AudioInputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The Event Queue's queue will store the instances of this class.
 | 
			
		||||
 * @author mkuprivecz
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class PlayMessage {
 | 
			
		||||
  
 | 
			
		||||
  private AudioInputStream stream;
 | 
			
		||||
  
 | 
			
		||||
  private float volume;
 | 
			
		||||
  
 | 
			
		||||
  public PlayMessage(AudioInputStream stream, float volume) {
 | 
			
		||||
    setStream(stream);
 | 
			
		||||
    setVolume(volume);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public AudioInputStream getStream() {
 | 
			
		||||
    return stream;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void setStream(AudioInputStream stream) {
 | 
			
		||||
    this.stream = stream;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public float getVolume() {
 | 
			
		||||
    return volume;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void setVolume(float volume) {
 | 
			
		||||
    this.volume = volume;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
/**
 | 
			
		||||
 * The MIT License
 | 
			
		||||
 * Copyright (c) 2014-2016 Ilkka Seppälä
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.event.queue;
 | 
			
		||||
import static org.junit.Assert.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import javax.sound.sampled.UnsupportedAudioFileException;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Testing the Audio service of the Queue
 | 
			
		||||
 * @author mkuprivecz
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class AudioTest {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test here that the playSound method works correctly
 | 
			
		||||
   * @throws UnsupportedAudioFileException when the audio file is not supported 
 | 
			
		||||
   * @throws IOException when the file is not readable
 | 
			
		||||
   * @throws InterruptedException when the test is interrupted externally
 | 
			
		||||
   */
 | 
			
		||||
  @Test
 | 
			
		||||
  public void testPlaySound() throws UnsupportedAudioFileException, IOException, InterruptedException {
 | 
			
		||||
    Audio.playSound(Audio.getAudioStream("./etc/Bass-Drum-1.wav"), -10.0f);
 | 
			
		||||
    // test that service is started
 | 
			
		||||
    assertTrue(Audio.isServiceRunning());
 | 
			
		||||
    // adding a small pause to be sure that the sound is ended
 | 
			
		||||
    Thread.sleep(5000);
 | 
			
		||||
    // test that service is finished
 | 
			
		||||
    assertFalse(!Audio.isServiceRunning());
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Test here that the Queue
 | 
			
		||||
   * @throws UnsupportedAudioFileException when the audio file is not supported 
 | 
			
		||||
   * @throws IOException when the file is not readable
 | 
			
		||||
   * @throws InterruptedException when the test is interrupted externally
 | 
			
		||||
   */
 | 
			
		||||
  @Test
 | 
			
		||||
  public void testQueue() throws UnsupportedAudioFileException, IOException, InterruptedException {
 | 
			
		||||
    Audio.playSound(Audio.getAudioStream("./etc/Bass-Drum-1.aif"), -10.0f);
 | 
			
		||||
    Audio.playSound(Audio.getAudioStream("./etc/Bass-Drum-1.aif"), -10.0f);
 | 
			
		||||
    Audio.playSound(Audio.getAudioStream("./etc/Bass-Drum-1.aif"), -10.0f);
 | 
			
		||||
    assertTrue(Audio.getPendingAudio().length > 0);
 | 
			
		||||
    // test that service is started
 | 
			
		||||
    assertTrue(Audio.isServiceRunning());
 | 
			
		||||
    // adding a small pause to be sure that the sound is ended
 | 
			
		||||
    Thread.sleep(10000);
 | 
			
		||||
    // test that service is finished
 | 
			
		||||
    assertFalse(!Audio.isServiceRunning());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								pom.xml
									
									
									
									
									
								
							@@ -122,7 +122,7 @@
 | 
			
		||||
        <module>factory-kit</module>
 | 
			
		||||
        <module>feature-toggle</module>
 | 
			
		||||
        <module>value-object</module>
 | 
			
		||||
		    <module>module</module>
 | 
			
		||||
        <module>module</module>
 | 
			
		||||
        <module>monad</module>
 | 
			
		||||
        <module>mute-idiom</module>
 | 
			
		||||
        <module>mutex</module>
 | 
			
		||||
@@ -133,6 +133,7 @@
 | 
			
		||||
        <module>promise</module>
 | 
			
		||||
        <module>page-object</module>
 | 
			
		||||
        <module>event-asynchronous</module>
 | 
			
		||||
        <module>event-queue</module>
 | 
			
		||||
        <module>queue-load-leveling</module>
 | 
			
		||||
        <module>object-mother</module>
 | 
			
		||||
        <module>data-bus</module>
 | 
			
		||||
@@ -302,23 +303,23 @@
 | 
			
		||||
                                    </action>
 | 
			
		||||
                                </pluginExecution>
 | 
			
		||||
                                <pluginExecution>
 | 
			
		||||
                                	<pluginExecutionFilter>
 | 
			
		||||
                                		<groupId>
 | 
			
		||||
                                			com.github.markusmo3.urm
 | 
			
		||||
                                		</groupId>
 | 
			
		||||
                                		<artifactId>
 | 
			
		||||
                                			urm-maven-plugin
 | 
			
		||||
                                		</artifactId>
 | 
			
		||||
                                		<versionRange>
 | 
			
		||||
                                			[1.4.1,)
 | 
			
		||||
                                		</versionRange>
 | 
			
		||||
                                		<goals>
 | 
			
		||||
                                			<goal>map</goal>
 | 
			
		||||
                                		</goals>
 | 
			
		||||
                                	</pluginExecutionFilter>
 | 
			
		||||
                                	<action>
 | 
			
		||||
                                		<ignore/>
 | 
			
		||||
                                	</action>
 | 
			
		||||
                                    <pluginExecutionFilter>
 | 
			
		||||
                                        <groupId>
 | 
			
		||||
                                            com.github.markusmo3.urm
 | 
			
		||||
                                        </groupId>
 | 
			
		||||
                                        <artifactId>
 | 
			
		||||
                                            urm-maven-plugin
 | 
			
		||||
                                        </artifactId>
 | 
			
		||||
                                        <versionRange>
 | 
			
		||||
                                            [1.4.1,)
 | 
			
		||||
                                        </versionRange>
 | 
			
		||||
                                        <goals>
 | 
			
		||||
                                            <goal>map</goal>
 | 
			
		||||
                                        </goals>
 | 
			
		||||
                                    </pluginExecutionFilter>
 | 
			
		||||
                                    <action>
 | 
			
		||||
                                        <ignore/>
 | 
			
		||||
                                    </action>
 | 
			
		||||
                                </pluginExecution>
 | 
			
		||||
                            </pluginExecutions>
 | 
			
		||||
                        </lifecycleMappingMetadata>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user