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