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