1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: LooperList.cpp 23 // Author(s): Erik Jaesler (erik@cgsoftware.com) 24 // Description: Maintains a global list of all loopers in a given team. 25 //------------------------------------------------------------------------------ 26 27 // Standard Includes ----------------------------------------------------------- 28 #include <algorithm> 29 30 // System Includes ------------------------------------------------------------- 31 #include <Autolock.h> 32 #include <Looper.h> 33 34 // Project Includes ------------------------------------------------------------ 35 36 // Local Includes -------------------------------------------------------------- 37 #include "LooperList.h" 38 39 // Local Defines --------------------------------------------------------------- 40 41 // Globals --------------------------------------------------------------------- 42 using std::vector; 43 44 namespace BPrivate { 45 46 BLooperList gLooperList; 47 48 typedef vector<BLooperList::LooperData>::iterator LDIter; 49 50 //------------------------------------------------------------------------------ 51 BLooperList::BLooperList() 52 : fLock("BLooperList lock"), 53 fLooperID(0) 54 { 55 } 56 //------------------------------------------------------------------------------ 57 bool BLooperList::Lock() 58 { 59 return fLock.Lock(); 60 } 61 //------------------------------------------------------------------------------ 62 void BLooperList::Unlock() 63 { 64 fLock.Unlock(); 65 } 66 //------------------------------------------------------------------------------ 67 bool BLooperList::IsLocked() 68 { 69 return fLock.IsLocked(); 70 } 71 //------------------------------------------------------------------------------ 72 void BLooperList::AddLooper(BLooper* looper) 73 { 74 BAutolock Listlock(fLock); 75 AssertLocked(); 76 if (!IsLooperValid(looper)) 77 { 78 LDIter i = find_if(fData.begin(), fData.end(), EmptySlotPred); 79 if (i == fData.end()) 80 { 81 fData.push_back(LooperData(looper, ++fLooperID)); 82 looper->fLooperID = fLooperID; 83 looper->Lock(); 84 } 85 else 86 { 87 i->looper = looper; 88 i->id = ++fLooperID; 89 looper->fLooperID = fLooperID; 90 looper->Lock(); 91 } 92 } 93 } 94 //------------------------------------------------------------------------------ 95 bool BLooperList::IsLooperValid(const BLooper* looper) 96 { 97 BAutolock Listlock(fLock); 98 AssertLocked(); 99 100 return find_if(fData.begin(), fData.end(), FindLooperPred(looper)) != 101 fData.end(); 102 } 103 //------------------------------------------------------------------------------ 104 bool BLooperList::RemoveLooper(BLooper* looper) 105 { 106 BAutolock Listlock(fLock); 107 AssertLocked(); 108 109 LDIter i = find_if(fData.begin(), fData.end(), FindLooperPred(looper)); 110 if (i != fData.end()) 111 { 112 i->looper = NULL; 113 return true; 114 } 115 116 return false; 117 } 118 //------------------------------------------------------------------------------ 119 void BLooperList::GetLooperList(BList* list) 120 { 121 BAutolock Listlock(fLock); 122 AssertLocked(); 123 for (uint32 i = 0; i < fData.size(); ++i) 124 { 125 if (fData[i].looper) 126 list->AddItem(fData[i].looper); 127 } 128 } 129 //------------------------------------------------------------------------------ 130 int32 BLooperList::CountLoopers() 131 { 132 BAutolock Listlock(fLock); 133 AssertLocked(); 134 return (int32)fData.size(); 135 } 136 //------------------------------------------------------------------------------ 137 BLooper* BLooperList::LooperAt(int32 index) 138 { 139 BAutolock Listlock(fLock); 140 AssertLocked(); 141 142 BLooper* Looper = NULL; 143 if (index < (int32)fData.size()) 144 { 145 Looper = fData[(uint32)index].looper; 146 } 147 148 return Looper; 149 } 150 //------------------------------------------------------------------------------ 151 BLooper* BLooperList::LooperForThread(thread_id tid) 152 { 153 BAutolock Listlock(fLock); 154 AssertLocked(); 155 BLooper* looper = NULL; 156 LDIter i = find_if(fData.begin(), fData.end(), FindThreadPred(tid)); 157 if (i != fData.end()) 158 { 159 looper = i->looper; 160 } 161 162 return looper; 163 } 164 //------------------------------------------------------------------------------ 165 BLooper* BLooperList::LooperForName(const char* name) 166 { 167 BAutolock Listlock(fLock); 168 AssertLocked(); 169 BLooper* looper = NULL; 170 LDIter i = find_if(fData.begin(), fData.end(), FindNamePred(name)); 171 if (i != fData.end()) 172 { 173 looper = i->looper; 174 } 175 176 return looper; 177 } 178 //------------------------------------------------------------------------------ 179 BLooper* BLooperList::LooperForPort(port_id port) 180 { 181 BAutolock Listlock(fLock); 182 AssertLocked(); 183 BLooper* looper = NULL; 184 LDIter i = find_if(fData.begin(), fData.end(), FindPortPred(port)); 185 if (i != fData.end()) 186 { 187 looper = i->looper; 188 } 189 190 return looper; 191 } 192 //------------------------------------------------------------------------------ 193 bool BLooperList::EmptySlotPred(LooperData& Data) 194 { 195 return Data.looper == NULL; 196 } 197 //------------------------------------------------------------------------------ 198 void BLooperList::AssertLocked() 199 { 200 if (!IsLocked()) 201 { 202 debugger("looperlist is not locked; proceed at great risk!"); 203 } 204 } 205 //------------------------------------------------------------------------------ 206 207 208 //------------------------------------------------------------------------------ 209 // #pragma mark - 210 // #pragma mark BLooperList::LooperData 211 // #pragma mark - 212 //------------------------------------------------------------------------------ 213 BLooperList::LooperData::LooperData() 214 : looper(NULL), id(0) 215 { 216 } 217 //------------------------------------------------------------------------------ 218 BLooperList::LooperData::LooperData(BLooper* loop, uint32 i) 219 : looper(loop), id(i) 220 { 221 ; 222 } 223 //------------------------------------------------------------------------------ 224 BLooperList::LooperData::LooperData(const LooperData& rhs) 225 { 226 *this = rhs; 227 } 228 //------------------------------------------------------------------------------ 229 BLooperList::LooperData& 230 BLooperList::LooperData::operator=(const LooperData& rhs) 231 { 232 if (this != &rhs) 233 { 234 looper = rhs.looper; 235 id = rhs.id; 236 } 237 238 return *this; 239 } 240 //------------------------------------------------------------------------------ 241 242 243 //------------------------------------------------------------------------------ 244 bool BLooperList::FindLooperPred::operator()(BLooperList::LooperData& Data) 245 { 246 return Data.looper && (looper == Data.looper); 247 } 248 //------------------------------------------------------------------------------ 249 bool BLooperList::FindThreadPred::operator()(LooperData& Data) 250 { 251 return Data.looper && (thread == Data.looper->Thread()); 252 } 253 //------------------------------------------------------------------------------ 254 bool BLooperList::FindNamePred::operator()(LooperData& Data) 255 { 256 return Data.looper && (strcmp(name, Data.looper->Name()) == 0); 257 } 258 //------------------------------------------------------------------------------ 259 bool BLooperList::FindPortPred::operator()(LooperData& Data) 260 { 261 return Data.looper && (port == _get_looper_port_(Data.looper)); 262 } 263 //------------------------------------------------------------------------------ 264 265 } // namespace BPrivate 266 267 /* 268 * $Log $ 269 * 270 * $Id $ 271 * 272 */ 273 274