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 if (fData[i].looper) 125 list->AddItem(fData[i].looper); 126 } 127 } 128 //------------------------------------------------------------------------------ 129 int32 BLooperList::CountLoopers() 130 { 131 BAutolock Listlock(fLock); 132 AssertLocked(); 133 return (int32)fData.size(); 134 } 135 //------------------------------------------------------------------------------ 136 BLooper* BLooperList::LooperAt(int32 index) 137 { 138 BAutolock Listlock(fLock); 139 AssertLocked(); 140 141 BLooper* Looper = NULL; 142 if (index < (int32)fData.size()) 143 { 144 Looper = fData[(uint32)index].looper; 145 } 146 147 return Looper; 148 } 149 //------------------------------------------------------------------------------ 150 BLooper* BLooperList::LooperForThread(thread_id tid) 151 { 152 BAutolock Listlock(fLock); 153 AssertLocked(); 154 BLooper* looper = NULL; 155 LDIter i = find_if(fData.begin(), fData.end(), FindThreadPred(tid)); 156 if (i != fData.end()) 157 { 158 looper = i->looper; 159 } 160 161 return looper; 162 } 163 //------------------------------------------------------------------------------ 164 BLooper* BLooperList::LooperForName(const char* name) 165 { 166 BAutolock Listlock(fLock); 167 AssertLocked(); 168 BLooper* looper = NULL; 169 LDIter i = find_if(fData.begin(), fData.end(), FindNamePred(name)); 170 if (i != fData.end()) 171 { 172 looper = i->looper; 173 } 174 175 return looper; 176 } 177 //------------------------------------------------------------------------------ 178 BLooper* BLooperList::LooperForPort(port_id port) 179 { 180 BAutolock Listlock(fLock); 181 AssertLocked(); 182 BLooper* looper = NULL; 183 LDIter i = find_if(fData.begin(), fData.end(), FindPortPred(port)); 184 if (i != fData.end()) 185 { 186 looper = i->looper; 187 } 188 189 return looper; 190 } 191 //------------------------------------------------------------------------------ 192 bool BLooperList::EmptySlotPred(LooperData& Data) 193 { 194 return Data.looper == NULL; 195 } 196 //------------------------------------------------------------------------------ 197 void BLooperList::AssertLocked() 198 { 199 if (!IsLocked()) 200 { 201 debugger("looperlist is not locked; proceed at great risk!"); 202 } 203 } 204 //------------------------------------------------------------------------------ 205 206 207 //------------------------------------------------------------------------------ 208 // #pragma mark - 209 // #pragma mark BLooperList::LooperData 210 // #pragma mark - 211 //------------------------------------------------------------------------------ 212 BLooperList::LooperData::LooperData() 213 : looper(NULL), id(0) 214 { 215 } 216 //------------------------------------------------------------------------------ 217 BLooperList::LooperData::LooperData(BLooper* loop, uint32 i) 218 : looper(loop), id(i) 219 { 220 ; 221 } 222 //------------------------------------------------------------------------------ 223 BLooperList::LooperData::LooperData(const LooperData& rhs) 224 { 225 *this = rhs; 226 } 227 //------------------------------------------------------------------------------ 228 BLooperList::LooperData& 229 BLooperList::LooperData::operator=(const LooperData& rhs) 230 { 231 if (this != &rhs) 232 { 233 looper = rhs.looper; 234 id = rhs.id; 235 } 236 237 return *this; 238 } 239 //------------------------------------------------------------------------------ 240 241 242 //------------------------------------------------------------------------------ 243 bool BLooperList::FindLooperPred::operator()(BLooperList::LooperData& Data) 244 { 245 return Data.looper && (looper == Data.looper); 246 } 247 //------------------------------------------------------------------------------ 248 bool BLooperList::FindThreadPred::operator()(LooperData& Data) 249 { 250 return Data.looper && (thread == Data.looper->Thread()); 251 } 252 //------------------------------------------------------------------------------ 253 bool BLooperList::FindNamePred::operator()(LooperData& Data) 254 { 255 return Data.looper && (strcmp(name, Data.looper->Name()) == 0); 256 } 257 //------------------------------------------------------------------------------ 258 bool BLooperList::FindPortPred::operator()(LooperData& Data) 259 { 260 return Data.looper && (port == _get_looper_port_(Data.looper)); 261 } 262 //------------------------------------------------------------------------------ 263 264 } // namespace BPrivate 265 266 /* 267 * $Log $ 268 * 269 * $Id $ 270 * 271 */ 272 273