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