xref: /haiku/src/kits/app/LooperList.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		LooperList.cpp
23 //	Author(s):		Erik Jaesler (erik@cgsoftware.com)
24 //	Description:	Maintains a global list of all loopers in a given team.
25 //------------------------------------------------------------------------------
26 
27 // Standard Includes -----------------------------------------------------------
28 #include <algorithm>
29 
30 // System Includes -------------------------------------------------------------
31 #include <Autolock.h>
32 #include <Looper.h>
33 
34 // Project Includes ------------------------------------------------------------
35 
36 // Local Includes --------------------------------------------------------------
37 #include "LooperList.h"
38 
39 // Local Defines ---------------------------------------------------------------
40 
41 // Globals ---------------------------------------------------------------------
42 using std::vector;
43 
44 namespace BPrivate {
45 
46 BLooperList gLooperList;
47 
48 typedef vector<BLooperList::LooperData>::iterator LDIter;
49 
50 //------------------------------------------------------------------------------
51 BLooperList::BLooperList()
52  :	fLock("BLooperList lock"),
53 	fLooperID(0)
54 {
55 }
56 //------------------------------------------------------------------------------
57 bool BLooperList::Lock()
58 {
59 	return fLock.Lock();
60 }
61 //------------------------------------------------------------------------------
62 void BLooperList::Unlock()
63 {
64 	fLock.Unlock();
65 }
66 //------------------------------------------------------------------------------
67 bool BLooperList::IsLocked()
68 {
69 	return fLock.IsLocked();
70 }
71 //------------------------------------------------------------------------------
72 void BLooperList::AddLooper(BLooper* looper)
73 {
74 	BAutolock Listlock(fLock);
75 	AssertLocked();
76 	if (!IsLooperValid(looper))
77 	{
78 		LDIter i = find_if(fData.begin(), fData.end(), EmptySlotPred);
79 		if (i == fData.end())
80 		{
81 			fData.push_back(LooperData(looper, ++fLooperID));
82 			looper->fLooperID = fLooperID;
83 			looper->Lock();
84 		}
85 		else
86 		{
87 			i->looper = looper;
88 			i->id = ++fLooperID;
89 			looper->fLooperID = fLooperID;
90 			looper->Lock();
91 		}
92 	}
93 }
94 //------------------------------------------------------------------------------
95 bool BLooperList::IsLooperValid(const BLooper* looper)
96 {
97 	BAutolock Listlock(fLock);
98 	AssertLocked();
99 
100 	return find_if(fData.begin(), fData.end(), FindLooperPred(looper)) !=
101 			fData.end();
102 }
103 //------------------------------------------------------------------------------
104 bool BLooperList::RemoveLooper(BLooper* looper)
105 {
106 	BAutolock Listlock(fLock);
107 	AssertLocked();
108 
109 	LDIter i = find_if(fData.begin(), fData.end(), FindLooperPred(looper));
110 	if (i != fData.end())
111 	{
112 		i->looper = NULL;
113 		return true;
114 	}
115 
116 	return false;
117 }
118 //------------------------------------------------------------------------------
119 void BLooperList::GetLooperList(BList* list)
120 {
121 	BAutolock Listlock(fLock);
122 	AssertLocked();
123 	for (uint32 i = 0; i < fData.size(); ++i)
124 	{
125 		if (fData[i].looper)
126 			list->AddItem(fData[i].looper);
127 	}
128 }
129 //------------------------------------------------------------------------------
130 int32 BLooperList::CountLoopers()
131 {
132 	BAutolock Listlock(fLock);
133 	AssertLocked();
134 	return (int32)fData.size();
135 }
136 //------------------------------------------------------------------------------
137 BLooper* BLooperList::LooperAt(int32 index)
138 {
139 	BAutolock Listlock(fLock);
140 	AssertLocked();
141 
142 	BLooper* Looper = NULL;
143 	if (index < (int32)fData.size())
144 	{
145 		Looper = fData[(uint32)index].looper;
146 	}
147 
148 	return Looper;
149 }
150 //------------------------------------------------------------------------------
151 BLooper* BLooperList::LooperForThread(thread_id tid)
152 {
153 	BAutolock Listlock(fLock);
154 	AssertLocked();
155 	BLooper* looper = NULL;
156 	LDIter i = find_if(fData.begin(), fData.end(), FindThreadPred(tid));
157 	if (i != fData.end())
158 	{
159 		looper = i->looper;
160 	}
161 
162 	return looper;
163 }
164 //------------------------------------------------------------------------------
165 BLooper* BLooperList::LooperForName(const char* name)
166 {
167 	BAutolock Listlock(fLock);
168 	AssertLocked();
169 	BLooper* looper = NULL;
170 	LDIter i = find_if(fData.begin(), fData.end(), FindNamePred(name));
171 	if (i != fData.end())
172 	{
173 		looper = i->looper;
174 	}
175 
176 	return looper;
177 }
178 //------------------------------------------------------------------------------
179 BLooper* BLooperList::LooperForPort(port_id port)
180 {
181 	BAutolock Listlock(fLock);
182 	AssertLocked();
183 	BLooper* looper = NULL;
184 	LDIter i = find_if(fData.begin(), fData.end(), FindPortPred(port));
185 	if (i != fData.end())
186 	{
187 		looper = i->looper;
188 	}
189 
190 	return looper;
191 }
192 //------------------------------------------------------------------------------
193 bool BLooperList::EmptySlotPred(LooperData& Data)
194 {
195 	return Data.looper == NULL;
196 }
197 //------------------------------------------------------------------------------
198 void BLooperList::AssertLocked()
199 {
200 	if (!IsLocked())
201 	{
202 		debugger("looperlist is not locked; proceed at great risk!");
203 	}
204 }
205 //------------------------------------------------------------------------------
206 
207 
208 //------------------------------------------------------------------------------
209 //	#pragma mark -
210 //	#pragma mark BLooperList::LooperData
211 //	#pragma mark -
212 //------------------------------------------------------------------------------
213 BLooperList::LooperData::LooperData()
214 	:	looper(NULL), id(0)
215 {
216 }
217 //------------------------------------------------------------------------------
218 BLooperList::LooperData::LooperData(BLooper* loop, uint32 i)
219 	:	looper(loop), id(i)
220 {
221 	;
222 }
223 //------------------------------------------------------------------------------
224 BLooperList::LooperData::LooperData(const LooperData& rhs)
225 {
226 	*this = rhs;
227 }
228 //------------------------------------------------------------------------------
229 BLooperList::LooperData&
230 BLooperList::LooperData::operator=(const LooperData& rhs)
231 {
232 	if (this != &rhs)
233 	{
234 		looper = rhs.looper;
235 		id = rhs.id;
236 	}
237 
238 	return *this;
239 }
240 //------------------------------------------------------------------------------
241 
242 
243 //------------------------------------------------------------------------------
244 bool BLooperList::FindLooperPred::operator()(BLooperList::LooperData& Data)
245 {
246 	return Data.looper && (looper == Data.looper);
247 }
248 //------------------------------------------------------------------------------
249 bool BLooperList::FindThreadPred::operator()(LooperData& Data)
250 {
251 	return Data.looper && (thread == Data.looper->Thread());
252 }
253 //------------------------------------------------------------------------------
254 bool BLooperList::FindNamePred::operator()(LooperData& Data)
255 {
256 	return Data.looper && (strcmp(name, Data.looper->Name()) == 0);
257 }
258 //------------------------------------------------------------------------------
259 bool BLooperList::FindPortPred::operator()(LooperData& Data)
260 {
261 	return Data.looper && (port == _get_looper_port_(Data.looper));
262 }
263 //------------------------------------------------------------------------------
264 
265 }	// namespace BPrivate
266 
267 /*
268  * $Log $
269  *
270  * $Id  $
271  *
272  */
273 
274