101 lines
2.5 KiB
C++
101 lines
2.5 KiB
C++
#include "clusters.hpp"
|
|
#include "cluster.hpp"
|
|
#include <cassert>
|
|
#include <algorithm>
|
|
|
|
namespace mkvparser
|
|
{
|
|
|
|
Clusters::Clusters()
|
|
: m_clusterLimit(0)
|
|
{
|
|
}
|
|
|
|
Clusters::~Clusters()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
void Clusters::clear()
|
|
{
|
|
ClusterVect_t::iterator first = m_clusters.begin();
|
|
ClusterVect_t::iterator last = m_clusters.end();
|
|
|
|
for ( ; first != last; ++first)
|
|
{
|
|
Cluster* const p = *first;
|
|
assert(p);
|
|
|
|
delete p;
|
|
}
|
|
m_clusters.clear();
|
|
}
|
|
|
|
Clusters::iterator Clusters::insert(iterator position, const value_type& val)
|
|
{
|
|
if (m_clusterLimit != 0 && m_clusters.size() >= m_clusterLimit)
|
|
position = RemoveOneCluster(position);
|
|
|
|
return m_clusters.insert(position, val);
|
|
}
|
|
|
|
void Clusters::SetClusterDestructionObserver(ClusterDestructionObserver* observer)
|
|
{
|
|
m_observers.push_back(observer);
|
|
}
|
|
|
|
void Clusters::RemoveClusterDestructionObserver(ClusterDestructionObserver* observer)
|
|
{
|
|
ObserverVect_t::iterator it = std::find(m_observers.begin(), m_observers.end(), observer);
|
|
if (it != m_observers.end())
|
|
m_observers.erase(it);
|
|
}
|
|
|
|
Clusters::iterator Clusters::RemoveOneCluster(iterator insertPosition)
|
|
{
|
|
// try to remove clusters behind insert position
|
|
if (!m_clusters.empty())
|
|
{
|
|
typedef std::iterator_traits<iterator>::difference_type diff_type;
|
|
diff_type posFromBegin = std::distance(m_clusters.begin(), insertPosition);
|
|
for (size_type i = 0; i < size_type(posFromBegin); ++i)
|
|
{
|
|
if (TryRemoveClusterAt(i))
|
|
{
|
|
--posFromBegin;
|
|
return m_clusters.begin() + posFromBegin;
|
|
}
|
|
}
|
|
// could not remove from the beginning, try from the end
|
|
for (size_type i = m_clusters.size() - 1; i > size_type(posFromBegin); --i)
|
|
{
|
|
if (TryRemoveClusterAt(i))
|
|
return m_clusters.begin() + posFromBegin;
|
|
}
|
|
}
|
|
// no removal
|
|
return insertPosition;
|
|
}
|
|
|
|
bool Clusters::TryRemoveClusterAt(size_type n)
|
|
{
|
|
bool canRemove = true;
|
|
ObserverVect_t::const_iterator first = m_observers.begin();
|
|
ObserverVect_t::const_iterator last = m_observers.end();
|
|
for (; first != last; ++first)
|
|
canRemove = canRemove && (*first)->CanDestroyCluster(m_clusters[n]);
|
|
|
|
if (canRemove)
|
|
{
|
|
// remove
|
|
Cluster* c = m_clusters[n];
|
|
delete c;
|
|
m_clusters.erase(m_clusters.begin() + n);
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
} // namespace mkvparser
|