32 |
namespace LinuxSampler { |
namespace LinuxSampler { |
33 |
|
|
34 |
/** |
/** |
35 |
* Used to determine and manage the relations between samples and consumers (e.g. regions) |
* Used to determine and manage the relations between samples and consumers |
36 |
|
* (e.g. regions). Even though this class is currently stored at a shared |
37 |
|
* source file location, this class is actually only used by the sfz engine |
38 |
|
* ATM. So the gig and sf2 engines are not using this class at all. |
39 |
|
* |
40 |
|
* NOTE: This class currently uses a somewhat unclean design by maintaining |
41 |
|
* a separate set of information of "consumers of a sample" vs. "consumers |
42 |
|
* actually using a sample" (see bug #308). We might need to revise this |
43 |
|
* design of this class in case new problems appear (e.g. when encountering |
44 |
|
* memory leaks after closing an sfz instrument). |
45 |
*/ |
*/ |
46 |
template <class S /* Sample */, class C /* Sample Consumer */> |
template <class S /* Sample */, class C /* Sample Consumer */> |
47 |
class SampleManager { |
class SampleManager { |
148 |
verifyPair(pSample, pConsumer, "SampleManager::SetSampleNotInUse"); |
verifyPair(pSample, pConsumer, "SampleManager::SetSampleNotInUse"); |
149 |
|
|
150 |
bool inUse = !samplesInUseMap[pSample].empty(); |
bool inUse = !samplesInUseMap[pSample].empty(); |
151 |
samplesInUseMap[pSample].erase(pConsumer); |
// Remove only one consumer at a time |
152 |
|
typename std::multiset<C*>::iterator it = samplesInUseMap[pSample].find(pConsumer); |
153 |
|
if (it != samplesInUseMap[pSample].end()) { |
154 |
|
samplesInUseMap[pSample].erase(it); |
155 |
|
} |
156 |
bool inUseNew = !samplesInUseMap[pSample].empty(); |
bool inUseNew = !samplesInUseMap[pSample].empty(); |
157 |
|
// Wih no consumers, erase sample |
158 |
|
if (!inUseNew) samplesInUseMap.erase(pSample); |
159 |
if(inUse && !inUseNew) OnSampleNotInUse(pSample); |
if(inUse && !inUseNew) OnSampleNotInUse(pSample); |
160 |
} |
} |
161 |
|
|
162 |
protected: |
protected: |
163 |
std::map<S*, std::set<C*> > sampleMap; |
std::map<S*, std::set<C*> > sampleMap; |
164 |
std::map<S*, std::set<C*> > samplesInUseMap; |
std::map<S*, std::multiset<C*> > samplesInUseMap; // std::multiset as data type fixes bug #308. |
165 |
|
|
166 |
void verifyPair(S* pSample, C* pConsumer, String caller) { |
void verifyPair(S* pSample, C* pConsumer, String caller) { |
167 |
if(!HasSample(pSample)) { |
if(!HasSample(pSample)) { |
177 |
* Override this method to handle the state change (not in use -> in use) |
* Override this method to handle the state change (not in use -> in use) |
178 |
* of the specified sample. |
* of the specified sample. |
179 |
*/ |
*/ |
180 |
virtual void OnSampleInUse(S* pSample) { } |
virtual void OnSampleInUse(S* pSample) = 0; |
181 |
|
|
182 |
/** |
/** |
183 |
* Override this method to handle the state change (in use -> not in use) |
* Override this method to handle the state change (in use -> not in use) |
184 |
* of the specified sample. |
* of the specified sample. |
185 |
*/ |
*/ |
186 |
virtual void OnSampleNotInUse(S* pSample) { } |
virtual void OnSampleNotInUse(S* pSample) = 0; |
187 |
}; |
}; |
188 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |
189 |
|
|