1 /* 2 * Copyright 2001-2010, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Erik Jaesler (erik@cgsoftware.com) 7 */ 8 9 10 //! Maintains a global list of all loopers in a given team. 11 12 13 #include "LooperList.h" 14 15 #include <Autolock.h> 16 #include <Looper.h> 17 18 #include <algorithm> 19 #include <string.h> 20 21 22 using std::vector; 23 24 namespace BPrivate { 25 26 BLooperList gLooperList; 27 28 typedef vector<BLooperList::LooperData>::iterator LooperDataIterator; 29 30 31 BLooperList::BLooperList() 32 : 33 fLock("BLooperList lock") 34 { 35 } 36 37 38 bool 39 BLooperList::Lock() 40 { 41 return fLock.Lock(); 42 } 43 44 45 void 46 BLooperList::Unlock() 47 { 48 fLock.Unlock(); 49 } 50 51 52 bool 53 BLooperList::IsLocked() 54 { 55 return fLock.IsLocked(); 56 } 57 58 59 void 60 BLooperList::AddLooper(BLooper* looper) 61 { 62 BAutolock locker(fLock); 63 AssertLocked(); 64 if (!IsLooperValid(looper)) { 65 LooperDataIterator i 66 = find_if(fData.begin(), fData.end(), EmptySlotPred); 67 if (i == fData.end()) { 68 fData.push_back(LooperData(looper)); 69 looper->Lock(); 70 } else { 71 i->looper = looper; 72 looper->Lock(); 73 } 74 } 75 } 76 77 78 bool 79 BLooperList::IsLooperValid(const BLooper* looper) 80 { 81 BAutolock locker(fLock); 82 AssertLocked(); 83 84 return find_if(fData.begin(), fData.end(), 85 FindLooperPred(looper)) != fData.end(); 86 } 87 88 89 bool 90 BLooperList::RemoveLooper(BLooper* looper) 91 { 92 BAutolock locker(fLock); 93 AssertLocked(); 94 95 LooperDataIterator i = find_if(fData.begin(), fData.end(), 96 FindLooperPred(looper)); 97 if (i != fData.end()) { 98 i->looper = NULL; 99 return true; 100 } 101 102 return false; 103 } 104 105 106 void 107 BLooperList::GetLooperList(BList* list) 108 { 109 BAutolock locker(fLock); 110 AssertLocked(); 111 112 for (uint32 i = 0; i < fData.size(); ++i) { 113 if (fData[i].looper) 114 list->AddItem(fData[i].looper); 115 } 116 } 117 118 119 int32 120 BLooperList::CountLoopers() 121 { 122 BAutolock locker(fLock); 123 AssertLocked(); 124 return (int32)fData.size(); 125 } 126 127 128 BLooper* 129 BLooperList::LooperAt(int32 index) 130 { 131 BAutolock locker(fLock); 132 AssertLocked(); 133 134 BLooper* looper = NULL; 135 if (index < (int32)fData.size()) 136 looper = fData[(uint32)index].looper; 137 138 return looper; 139 } 140 141 142 BLooper* 143 BLooperList::LooperForThread(thread_id thread) 144 { 145 BAutolock locker(fLock); 146 AssertLocked(); 147 148 BLooper* looper = NULL; 149 LooperDataIterator i 150 = find_if(fData.begin(), fData.end(), FindThreadPred(thread)); 151 if (i != fData.end()) 152 looper = i->looper; 153 154 return looper; 155 } 156 157 158 BLooper* 159 BLooperList::LooperForName(const char* name) 160 { 161 BAutolock locker(fLock); 162 AssertLocked(); 163 164 BLooper* looper = NULL; 165 LooperDataIterator i 166 = find_if(fData.begin(), fData.end(), FindNamePred(name)); 167 if (i != fData.end()) 168 looper = i->looper; 169 170 return looper; 171 } 172 173 174 BLooper* 175 BLooperList::LooperForPort(port_id port) 176 { 177 BAutolock locker(fLock); 178 AssertLocked(); 179 180 BLooper* looper = NULL; 181 LooperDataIterator i 182 = find_if(fData.begin(), fData.end(), FindPortPred(port)); 183 if (i != fData.end()) 184 looper = i->looper; 185 186 return looper; 187 } 188 189 190 bool 191 BLooperList::EmptySlotPred(LooperData& data) 192 { 193 return data.looper == NULL; 194 } 195 196 197 void 198 BLooperList::AssertLocked() 199 { 200 if (!IsLocked()) 201 debugger("looperlist is not locked; proceed at great risk!"); 202 } 203 204 205 // #pragma mark - BLooperList::LooperData 206 207 208 BLooperList::LooperData::LooperData() 209 : 210 looper(NULL) 211 { 212 } 213 214 215 BLooperList::LooperData::LooperData(BLooper* looper) 216 : 217 looper(looper) 218 { 219 } 220 221 222 BLooperList::LooperData::LooperData(const LooperData& other) 223 { 224 *this = other; 225 } 226 227 228 BLooperList::LooperData& 229 BLooperList::LooperData::operator=(const LooperData& other) 230 { 231 if (this != &other) 232 looper = other.looper; 233 234 return *this; 235 } 236 237 238 bool 239 BLooperList::FindLooperPred::operator()(BLooperList::LooperData& data) 240 { 241 return data.looper && looper == data.looper; 242 } 243 244 245 bool 246 BLooperList::FindThreadPred::operator()(LooperData& data) 247 { 248 return data.looper && thread == data.looper->Thread(); 249 } 250 251 252 bool 253 BLooperList::FindNamePred::operator()(LooperData& data) 254 { 255 return data.looper && !strcmp(name, data.looper->Name()); 256 } 257 258 259 bool 260 BLooperList::FindPortPred::operator()(LooperData& data) 261 { 262 return data.looper && port == _get_looper_port_(data.looper); 263 } 264 265 } // namespace BPrivate 266 267