00001 /* 00002 * WOscLib, an object oriented OSC library. 00003 * Copyright (C) 2005 Uli Clemens Franke, Weiss Engineering LTD, Switzerland. 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 * 00019 * For details see lgpl.txt 00020 * 00021 * Weiss Engineering LTD. 00022 * Florastrass 42 00023 * 8610 Uster 00024 * Switzerland 00025 * 00026 * uli.franke@weiss.ch 00027 */ 00028 00029 /** WOscQueueItem and WOscPriorityQueue source file. 00030 * \file 00031 * 00032 * $Author: cls-nebadje $ ( \ref _UcfWOscLib ) 00033 * $Date: 2006-03-20 20:31:47 $ 00034 * $Revision: 1.3 $ 00035 * 00036 * Copyright (c) Weiss Engineering Ltd 00037 * 00038 */ 00039 00040 #include "WOscPriorityQueue.h" 00041 #include "WOscException.h" 00042 00043 /* ----------------------------------------------------------------------- */ 00044 /* WOscPriorityQueue */ 00045 /* ----------------------------------------------------------------------- */ 00046 #if WOSC_USE_PRIORITY_QUEUE == 1 00047 /** Constructor. 00048 * Constructs an empty priority queue with a capacity of 00049 * "initialCapacity". 00050 * 00051 * \param initialCapacity 00052 * The initial capacity (how many items can be inserted until 00053 * doubleCapacity() will be called. 00054 * 00055 * \see 00056 * WOscPriorityQueue::doubleCapacity() 00057 */ 00058 WOscPriorityQueue::WOscPriorityQueue(int initialCapacity) 00059 { 00060 00061 /* allocate list (queue) */ 00062 m_listCapacity = initialCapacity; 00063 m_list = new WOscQueueItem*[initialCapacity]; 00064 00065 /* reset list (no items) */ 00066 for( int i = 0; i < initialCapacity; i++ ) 00067 m_list[i] = NULL; 00068 m_itemsInList = 0; 00069 00070 } 00071 00072 /** Destructor. 00073 * All elements which are not removed from the priority-queue 00074 * get deleted automatically. 00075 * 00076 */ 00077 WOscPriorityQueue::~WOscPriorityQueue() 00078 { 00079 00080 /* empty queue as long there are items in the queue*/ 00081 while( GetNumItems() > 0 ) 00082 delete RemoveEarliestItem(); 00083 00084 delete [] m_list; 00085 } 00086 00087 /** Inserts an item into the queue. 00088 * Items are simply inserted and not ordered. 00089 * 00090 * \remarks 00091 * WOscPriorityQueue::getEarliestTimeTag() then checks 00092 * the time-tags and returns the earliest. 00093 * 00094 */ 00095 void 00096 WOscPriorityQueue::InsertItem(WOscQueueItem *item) 00097 { 00098 00099 // check capacity, double if necessary 00100 if ( m_itemsInList == m_listCapacity ) 00101 DoubleCapacity(); 00102 00103 // insert pointer to element and increment population 00104 m_list[m_itemsInList++] = item; 00105 00106 } 00107 00108 /** Doubles the capacity of the queue. 00109 * If a new item is about to be inserted into the queue and the 00110 * capacity is exhausted, the insertion function doubles 00111 * the capacity. 00112 */ 00113 void 00114 WOscPriorityQueue::DoubleCapacity() 00115 { 00116 // allocate larger list 00117 int newListCapacity = 2 * m_listCapacity; 00118 WOscQueueItem** newList = new WOscQueueItem*[newListCapacity]; 00119 00120 // copy old elements 00121 int i = 0; 00122 for ( ; i < m_listCapacity; i++ ) 00123 newList[i] = m_list[i]; 00124 00125 // init new elements 00126 for ( ; i < newListCapacity; i++ ) 00127 newList[i] = NULL; 00128 00129 // activate new list and delete old 00130 delete [] m_list; 00131 m_list = newList; 00132 m_listCapacity = newListCapacity; 00133 } 00134 00135 /** Returns the timetag of the earliest item. 00136 * Searches by linearly traversing the queue. 00137 * 00138 * \returns 00139 * The time-tag of the earliest item. If no time-tag smaller 00140 * than WOscTimeTag::getLargestTimeTag() can be found 00141 * WOscTimeTag::getLargestTimeTag() will be returned. 00142 */ 00143 WOscTimeTag WOscPriorityQueue::GetEarliestTimeTag() 00144 { 00145 00146 WOscTimeTag smallest = WOscTimeTag::GetLargestTimeTag(); 00147 00148 for ( int i = 0; i < m_itemsInList; i++ ) 00149 if ( *m_list[i] < smallest ) 00150 smallest = *m_list[i]; 00151 00152 return smallest; 00153 } 00154 00155 /** Remove item with index idx from the queue. 00156 * Decrements the number of items contained in the queue. 00157 * 00158 * \param idx 00159 * Index of the item to be removed. 00160 */ 00161 void 00162 WOscPriorityQueue::RemoveItem(int idx) 00163 { 00164 00165 m_itemsInList--; 00166 00167 for ( int i = idx; i < m_itemsInList; i++ ) 00168 m_list[i] = m_list[i+1]; 00169 } 00170 00171 /** Removes the earliest item from the queue and returns it. 00172 * 00173 * \returns 00174 * The pointer to the earliest item removed from the queue. 00175 * 00176 * \throws WOscException 00177 * When trying to remove from an empty queue. 00178 * 00179 * \remarks 00180 * When removed, the user (caller) has to care about the 00181 * deletion of that element, since the queue is only an itermediate 00182 * buffer. When removed the queue does not know anything about this 00183 * object anymore. 00184 * 00185 */ 00186 WOscQueueItem* 00187 WOscPriorityQueue::RemoveEarliestItem() 00188 { 00189 00190 WOscQueueItem* result; 00191 00192 int smallestIdx = 0; 00193 00194 if ( m_itemsInList == 0 ) 00195 throw WOscException(ERR_REMOVE_FROM_EMPTY_QUEUE, __FILE__, __LINE__); 00196 00197 /* traverse the queue and */ 00198 for ( int i = 0; i < m_itemsInList; i++ ) 00199 /* compare time-tags */ 00200 if ( *m_list[smallestIdx] > *m_list[i] ) 00201 smallestIdx = i; 00202 00203 /* save pointer before removing it */ 00204 result = m_list[smallestIdx]; 00205 00206 RemoveItem(smallestIdx); 00207 00208 return result; 00209 } 00210 00211 /** Returns the number of items in the queue. 00212 * \returns 00213 * The number of items in the queue. 00214 */ 00215 int 00216 WOscPriorityQueue::GetNumItems() 00217 { 00218 return m_itemsInList; 00219 } 00220 00221 #endif // #if WOSC_USE_PRIORITY_QUEUE == 1