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