/**
* Copyright (c) 2005 - Bob Lang (http://www.cems.uwe.ac.uk/~lrlang/)
*
* http://www.frinika.com
*
* This file is part of Frinika.
*
* Frinika is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Frinika is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Frinika; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.frinika.contrib.boblang;
/**
Implements a thread safe circular buffer of commands with appropriate
notify and time out facilities.
@author Bob Lang
@version 15 Nov 2002
*/
public class CommandList {
// Exported constants
public static final int
NOTE_ON = 1, // Command code for note on
NOTE_OFF = 2; // Command code for note off
// Local constants
private static final int
MAX_COMMAND_LIST = 32; // Max number of stored commands
// Pointers and data counter
private int
putPointer, // Pointer to last command in list
getPointer, // Pointer to first command in list
counter; // Number of commands waiting
// Circular buffers
private int []
commandType = new int [MAX_COMMAND_LIST],
commandNote = new int [MAX_COMMAND_LIST];
// Dummy array used in getCommand ()
private int []
retVal = new int [2];
/**
Constructor to create an empty buffer
*/
public CommandList () {
putPointer = 0;
getPointer = 0;
counter = 0;
} // CommandList ()
/**
Put a command in the buffer and then notify any waiting
tasks.
*/
public synchronized void putCommand (int type, int note) {
// Incr put pointer and check for overflow
putPointer++;
if (putPointer >= MAX_COMMAND_LIST) {
putPointer = 0;
} // if
// Store the command in the buffer
commandType [putPointer] = type;
commandNote [putPointer] = note;
// Flag that there's more data waiting and notify waiters
counter++;
//notifyAll ();
} // putCommand ()
/**
Return true if a command is waiting in the command buffer
*/
public synchronized boolean isCommandWaiting (long waitMsecs) {
//try {
// wait (waitMsecs);
// }
//catch (Exception e) {
// System.out.println (e);
//}
// Return true if data in buffer
return (counter > 0);
} // isCommandWaiting ()
/**
Get the next command type and note from the buffer. It is assumed
that waitForCommand has been called prior to this method so that
it is known that there is data waiting to be taken
*/
public synchronized int [] getCommand () {
// Establish that there is data waiting
if (counter > 0) {
// Increment take pointer, dealing with overflow
getPointer++;
if (getPointer >= MAX_COMMAND_LIST) {
getPointer = 0;
} // if
// Extract the data
retVal [0] = commandType [getPointer];
retVal [1] = commandNote [getPointer];
// Backup the counter by one
counter--;
} // if
else {
// return null result
retVal [0] = 0;
retVal [1] = 0;
} // else
// Return the resulting data
return retVal;
} // getCommand ()
} // CommandList