When installing addons the karts/tracks are now not all completely
reloaded, only the new addon is loaded. This should also fix a (minor) memory leak when a kart model is updated (textures and mesh weren't freed). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10103 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
1088fd35c8
commit
227bcdd773
@ -407,15 +407,19 @@ bool AddonsManager::install(const Addon &addon)
|
||||
// karts will not reload their meshes.
|
||||
const KartProperties *prop =
|
||||
kart_properties_manager->getKart(addon.getId());
|
||||
// If the model already exist (i.e. it's an update, not a new install)
|
||||
// make sure to remove the cached copy of the mesh
|
||||
// If the model already exist, first remove the old kart
|
||||
if(prop)
|
||||
{
|
||||
const KartModel &model = prop->getMasterKartModel();
|
||||
irr_driver->removeMeshFromCache(model.getModel());
|
||||
}
|
||||
kart_properties_manager->removeKart(addon.getId());
|
||||
kart_properties_manager->loadKart(addon.getDataDir());
|
||||
}
|
||||
saveInstalled(addon.getType());
|
||||
else if (addon.getType()=="track" || addon.getType()=="arena")
|
||||
{
|
||||
Track *track = track_manager->getTrack(addon.getId());
|
||||
if(track)
|
||||
track_manager->removeTrack(addon.getId());
|
||||
track_manager->loadTrack(addon.getDataDir());
|
||||
}
|
||||
saveInstalled();
|
||||
return true;
|
||||
} // install
|
||||
|
||||
@ -437,7 +441,15 @@ bool AddonsManager::uninstall(const Addon &addon)
|
||||
|
||||
//remove the addons directory
|
||||
bool error = !file_manager->removeDirectory(addon.getDataDir());
|
||||
saveInstalled(addon.getType());
|
||||
if(addon.getType()=="kart")
|
||||
{
|
||||
kart_properties_manager->removeKart(addon.getId());
|
||||
}
|
||||
else if(addon.getType()=="track" || addon.getType()=="arena")
|
||||
{
|
||||
track_manager->removeTrack(addon.getId());
|
||||
}
|
||||
saveInstalled();
|
||||
return !error;
|
||||
} // uninstall
|
||||
|
||||
|
@ -145,21 +145,17 @@ KartModel::~KartModel()
|
||||
|
||||
m_wheel_node[i]->drop();
|
||||
}
|
||||
// For now don't drop the textures: note that the mesh is not
|
||||
// dropped either (which enables a reload of kart_properties
|
||||
// without reading the full mesh again when a new addon is
|
||||
// installed, see KartPropertiesManager::reLoadAllKarts).
|
||||
// Therefore if the textures are dropped here, the mesh would
|
||||
// reference a freed texture, causing a crash.
|
||||
// While this potentially causes a memory leak, this is not
|
||||
// important since all kart meshes and all textures they use
|
||||
// are around till the very end of STK. The textures stay in
|
||||
// irrlicht's texture cache, and will be freed on exit.
|
||||
//if(m_is_master && m_wheel_model[i])
|
||||
// irr_driver->dropAllTextures(m_wheel_model[i]);
|
||||
if(m_is_master && m_wheel_model[i])
|
||||
irr_driver->dropAllTextures(m_wheel_model[i]);
|
||||
|
||||
}
|
||||
|
||||
if(m_is_master)
|
||||
{
|
||||
irr_driver->dropAllTextures(m_mesh);
|
||||
irr_driver->removeMeshFromCache(m_mesh);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#if SKELETON_DEBUG
|
||||
irr_driver->debug_meshes.clear();
|
||||
@ -285,7 +281,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
assert(m_is_master);
|
||||
std::string full_path = kart_properties.getKartDir()+"/"+m_model_filename;
|
||||
m_mesh = irr_driver->getAnimatedMesh(full_path);
|
||||
|
||||
irr_driver->grabAllTextures(m_mesh);
|
||||
if(!m_mesh)
|
||||
{
|
||||
printf("Problems loading mesh '%s' - kart '%s' will not be available\n",
|
||||
|
@ -68,30 +68,96 @@ void KartPropertiesManager::unloadAllKarts()
|
||||
m_karts_properties.clearAndDeleteAll();
|
||||
m_selected_karts.clear();
|
||||
m_kart_available.clear();
|
||||
m_groups.clear();
|
||||
m_groups_2_indices.clear();
|
||||
m_all_groups.clear();
|
||||
m_kart_search_path.clear();
|
||||
} // removeTextures
|
||||
} // unloadAllKarts
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Reloads all karts, i.e. reloads the meshes and textures. This is used
|
||||
* when changing the screen resolution.
|
||||
*/
|
||||
void KartPropertiesManager::reLoadAllKarts()
|
||||
{
|
||||
m_karts_properties.clearAndDeleteAll();
|
||||
m_selected_karts.clear();
|
||||
m_kart_available.clear();
|
||||
m_groups.clear();
|
||||
m_groups_2_indices.clear();
|
||||
m_all_groups.clear();
|
||||
//m_kart_search_path.clear();
|
||||
loadAllKarts(false);
|
||||
}
|
||||
} // reLoadAllKarts
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Remove a kart from the kart manager.
|
||||
* \param id The kart id (i.e. name of the directory) to remove.
|
||||
*/
|
||||
void KartPropertiesManager::removeKart(const std::string &ident)
|
||||
{
|
||||
// Remove the kart properties from the vector of all kart properties
|
||||
int index = getKartId(ident);
|
||||
const KartProperties *kp = getKart(ident); // must be done before remove
|
||||
m_karts_properties.remove(index);
|
||||
m_all_kart_dirs.erase(m_all_kart_dirs.begin()+index);
|
||||
m_kart_available.erase(m_kart_available.begin()+index);
|
||||
|
||||
// Remove the just removed kart from the 'group-name to kart property
|
||||
// index' mapping. If a group is now empty (i.e. the removed kart was
|
||||
// the only member of this group), remove the group
|
||||
const std::vector<std::string> &groups = kp->getGroups();
|
||||
|
||||
for (unsigned int i=0; i<groups.size(); i++)
|
||||
{
|
||||
std::vector<int> ::iterator it;
|
||||
it = std::find(m_groups_2_indices[groups[i]].begin(),
|
||||
m_groups_2_indices[groups[i]].end(), index);
|
||||
// Since we are iterating over all groups the kart belongs to,
|
||||
// there must be an entry found
|
||||
assert(it!=m_groups_2_indices[groups[i]].end());
|
||||
|
||||
m_groups_2_indices[groups[i]].erase(it);
|
||||
|
||||
// Check if the last kart of a group was removed
|
||||
if(m_groups_2_indices[groups[i]].size()==0)
|
||||
{
|
||||
m_groups_2_indices.erase(groups[i]);
|
||||
std::vector<std::string>::iterator its;
|
||||
its = std::find(m_all_groups.begin(), m_all_groups.end(),
|
||||
groups[i]);
|
||||
assert(its!=m_all_groups.end());
|
||||
m_all_groups.erase(its);
|
||||
} // if m_groups_2_indices[groups[i]].size()==0)
|
||||
} // for i in all groups the kart belongs to
|
||||
|
||||
|
||||
// Adjust the indices of all kart properties in the 'group name to
|
||||
// kart property index' mapping: all kart properties with an index
|
||||
// greater than index were moved one position further to the beginning
|
||||
std::map<std::string, std::vector<int> >::iterator it_gr;
|
||||
for(it_gr=m_groups_2_indices.begin(); it_gr != m_groups_2_indices.end();
|
||||
it_gr++)
|
||||
{
|
||||
for(unsigned int i=0; i<(*it_gr).second.size(); i++)
|
||||
{
|
||||
if( (*it_gr).second[i]>index)
|
||||
(*it_gr).second[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
delete kp;
|
||||
|
||||
// Only used for networking only, and it is safe to just clear it.
|
||||
// If a networking game is started it will be initialised properly.
|
||||
m_selected_karts.clear();
|
||||
} // removeKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads all kart properties and models.
|
||||
*/
|
||||
void KartPropertiesManager::loadAllKarts(bool loading_icon)
|
||||
{
|
||||
m_all_kart_dirs.clear();
|
||||
for(std::vector<std::string>::const_iterator dir=m_kart_search_path.begin();
|
||||
dir!=m_kart_search_path.end(); dir++)
|
||||
std::vector<std::string>::const_iterator dir;
|
||||
for(dir = m_kart_search_path.begin(); dir!=m_kart_search_path.end(); dir++)
|
||||
{
|
||||
// First check if there is a kart in the current directory
|
||||
// -------------------------------------------------------
|
||||
@ -109,9 +175,9 @@ void KartPropertiesManager::loadAllKarts(bool loading_icon)
|
||||
if (loaded && loading_icon)
|
||||
{
|
||||
GUIEngine::addLoadingIcon(irr_driver->getTexture(
|
||||
m_karts_properties[m_karts_properties.size()-1].getAbsoluteIconFile()
|
||||
)
|
||||
);
|
||||
m_karts_properties[m_karts_properties.size()-1]
|
||||
.getAbsoluteIconFile() )
|
||||
);
|
||||
}
|
||||
} // for all files in the currently handled directory
|
||||
} // for i
|
||||
@ -145,7 +211,8 @@ bool KartPropertiesManager::loadKart(const std::string &dir)
|
||||
if (kart_properties->getVersion() < stk_config->m_min_kart_version ||
|
||||
kart_properties->getVersion() > stk_config->m_max_kart_version)
|
||||
{
|
||||
fprintf(stderr, "[KartPropertiesManager] Warning: kart '%s' is not supported by this binary, ignored.\n",
|
||||
fprintf(stderr, "[KartPropertiesManager] Warning: kart '%s' is not "
|
||||
"supported by this binary, ignored.\n",
|
||||
kart_properties->getIdent().c_str());
|
||||
delete kart_properties;
|
||||
return false;
|
||||
@ -156,17 +223,21 @@ bool KartPropertiesManager::loadKart(const std::string &dir)
|
||||
const std::vector<std::string>& groups=kart_properties->getGroups();
|
||||
for(unsigned int g=0; g<groups.size(); g++)
|
||||
{
|
||||
if(m_groups.find(groups[g])==m_groups.end())
|
||||
if(m_groups_2_indices.find(groups[g])==m_groups_2_indices.end())
|
||||
{
|
||||
m_all_groups.push_back(groups[g]);
|
||||
}
|
||||
m_groups[groups[g]].push_back(m_karts_properties.size()-1);
|
||||
m_groups_2_indices[groups[g]].push_back(m_karts_properties.size()-1);
|
||||
}
|
||||
m_all_kart_dirs.push_back(dir);
|
||||
return true;
|
||||
} // loadKartData
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns index of the kart properties with the given ident.
|
||||
* \return Index of kart (between 0 and number of karts - 1).
|
||||
|
||||
*/
|
||||
const int KartPropertiesManager::getKartId(const std::string &ident) const
|
||||
{
|
||||
for (int i=0; i<m_karts_properties.size(); i++)
|
||||
@ -181,7 +252,8 @@ const int KartPropertiesManager::getKartId(const std::string &ident) const
|
||||
} // getKartId
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const KartProperties* KartPropertiesManager::getKart(const std::string &ident) const
|
||||
const KartProperties* KartPropertiesManager::getKart(
|
||||
const std::string &ident) const
|
||||
{
|
||||
const KartProperties* kp;
|
||||
for_in (kp, m_karts_properties)
|
||||
@ -227,12 +299,14 @@ void KartPropertiesManager::setUnavailableKarts(std::vector<std::string> karts)
|
||||
{
|
||||
if (!m_kart_available[i]) continue;
|
||||
|
||||
if (std::find(karts.begin(), karts.end(), m_karts_properties[i].getIdent())
|
||||
if (std::find(karts.begin(), karts.end(),
|
||||
m_karts_properties[i].getIdent())
|
||||
== karts.end())
|
||||
{
|
||||
m_kart_available[i] = false;
|
||||
|
||||
fprintf(stderr, "Kart '%s' not available on all clients, disabled.\n",
|
||||
fprintf(stderr,
|
||||
"Kart '%s' not available on all clients, disabled.\n",
|
||||
m_karts_properties[i].getIdent().c_str());
|
||||
} // kart not in list
|
||||
} // for i in m_kart_properties
|
||||
@ -242,13 +316,15 @@ void KartPropertiesManager::setUnavailableKarts(std::vector<std::string> karts)
|
||||
/** Returns the (global) index of the n-th kart of a given group. If there is
|
||||
* no such kart, -1 is returned.
|
||||
*/
|
||||
int KartPropertiesManager::getKartByGroup(const std::string& group, int n) const
|
||||
int KartPropertiesManager::getKartByGroup(const std::string& group,
|
||||
int n) const
|
||||
{
|
||||
int count=0;
|
||||
for (int i=0; i<m_karts_properties.size(); i++)
|
||||
{
|
||||
std::vector<std::string> groups = m_karts_properties[i].getGroups();
|
||||
if (std::find(groups.begin(), groups.end(), group) == groups.end()) continue;
|
||||
if (std::find(groups.begin(), groups.end(), group) == groups.end())
|
||||
continue;
|
||||
if (count == n) return i;
|
||||
count = count + 1;
|
||||
}
|
||||
@ -293,9 +369,13 @@ void KartPropertiesManager::selectKartName(const std::string &kart_name)
|
||||
} // selectKartName
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
const std::vector<int> KartPropertiesManager::getKartsInGroup(const std::string& g)
|
||||
/** Returns a vector with the indices of all karts in the specified group.
|
||||
* \param g The name of the group for which the kart indicies should be
|
||||
* determined
|
||||
* \return A vector of indices with the karts in the given group.
|
||||
*/
|
||||
const std::vector<int> KartPropertiesManager::getKartsInGroup(
|
||||
const std::string& g)
|
||||
{
|
||||
if (g == ALL_KART_GROUPS_ID)
|
||||
{
|
||||
@ -308,9 +388,9 @@ const std::vector<int> KartPropertiesManager::getKartsInGroup(const std::string&
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_groups[g];
|
||||
return m_groups_2_indices[g];
|
||||
}
|
||||
}
|
||||
} // getKartsInGroup
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns a list of randomly selected karts. This list firstly contains
|
||||
@ -323,8 +403,8 @@ const std::vector<int> KartPropertiesManager::getKartsInGroup(const std::string&
|
||||
* list of karts selected by the players.
|
||||
*/
|
||||
void KartPropertiesManager::getRandomKartList(int count,
|
||||
RemoteKartInfoList& existing_karts,
|
||||
std::vector<std::string> *ai_list)
|
||||
RemoteKartInfoList& existing_karts,
|
||||
std::vector<std::string> *ai_list)
|
||||
{
|
||||
// First: set up flags (based on global kart
|
||||
// index) for which karts are already used
|
||||
@ -332,7 +412,7 @@ void KartPropertiesManager::getRandomKartList(int count,
|
||||
std::vector<bool> used;
|
||||
used.resize(getNumberOfKarts(), false);
|
||||
|
||||
std::vector<std::string> randomKartQueue;
|
||||
std::vector<std::string> random_kart_queue;
|
||||
for (unsigned int i=0; i<existing_karts.size(); i++)
|
||||
{
|
||||
try
|
||||
@ -344,7 +424,8 @@ void KartPropertiesManager::getRandomKartList(int count,
|
||||
{
|
||||
(void)ex;
|
||||
std::cerr <<
|
||||
"[KartPropertiesManager] getRandomKartList : WARNING, can't find kart '"
|
||||
"[KartPropertiesManager] getRandomKartList : WARNING, "
|
||||
"can't find kart '"
|
||||
<< existing_karts[i].getKartName() << "'\n";
|
||||
}
|
||||
}
|
||||
@ -359,7 +440,8 @@ void KartPropertiesManager::getRandomKartList(int count,
|
||||
{
|
||||
(void)ex;
|
||||
std::cerr <<
|
||||
"[KartPropertiesManager] getRandomKartList : WARNING, can't find kart '"
|
||||
"[KartPropertiesManager] getRandomKartList : WARNING, "
|
||||
"can't find kart '"
|
||||
<< (*ai_list)[i] << "'\n";
|
||||
}
|
||||
}
|
||||
@ -367,41 +449,47 @@ void KartPropertiesManager::getRandomKartList(int count,
|
||||
do
|
||||
{
|
||||
// if we have no karts left in our queue, re-fill it
|
||||
if (count > 0 && randomKartQueue.size() == 0)
|
||||
if (count > 0 && random_kart_queue.size() == 0)
|
||||
{
|
||||
randomKartQueue.clear();
|
||||
std::vector<int> kartsInGroup = getKartsInGroup(UserConfigParams::m_last_used_kart_group);
|
||||
random_kart_queue.clear();
|
||||
std::vector<int> karts_in_group =
|
||||
getKartsInGroup(UserConfigParams::m_last_used_kart_group);
|
||||
|
||||
assert(kartsInGroup.size() > 0);
|
||||
assert(karts_in_group.size() > 0);
|
||||
|
||||
// first try not to use a kart already used by a player
|
||||
for (unsigned int i=0; i<kartsInGroup.size(); i++)
|
||||
for (unsigned int i=0; i<karts_in_group.size(); i++)
|
||||
{
|
||||
if (!used[kartsInGroup[i]] && m_kart_available[kartsInGroup[i]] &&
|
||||
!unlock_manager->isLocked(m_karts_properties[kartsInGroup[i]].getIdent()) )
|
||||
const KartProperties &kp=m_karts_properties[karts_in_group[i]];
|
||||
if (!used[karts_in_group[i]] &&
|
||||
m_kart_available[karts_in_group[i]] &&
|
||||
!unlock_manager->isLocked(kp.getIdent()) )
|
||||
{
|
||||
randomKartQueue.push_back(m_karts_properties[kartsInGroup[i]].getIdent());
|
||||
random_kart_queue.push_back(kp.getIdent());
|
||||
}
|
||||
}
|
||||
|
||||
// if we really need to, reuse the same kart as the player
|
||||
if (randomKartQueue.size() == 0)
|
||||
if (random_kart_queue.size() == 0)
|
||||
{
|
||||
for (unsigned int i=0; i<kartsInGroup.size(); i++)
|
||||
for (unsigned int i=0; i<karts_in_group.size(); i++)
|
||||
{
|
||||
randomKartQueue.push_back(m_karts_properties[kartsInGroup[i]].getIdent());
|
||||
const KartProperties &kp =
|
||||
m_karts_properties[karts_in_group[i]];
|
||||
random_kart_queue.push_back(kp.getIdent());
|
||||
}
|
||||
}
|
||||
|
||||
assert(randomKartQueue.size() > 0);
|
||||
assert(random_kart_queue.size() > 0);
|
||||
|
||||
std::random_shuffle(randomKartQueue.begin(), randomKartQueue.end());
|
||||
std::random_shuffle(random_kart_queue.begin(),
|
||||
random_kart_queue.end() );
|
||||
}
|
||||
|
||||
while (count > 0 && randomKartQueue.size() > 0)
|
||||
while (count > 0 && random_kart_queue.size() > 0)
|
||||
{
|
||||
ai_list->push_back(randomKartQueue.back());
|
||||
randomKartQueue.pop_back();
|
||||
ai_list->push_back(random_kart_queue.back());
|
||||
random_kart_queue.pop_back();
|
||||
count --;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ private:
|
||||
std::vector<std::string> m_all_groups;
|
||||
|
||||
/** Mapping of group names to list of kart indices in each group. */
|
||||
std::map<std::string, std::vector<int> > m_groups;
|
||||
std::map<std::string, std::vector<int> > m_groups_2_indices;
|
||||
|
||||
/** Vector containing kart numbers that have been selected in multiplayer
|
||||
* games. This it used to ensure the same kart can not be selected more
|
||||
@ -58,7 +58,6 @@ private:
|
||||
* all clients or not. */
|
||||
std::vector<bool> m_kart_available;
|
||||
|
||||
bool loadKart(const std::string &dir);
|
||||
protected:
|
||||
|
||||
typedef PtrVector<KartProperties> KartPropertiesVector;
|
||||
@ -75,9 +74,11 @@ public:
|
||||
int getKartByGroup(const std::string& group,
|
||||
int i) const;
|
||||
|
||||
bool loadKart (const std::string &dir);
|
||||
void loadAllKarts (bool loading_icon = true);
|
||||
void unloadAllKarts ();
|
||||
void reLoadAllKarts ();
|
||||
void removeKart(const std::string &id);
|
||||
const std::vector<int> getKartsInGroup (const std::string& g);
|
||||
bool kartAvailable(int kartid);
|
||||
std::vector<std::string> getAllAvailableKarts() const;
|
||||
|
@ -71,7 +71,6 @@ Track* TrackManager::getTrack(const std::string& ident) const
|
||||
return *i;
|
||||
}
|
||||
|
||||
std::cerr << "TrackManager: Couldn't find track: '" << ident << "'" << std::endl;
|
||||
return NULL;
|
||||
|
||||
} // getTrack
|
||||
@ -91,7 +90,8 @@ void TrackManager::setUnavailableTracks(const std::vector<std::string> &tracks)
|
||||
if (std::find(tracks.begin(), tracks.end(), id)==tracks.end())
|
||||
{
|
||||
m_track_avail[i-m_tracks.begin()] = false;
|
||||
fprintf(stderr, "Track '%s' not available on all clients, disabled.\n",
|
||||
fprintf(stderr,
|
||||
"Track '%s' not available on all clients, disabled.\n",
|
||||
id.c_str());
|
||||
} // if id not in tracks
|
||||
} // for all available tracks in track manager
|
||||
@ -161,7 +161,8 @@ bool TrackManager::loadTrack(const std::string& dirname)
|
||||
if(track->getVersion()<stk_config->m_min_track_version ||
|
||||
track->getVersion()>stk_config->m_max_track_version)
|
||||
{
|
||||
fprintf(stderr, "[TrackManager] Warning: track '%s' is not supported by this binary, ignored.\n",
|
||||
fprintf(stderr, "[TrackManager] Warning: track '%s' is not supported "
|
||||
"by this binary, ignored.\n",
|
||||
track->getIdent().c_str());
|
||||
delete track;
|
||||
return false;
|
||||
@ -173,6 +174,66 @@ bool TrackManager::loadTrack(const std::string& dirname)
|
||||
return true;
|
||||
} // loadTrack
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Removes a track.
|
||||
* \param ident Identifier of the track (i.e. the name of the directory).
|
||||
*/
|
||||
void TrackManager::removeTrack(const std::string &ident)
|
||||
{
|
||||
Track *track = getTrack(ident);
|
||||
std::vector<Track*>::iterator it = std::find(m_tracks.begin(),
|
||||
m_tracks.end(), track);
|
||||
assert(it!=m_tracks.end());
|
||||
int index = it - m_tracks.begin();
|
||||
|
||||
// Remove the track from all groups it belongs to
|
||||
Group2Indices &group_2_indices = track->isArena() ? m_arena_groups
|
||||
: m_track_groups;
|
||||
std::vector<std::string> &group_names = track->isArena()
|
||||
? m_arena_group_names
|
||||
: m_track_group_names;
|
||||
const std::vector<std::string>& groups=track->getGroups();
|
||||
for(unsigned int i=0; i<groups.size(); i++)
|
||||
{
|
||||
std::vector<int> &indices = group_2_indices[groups[i]];
|
||||
std::vector<int>::iterator j;
|
||||
j = std::find(indices.begin(), indices.end(), index);
|
||||
assert(j!=indices.end());
|
||||
indices.erase(j);
|
||||
|
||||
// If the track was the last member of a group,
|
||||
// completely remove the group
|
||||
if(indices.size()==0)
|
||||
{
|
||||
group_2_indices.erase(groups[i]);
|
||||
std::vector<std::string>::iterator it_g;
|
||||
it_g = std::find(group_names.begin(), group_names.end(),
|
||||
groups[i]);
|
||||
assert(it_g!=group_names.end());
|
||||
group_names.erase(it_g);
|
||||
} // if complete group must be removed
|
||||
} // for i in groups
|
||||
|
||||
// Adjust all indices of tracks with an index number higher than
|
||||
// the removed track, since they have been moved down. This must
|
||||
// be done for all tracks and all arenas
|
||||
for(unsigned int i=0; i<2; i++) // i=0: arenas, i=1: tracks
|
||||
{
|
||||
Group2Indices &g2i = i==0 ? m_arena_groups : m_track_groups;
|
||||
Group2Indices::iterator j;
|
||||
for(j=g2i.begin(); j!=g2i.end(); j++)
|
||||
{
|
||||
for(unsigned int i=0; i<(*j).second.size(); i++)
|
||||
if((*j).second[i]>index) (*j).second[i]--;
|
||||
} // for j in group_2_indices
|
||||
} // for i in arenas, tracks
|
||||
|
||||
m_tracks.erase(it);
|
||||
m_all_track_dirs.erase(m_all_track_dirs.begin()+index);
|
||||
m_track_avail.erase(m_track_avail.begin()+index);
|
||||
delete track;
|
||||
} // removeTrack
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Updates the groups after a track was read in.
|
||||
* \param track Pointer to the new track, whose groups are now analysed.
|
||||
@ -188,8 +249,10 @@ void TrackManager::updateGroups(const Track* track)
|
||||
if (isArena)
|
||||
{
|
||||
// update the list of group names if necessary
|
||||
const bool isInArenaGroupsList = (m_arena_groups.find(new_groups[i]) != m_arena_groups.end());
|
||||
if (!isInArenaGroupsList) m_arena_group_names.push_back(new_groups[i]);
|
||||
const bool isInArenaGroupsList =
|
||||
(m_arena_groups.find(new_groups[i]) != m_arena_groups.end());
|
||||
if (!isInArenaGroupsList)
|
||||
m_arena_group_names.push_back(new_groups[i]);
|
||||
|
||||
// add this track to its group
|
||||
m_arena_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
||||
@ -197,8 +260,10 @@ void TrackManager::updateGroups(const Track* track)
|
||||
else
|
||||
{
|
||||
// update the list of group names if necessary
|
||||
const bool isInTrackGroupsList = (m_track_groups.find(new_groups[i]) != m_track_groups.end());
|
||||
if (!isInTrackGroupsList) m_track_group_names.push_back(new_groups[i]);
|
||||
const bool isInTrackGroupsList =
|
||||
(m_track_groups.find(new_groups[i]) != m_track_groups.end());
|
||||
if (!isInTrackGroupsList)
|
||||
m_track_group_names.push_back(new_groups[i]);
|
||||
|
||||
// add this track to its group
|
||||
m_track_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
||||
|
@ -44,11 +44,12 @@ private:
|
||||
/** All track objects. */
|
||||
Tracks m_tracks;
|
||||
|
||||
typedef std::map<std::string, std::vector<int> > Group2Indices;
|
||||
/** List of all racing track groups. */
|
||||
std::map<std::string, std::vector<int> > m_track_groups;
|
||||
Group2Indices m_track_groups;
|
||||
|
||||
/** List of all arena groups. */
|
||||
std::map<std::string, std::vector<int> > m_arena_groups;
|
||||
Group2Indices m_arena_groups;
|
||||
|
||||
/** List of all groups (for both normal tracks and arenas) */
|
||||
//std::vector<std::string> m_all_group_names;
|
||||
@ -65,22 +66,18 @@ private:
|
||||
std::vector<bool> m_track_avail;
|
||||
|
||||
void updateGroups(const Track* track);
|
||||
bool loadTrack(const std::string& dirname);
|
||||
|
||||
public:
|
||||
TrackManager();
|
||||
~TrackManager();
|
||||
|
||||
static void addTrackSearchDir(const std::string &dir);
|
||||
|
||||
bool loadTrack(const std::string& dirname);
|
||||
|
||||
/** \brief Returns a list of all directories that contain a track. */
|
||||
const std::vector<std::string>* getAllTrackDirs() const
|
||||
{ return &m_all_track_dirs; }
|
||||
|
||||
/** \brief Returns a list of the names of all used groups (for tracks or arenas) */
|
||||
//const std::vector<std::string>&
|
||||
// getAllGroups() const { return m_all_group_names; }
|
||||
|
||||
/** \brief Returns a list of the names of all used track groups. */
|
||||
const std::vector<std::string>&
|
||||
getAllTrackGroups() const { return m_track_group_names; }
|
||||
@ -122,7 +119,10 @@ public:
|
||||
|
||||
/** Load all .track files from all directories */
|
||||
void loadTrackList();
|
||||
};
|
||||
|
||||
void removeTrack(const std::string &ident);
|
||||
|
||||
}; // TrackManager
|
||||
|
||||
extern TrackManager* track_manager;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user