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 : fLooperID(0) 53 { 54 } 55 //------------------------------------------------------------------------------ 56 bool BLooperList::Lock() 57 { 58 return fLock.Lock(); 59 } 60 //------------------------------------------------------------------------------ 61 void BLooperList::Unlock() 62 { 63 fLock.Unlock(); 64 } 65 //------------------------------------------------------------------------------ 66 bool BLooperList::IsLocked() 67 { 68 return fLock.IsLocked(); 69 } 70 //------------------------------------------------------------------------------ 71 void BLooperList::AddLooper(BLooper* looper) 72 { 73 BAutolock Listlock(fLock); 74 AssertLocked(); 75 if (!IsLooperValid(looper)) 76 { 77 LDIter i = find_if(fData.begin(), fData.end(), EmptySlotPred); 78 if (i == fData.end()) 79 { 80 fData.push_back(LooperData(looper, ++fLooperID)); 81 looper->fLooperID = fLooperID; 82 looper->Lock(); 83 } 84 else 85 { 86 i->looper = looper; 87 i->id = ++fLooperID; 88 looper->fLooperID = fLooperID; 89 looper->Lock(); 90 } 91 } 92 } 93 //------------------------------------------------------------------------------ 94 bool BLooperList::IsLooperValid(const BLooper* looper) 95 { 96 BAutolock Listlock(fLock); 97 AssertLocked(); 98 99 return find_if(fData.begin(), fData.end(), FindLooperPred(looper)) != 100 fData.end(); 101 } 102 //------------------------------------------------------------------------------ 103 bool BLooperList::RemoveLooper(BLooper* looper) 104 { 105 BAutolock Listlock(fLock); 106 AssertLocked(); 107 108 LDIter i = find_if(fData.begin(), fData.end(), FindLooperPred(looper)); 109 if (i != fData.end()) 110 { 111 i->looper = NULL; 112 return true; 113 } 114 115 return false; 116 } 117 //------------------------------------------------------------------------------ 118 void BLooperList::GetLooperList(BList* list) 119 { 120 BAutolock Listlock(fLock); 121 AssertLocked(); 122 for (uint32 i = 0; i < fData.size(); ++i) 123 { 124 list->AddItem(fData[i].looper); 125 } 126 } 127 //------------------------------------------------------------------------------ 128 int32 BLooperList::CountLoopers() 129 { 130 BAutolock Listlock(fLock); 131 AssertLocked(); 132 return (int32)fData.size(); 133 } 134 //------------------------------------------------------------------------------ 135 BLooper* BLooperList::LooperAt(int32 index) 136 { 137 BAutolock Listlock(fLock); 138 AssertLocked(); 139 140 BLooper* Looper = NULL; 141 if (index < (int32)fData.size()) 142 { 143 Looper = fData[(uint32)index].looper; 144 } 145 146 return Looper; 147 } 148 //------------------------------------------------------------------------------ 149 BLooper* BLooperList::LooperForThread(thread_id tid) 150 { 151 BAutolock Listlock(fLock); 152 AssertLocked(); 153 BLooper* looper = NULL; 154 LDIter i = find_if(fData.begin(), fData.end(), FindThreadPred(tid)); 155 if (i != fData.end()) 156 { 157 looper = i->looper; 158 } 159 160 return looper; 161 } 162 //------------------------------------------------------------------------------ 163 BLooper* BLooperList::LooperForName(const char* name) 164 { 165 BAutolock Listlock(fLock); 166 AssertLocked(); 167 BLooper* looper = NULL; 168 LDIter i = find_if(fData.begin(), fData.end(), FindNamePred(name)); 169 if (i != fData.end()) 170 { 171 looper = i->looper; 172 } 173 174 return looper; 175 } 176 //------------------------------------------------------------------------------ 177 BLooper* BLooperList::LooperForPort(port_id port) 178 { 179 BAutolock Listlock(fLock); 180 AssertLocked(); 181 BLooper* looper = NULL; 182 LDIter i = find_if(fData.begin(), fData.end(), FindPortPred(port)); 183 if (i != fData.end()) 184 { 185 looper = i->looper; 186 } 187 188 return looper; 189 } 190 //------------------------------------------------------------------------------ 191 bool BLooperList::EmptySlotPred(LooperData& Data) 192 { 193 return Data.looper == NULL; 194 } 195 //------------------------------------------------------------------------------ 196 void BLooperList::AssertLocked() 197 { 198 if (!IsLocked()) 199 { 200 debugger("looperlist is not locked; proceed at great risk!"); 201 } 202 } 203 //------------------------------------------------------------------------------ 204 205 206 //------------------------------------------------------------------------------ 207 // #pragma mark - 208 // #pragma mark BLooperList::LooperData 209 // #pragma mark - 210 //------------------------------------------------------------------------------ 211 BLooperList::LooperData::LooperData() 212 : looper(NULL), id(0) 213 { 214 } 215 //------------------------------------------------------------------------------ 216 BLooperList::LooperData::LooperData(BLooper* loop, uint32 i) 217 : looper(loop), id(i) 218 { 219 ; 220 } 221 //------------------------------------------------------------------------------ 222 BLooperList::LooperData::LooperData(const LooperData& rhs) 223 { 224 *this = rhs; 225 } 226 //------------------------------------------------------------------------------ 227 BLooperList::LooperData& 228 BLooperList::LooperData::operator=(const LooperData& rhs) 229 { 230 if (this != &rhs) 231 { 232 looper = rhs.looper; 233 id = rhs.id; 234 } 235 236 return *this; 237 } 238 //------------------------------------------------------------------------------ 239 240 241 //------------------------------------------------------------------------------ 242 bool BLooperList::FindLooperPred::operator()(BLooperList::LooperData& Data) 243 { 244 return Data.looper && (looper == Data.looper); 245 } 246 //------------------------------------------------------------------------------ 247 bool BLooperList::FindThreadPred::operator()(LooperData& Data) 248 { 249 return Data.looper && (thread == Data.looper->Thread()); 250 } 251 //------------------------------------------------------------------------------ 252 bool BLooperList::FindNamePred::operator()(LooperData& Data) 253 { 254 return Data.looper && (strcmp(name, Data.looper->Name()) == 0); 255 } 256 //------------------------------------------------------------------------------ 257 bool BLooperList::FindPortPred::operator()(LooperData& Data) 258 { 259 return Data.looper && (port == _get_looper_port_(Data.looper)); 260 } 261 //------------------------------------------------------------------------------ 262 263 } // namespace BPrivate 264 265 /* 266 * $Log $ 267 * 268 * $Id $ 269 * 270 */ 271 272