xref: /haiku/src/kits/app/LooperList.cpp (revision d374a27286b8a52974a97dba0d5966ea026a665d)
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