From 96dc2a8fe2d0da43b356d693b8318770a49b1aa8 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 24 Aug 2009 05:56:53 +0000 Subject: [PATCH] Cleaned up StringUtils: used 'better' names (e.g. getPath() instead of path()), and used our convention of using capitalization for words (and not _). Started adding support for additional track directories, but that's not working yet. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3912 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/audio/music_information.cpp | 10 +-- src/audio/sound_manager.cpp | 6 +- src/challenges/challenge.cpp | 10 +-- src/challenges/unlock_manager.cpp | 6 +- src/graphics/material.cpp | 2 +- src/graphics/material_manager.cpp | 4 +- src/guiengine/widgets/spinner_widget.cpp | 8 +- src/input/input.cpp | 10 +-- src/io/file_manager.cpp | 37 +------- src/items/item_manager.cpp | 4 +- src/karts/kart_properties.cpp | 2 +- src/main.cpp | 72 ++++++++------- src/modes/world.cpp | 4 +- src/race/grand_prix_data.cpp | 2 +- src/race/grand_prix_manager.cpp | 2 +- src/states_screens/kart_selection.cpp | 19 ++-- src/tracks/track.cpp | 9 +- src/tracks/track_manager.cpp | 13 ++- src/tracks/track_manager.hpp | 3 + src/utils/string_utils.cpp | 107 +++++++++++++++++------ src/utils/string_utils.hpp | 32 +++---- 21 files changed, 204 insertions(+), 158 deletions(-) diff --git a/src/audio/music_information.cpp b/src/audio/music_information.cpp index ec144655d..a21e94b39 100644 --- a/src/audio/music_information.cpp +++ b/src/audio/music_information.cpp @@ -45,11 +45,11 @@ MusicInformation::MusicInformation(const std::string& filename) m_gain = 1.0f; m_adjustedGain = 1.0f; - if(StringUtils::extension(filename)!="music") + if(StringUtils::getExtension(filename)!="music") { // Create information just from ogg file // ------------------------------------- - m_title = StringUtils::without_extension(StringUtils::basename(filename)); + m_title = StringUtils::removeExtension(StringUtils::getBasename(filename)); m_normal_filename = filename; return; } @@ -87,7 +87,7 @@ MusicInformation::MusicInformation(const std::string& filename) m_adjustedGain = m_gain; // Get the path from the filename and add it to the ogg filename - std::string path=StringUtils::path(filename); + std::string path=StringUtils::getPath(filename); m_normal_filename=path+"/"+m_normal_filename; // Get the path from the filename and add it to the ogg filename @@ -120,7 +120,7 @@ void MusicInformation::startMusic() // First load the 'normal' music // ----------------------------- - if(StringUtils::extension(m_normal_filename)!="ogg") + if(StringUtils::getExtension(m_normal_filename)!="ogg") { fprintf(stderr, "WARNING: music file %s format not recognized.\n", m_normal_filename.c_str()); @@ -147,7 +147,7 @@ void MusicInformation::startMusic() return; // no fast music } - if(StringUtils::extension(m_fast_filename)!="ogg") + if(StringUtils::getExtension(m_fast_filename)!="ogg") { fprintf(stderr, "WARNING: music file %s format not recognized, fast music is ignored\n", diff --git a/src/audio/sound_manager.cpp b/src/audio/sound_manager.cpp index e24d90dae..72fa64278 100644 --- a/src/audio/sound_manager.cpp +++ b/src/audio/sound_manager.cpp @@ -108,8 +108,8 @@ void SoundManager::loadMusicFromOneDir(const std::string& dir) /*make_full_path*/ true); for(std::set::iterator i = files.begin(); i != files.end(); ++i) { - if(StringUtils::extension(*i)!="music") continue; - m_allMusic[StringUtils::basename(*i)] = new MusicInformation(*i); + if(StringUtils::getExtension(*i)!="music") continue; + m_allMusic[StringUtils::getBasename(*i)] = new MusicInformation(*i); } // for i } // loadMusicFromOneDir @@ -171,7 +171,7 @@ MusicInformation* SoundManager::getMusicInformation(const std::string& filename) { return NULL; } - const std::string basename = StringUtils::basename(filename); + const std::string basename = StringUtils::getBasename(filename); MusicInformation* mi = m_allMusic[basename]; if(!mi) { diff --git a/src/challenges/challenge.cpp b/src/challenges/challenge.cpp index 47988e496..42d34d95b 100644 --- a/src/challenges/challenge.cpp +++ b/src/challenges/challenge.cpp @@ -102,32 +102,32 @@ const std::string Challenge::getUnlockedMessage() const case UNLOCK_TRACK: { // {} avoids compiler warning Track* track = track_manager->getTrack( m_feature[n].name ); - message = StringUtils::insert_values( + message = StringUtils::insertValues( _("New track '%s'\nnow available"), _(track->getName().c_str()) ); break; } case UNLOCK_MODE: - message = StringUtils::insert_values( + message = StringUtils::insertValues( _("New game mode\n'%s'\nnow available"), m_feature[n].user_name); break; case UNLOCK_GP: { std::string gp_user_name = grand_prix_manager->getGrandPrix(m_feature[n].name)->getName(); - message = StringUtils::insert_values( + message = StringUtils::insertValues( _("New Grand Prix '%s'\nnow available"), gp_user_name); break; } case UNLOCK_DIFFICULTY: - message = StringUtils::insert_values( + message = StringUtils::insertValues( _("New difficulty\n'%s'\nnow available"), m_feature[n].user_name); break; case UNLOCK_KART: const KartProperties *kp=kart_properties_manager->getKart(m_feature[n].name ); - message = StringUtils::insert_values( + message = StringUtils::insertValues( _("New kart\n'%s'\nnow available"), kp->getName()); break; diff --git a/src/challenges/unlock_manager.cpp b/src/challenges/unlock_manager.cpp index 152e52fff..3587e50e5 100644 --- a/src/challenges/unlock_manager.cpp +++ b/src/challenges/unlock_manager.cpp @@ -46,7 +46,7 @@ UnlockManager::UnlockManager() for(std::set::iterator i = result.begin(); i != result.end() ; i++) { - if (StringUtils::has_suffix(*i, ".challenge")) + if (StringUtils::hasSuffix(*i, ".challenge")) addChallenge(file_manager->getConfigFile(*i)); } // for i @@ -70,7 +70,7 @@ UnlockManager::UnlockManager() } // Check for a challenge file std::string challenge_file = - StringUtils::without_extension(config_file)+".challenge"; + StringUtils::removeExtension(config_file)+".challenge"; FILE *f=fopen(challenge_file.c_str(), "r"); if(f) { @@ -110,7 +110,7 @@ UnlockManager::UnlockManager() for(std::set::iterator i = result.begin(); i != result.end() ; i++) { - if (StringUtils::has_suffix(*i, ".challenge")) + if (StringUtils::hasSuffix(*i, ".challenge")) addChallenge(file_manager->getConfigFile("grandprix/"+*i)); } // for i diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 9472917b3..20f9963e4 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -120,7 +120,7 @@ void Material::install(bool is_full_path) m_texture = irr_driver->getTexture(file_manager->getTextureFile(m_texname)); // now set the name to the basename, so that all tests work as expected - m_texname = StringUtils::basename(m_texname); + m_texname = StringUtils::getBasename(m_texname); } // isntall //----------------------------------------------------------------------------- diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 76f8a1941..13f3ad532 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -50,7 +50,7 @@ MaterialManager::MaterialManager() void MaterialManager::setAllMaterialFlags(video::ITexture* t, scene::IMeshBuffer *mb) const { - const std::string image = StringUtils::basename(t->getName().c_str()); + const std::string image = StringUtils::getBasename(t->getName().c_str()); // Search backward so that temporary (track) textures are found first for(int i = (int)m_materials.size()-1; i>=0; i-- ) { @@ -181,7 +181,7 @@ Material *MaterialManager::getMaterial(const std::string& fname, return NULL; } - std::string basename=StringUtils::basename(fname); + std::string basename=StringUtils::getBasename(fname); // Search backward so that temporary (track) textures are found first for(int i = (int)m_materials.size()-1; i>=0; i-- ) diff --git a/src/guiengine/widgets/spinner_widget.cpp b/src/guiengine/widgets/spinner_widget.cpp index da2a98a9c..6b416242a 100644 --- a/src/guiengine/widgets/spinner_widget.cpp +++ b/src/guiengine/widgets/spinner_widget.cpp @@ -86,7 +86,7 @@ void SpinnerWidget::add() { std::ostringstream icon_stream; icon_stream << file_manager->getDataDir() << "/" << m_properties[PROP_ICON]; - std::string imagefile = StringUtils::insert_values(icon_stream.str(), m_value); + std::string imagefile = StringUtils::insertValues(icon_stream.str(), m_value); ITexture* texture = irr_driver->getTexture(imagefile); assert(texture != NULL); @@ -144,7 +144,7 @@ void SpinnerWidget::move(const int x, const int y, const int w, const int h) // FIXME : code duplicated from add() std::ostringstream icon_stream; icon_stream << file_manager->getDataDir() << "/" << m_properties[PROP_ICON]; - std::string imagefile = StringUtils::insert_values(icon_stream.str(), m_value); + std::string imagefile = StringUtils::insertValues(icon_stream.str(), m_value); ITexture* texture = irr_driver->getTexture(imagefile); assert(texture != NULL); @@ -202,7 +202,7 @@ void SpinnerWidget::setValue(const int new_value) { std::ostringstream icon; icon << file_manager->getDataDir() << "/" << m_properties[PROP_ICON]; - std::string imagefile = StringUtils::insert_values(icon.str(), m_value); + std::string imagefile = StringUtils::insertValues(icon.str(), m_value); //((IGUIButton*)(m_children[1].m_element))->setImage(GUIEngine::getDriver()->getTexture(imagefile)); ((IGUIImage*)(m_children[1].m_element))->setImage(irr_driver->getTexture(imagefile)); } @@ -212,7 +212,7 @@ void SpinnerWidget::setValue(const int new_value) } else if(m_properties[PROP_TEXT].size() > 0) { - std::string text = StringUtils::insert_values(_(m_properties[PROP_TEXT].c_str()), m_value); + std::string text = StringUtils::insertValues(_(m_properties[PROP_TEXT].c_str()), m_value); m_children[1].m_element->setText( stringw(text.c_str()).c_str() ); } else diff --git a/src/input/input.cpp b/src/input/input.cpp index c691a57af..dc7901c57 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -476,23 +476,23 @@ std::string Input::getInputAsString(const Input::InputType type, const int id, c break; case Input::IT_STICKMOTION: //I18N : to appear in input configuration screen, for gamepad axes - s = StringUtils::insert_values( _("Axis %d %s"), id, (dir == Input::AD_NEGATIVE) ? '-' : '+'); + s = StringUtils::insertValues( _("Axis %d %s"), id, (dir == Input::AD_NEGATIVE) ? '-' : '+'); break; case Input::IT_STICKBUTTON: //I18N : to appear in input configuration screen, for gamepad buttons - s = StringUtils::insert_values( _("Gamepad button %d"), (id+1)); + s = StringUtils::insertValues( _("Gamepad button %d"), (id+1)); break; case Input::IT_STICKHAT: //I18N : to appear in input configuration screen, for gamepad hats - s = StringUtils::insert_values( _("Gamepad hat %d"), (id+1)); + s = StringUtils::insertValues( _("Gamepad hat %d"), (id+1)); break; case Input::IT_MOUSEBUTTON: //I18N : to appear in input configuration screen, for mouse (might not be used at all) - s = StringUtils::insert_values( _("Mouse button %d"), (id+1)); + s = StringUtils::insertValues( _("Mouse button %d"), (id+1)); break; case Input::IT_MOUSEMOTION: // FIXME : I don't reckon this is used at all //I18N : to appear in input configuration screen, for mouse (might not be used at all) - s = StringUtils::insert_values( _("Mouse axis %d %s"), + s = StringUtils::insertValues( _("Mouse axis %d %s"), (id+1), (dir == Input::AD_NEGATIVE) ? '-': '+' ); diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 25c67171e..7a2ff7c31 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -136,38 +136,7 @@ FileManager::FileManager() if(getenv("SUPERTUXKART_MUSIC_PATH")!=NULL) { std::string path=getenv("SUPERTUXKART_MUSIC_PATH"); - std::vector dirs=StringUtils::split(path,':'); - for(int i=(int)dirs.size()-1; i>=0; i--) - { - // Remove '/' at the end of paths, since this can cause - // problems with windows when using stat() - while(dirs[i].size()>=1 && dirs[i][dirs[i].size()-1]=='/') - { - dirs[i]=dirs[i].substr(0, dirs[i].size()-1); - } - // remove empty entries - if(dirs[i].size()==0) - { - dirs.erase(dirs.begin()+i); - continue; - } - } -#ifdef WIN32 - // Handle filenames like d:/dir, which becomes ["d","/dir"] - for(int i=(int)dirs.size()-1; i>=0; i--) - { - if(dirs[i].size()>1) continue; - if(i==dirs.size()-1) // last element - { - dirs[i]+=":"; // turn "c" back into "c:" - } - else - { - dirs[i]+=":"+dirs[i+1]; // restore "d:/dir" back - dirs.erase(dirs.begin()+i+1); - } - } -#endif + std::vector dirs = StringUtils::splitPath(path); for(int i=0;i<(int)dirs.size(); i++) pushMusicSearchPath(dirs[i]); } @@ -316,7 +285,7 @@ std::string FileManager::getTrackFile(const std::string& fname, // but if a track name is supplied use it (which is necessary // e.g. to load a model from a track directory std::string basename = (track_name!="") ? track_name - : StringUtils::without_extension(fname); + : StringUtils::removeExtension(fname); return getTrackDir()+"/"+basename+"/"+fname; } // getTrackFile @@ -328,7 +297,7 @@ std::string FileManager::getKartFile(const std::string& fname, // but if a kart name is supplied use it (which is necessary // e.g. to load a model from a kart directory std::string basename = (kart_name!="") ? kart_name - : StringUtils::without_extension(fname); + : StringUtils::removeExtension(fname); return getKartDir()+"/"+basename+"/"+fname; } // getKartFile diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index 052fd2153..f63daf5ef 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -89,10 +89,10 @@ void ItemManager::loadDefaultItems() for(std::set::iterator i = files.begin(); i != files.end(); ++i) { - if(StringUtils::extension(*i)!="b3d") continue; + if(StringUtils::getExtension(*i)!="b3d") continue; scene::IMesh *mesh = irr_driver->getAnimatedMesh(*i); if(!mesh) continue; - std::string shortName = StringUtils::basename(StringUtils::without_extension(*i)); + std::string shortName = StringUtils::getBasename(StringUtils::removeExtension(*i)); m_all_meshes[shortName] = mesh; mesh->grab(); } // for i diff --git a/src/karts/kart_properties.cpp b/src/karts/kart_properties.cpp index 24bd66dc4..d0812f074 100644 --- a/src/karts/kart_properties.cpp +++ b/src/karts/kart_properties.cpp @@ -119,7 +119,7 @@ void KartProperties::load(const std::string &filename, const std::string &node, } #else const lisp::Lisp* root = 0; - m_ident = StringUtils::basename(StringUtils::without_extension(filename)); + m_ident = StringUtils::getBasename(StringUtils::removeExtension(filename)); try { diff --git a/src/main.cpp b/src/main.cpp index e61ba5fd9..1cabdd38a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,38 +84,37 @@ void cmdLineHelp (char* invocation) "Run SuperTuxKart, a racing game with go-kart that features" " the Tux and friends.\n\n" "Options:\n" - " -N, --no-start-screen Quick race\n" - " -t, --track NAME Start at track NAME (see --list-tracks)\n" + " -N, --no-start-screen Immediatgely start race without showing a menu.\n" + " -t, --track NAME Start at track NAME (see --list-tracks).\n" " --stk-config FILE use ./data/FILE instead of ./data/stk_config.xml\n" - " -l, --list-tracks Show available tracks\n" - " -k, --numkarts NUM Number of karts on the racetrack\n" - " --kart NAME Use kart number NAME (see --list-karts)\n" - " --list-karts Show available karts\n" - " --laps N Define number of laps to N\n" - " --mode N N=1 novice, N=2 driver, N=3 racer\n" + " -l, --list-tracks Show available tracks.\n" + " -k, --numkarts NUM Number of karts on the racetrack.\n" + " --kart NAME Use kart number NAME (see --list-karts).\n" + " --list-karts Show available karts.\n" + " --laps N Define number of laps to N.\n" + " --mode N N=1 novice, N=2 driver, N=3 racer.\n" //FIXME" --players n Define number of players to between 1 and 4.\n" - //FIXME " --reverse Enable reverse mode\n" - //FIXME " --mirror Enable mirror mode (when supported)\n" - " --item STYLE Use STYLE as your item style\n" - " -f, --fullscreen Fullscreen display\n" - " -w, --windowed Windowed display (default)\n" - " -s, --screensize WxH Set the screen size (e.g. 320x200)\n" - " -v, --version Show version\n" + " --item STYLE Use STYLE as your item style.\n" + " -f, --fullscreen Select fullscreen display.\n" + " -w, --windowed Windowed display (default).\n" + " -s, --screensize WxH Set the screen size (e.g. 320x200).\n" + " -v, --version Show version of SuperTuxKart.\n" + " --trackdir DIR A directory from which additional tracks are loaded.\n" // should not be used by unaware users: - // " --profile Enable automatic driven profile mode for 20 seconds\n" - // " --profile=n Enable automatic driven profile mode for n seconds\n" - // " if n<0 --> (-n) = number of laps to drive - // " --history Replay history file 'history.dat'\n" + // " --profile Enable automatic driven profile mode for 20 seconds.\n" + // " --profile=n Enable automatic driven profile mode for n seconds.\n" + // " if n<0 --> (-n) = number of laps to drive. + // " --history Replay history file 'history.dat'.\n" // " --history=n Replay history file 'history.dat' using mode:\n" // " n=1: use recorded positions\n" // " n=2: use recorded key strokes\n" - " --server[=port] This is the server (running on the specified port)\n" - " --client=ip This is a client, connect to the specified ip address\n" - " --port=n Port number to use\n" - " --numclients=n Number of clients to wait for (server only)\n" - " --log=terminal Write messages to screen\n" - " --log=file Write messages/warning to log files stdout.log/stderr.log\n" - " -h, --help Show this help\n" + " --server[=port] This is the server (running on the specified port).\n" + " --client=ip This is a client, connect to the specified ip address.\n" + " --port=n Port number to use.\n" + " --numclients=n Number of clients to wait for (server only).\n" + " --log=terminal Write messages to screen.\n" + " --log=file Write messages/warning to log files stdout.log/stderr.log.\n" + " -h, --help Show this help.\n" "\n" "You can visit SuperTuxKart's homepage at " "http://supertuxkart.sourceforge.net\n\n", invocation @@ -123,8 +122,9 @@ void cmdLineHelp (char* invocation) } // cmdLineHelp //============================================================================= -// for base options that don't need much to be inited (and, in some cases, that need to -// be read before initing stuff) +/** For base options that don't need much to be inited (and, in some cases, + * that need to be read before initing stuff. + */ int handleCmdLinePreliminary(int argc, char **argv) { for(int i=1; isetLocalKartInfo(0, argv[i+1]); } fprintf ( stdout, "You chose to use kart '%s'.\n", argv[i+1] ) ; + i++; } else { @@ -379,9 +384,10 @@ int handleCmdLine(int argc, char **argv) { fprintf ( stdout, "You choose to have %d laps.\n", atoi(argv[i+1]) ) ; race_manager->setNumLaps(atoi(argv[i+1])); + i++; } /* FIXME: - else if ( !strcmp(argv[i], "--players") && i+1 4) { @@ -433,6 +439,12 @@ int handleCmdLine(int argc, char **argv) else if( !strcmp(argv[i], "--item") && i+1setUserFilename(argv[i+1]); + i++; + } + else if( !strcmp(argv[i], "--trackdir") && i+1addTrackDir(argv[i+1]); + i++; } // these commands are already processed in handleCmdLinePreliminary, but repeat this // just so that we don't get error messages about unknown commands diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 5e4d3d838..af5082da0 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -446,8 +446,8 @@ void World::removeKart(int kart_number) else { std::string s = _("'%s' has\nbeen eliminated."); - m_race_gui->addMessage( StringUtils::insert_values(s, kart->getName()), - *i, 2.0f, 60); + m_race_gui->addMessage(StringUtils::insertValues(s, kart->getName()), + *i, 2.0f, 60); } } // for i in kart if(kart->isPlayerKart()) diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index 97273c2c9..b3ae1f03c 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -32,7 +32,7 @@ GrandPrixData::GrandPrixData(const std::string filename) { m_filename = filename; - m_id = StringUtils::basename(StringUtils::without_extension(filename)); + m_id = StringUtils::getBasename(StringUtils::removeExtension(filename)); const lisp::Lisp* lisp = 0; try { diff --git a/src/race/grand_prix_manager.cpp b/src/race/grand_prix_manager.cpp index 0c7ad3c76..867dcb24b 100644 --- a/src/race/grand_prix_manager.cpp +++ b/src/race/grand_prix_manager.cpp @@ -34,7 +34,7 @@ GrandPrixManager::GrandPrixManager() for(std::set::iterator i = result.begin(); i != result.end() ; i++) { - if (StringUtils::has_suffix(*i, ".grandprix")) load("grandprix/"+*i); + if (StringUtils::hasSuffix(*i, ".grandprix")) load("grandprix/"+*i); } // for i } // GrandPrixManager diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 18af80d9a..10d5b53c4 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -84,7 +84,7 @@ namespace KartSelectionScreen this->playerID = playerID; // FIXME : if a player removes itself, all IDs need to be updated - this->m_properties[PROP_ID] = StringUtils::insert_values("@p%i", playerID); + this->m_properties[PROP_ID] = StringUtils::insertValues("@p%i", playerID); setSize(area->x, area->y, area->w, area->h); target_x = x; @@ -103,9 +103,10 @@ namespace KartSelectionScreen } playerIDLabel = new LabelWidget(); - playerIDLabel->m_properties[PROP_TEXT] = StringUtils::insert_values(_("Player %i ("), playerID + 1) + deviceName + ")"; + playerIDLabel->m_properties[PROP_TEXT] = + StringUtils::insertValues(_("Player %i ("), playerID + 1) + deviceName + ")"; playerIDLabel->m_properties[PROP_TEXT_ALIGN] = "center"; - playerIDLabel->m_properties[PROP_ID] = StringUtils::insert_values("@p%i_label", playerID); + playerIDLabel->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_label", playerID); playerIDLabel->x = player_id_x; playerIDLabel->y = player_id_y; playerIDLabel->w = player_id_w; @@ -119,7 +120,7 @@ namespace KartSelectionScreen playerName->w = player_name_w; playerName->h = player_name_h; - spinnerID = StringUtils::insert_values("@p%i_spinner", playerID); + spinnerID = StringUtils::insertValues("@p%i_spinner", playerID); const int playerAmount = UserConfigParams::m_all_players.size(); playerName->m_properties[PROP_MIN_VALUE] = "0"; @@ -137,7 +138,7 @@ namespace KartSelectionScreen modelView->y = model_y; modelView->w = model_w; modelView->h = model_h; - modelView->m_properties[PROP_ID] = StringUtils::insert_values("@p%i_model", playerID); + modelView->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_model", playerID); //modelView->setParent(this); m_children.push_back(modelView); @@ -154,7 +155,7 @@ namespace KartSelectionScreen kartName = new LabelWidget(); kartName->m_properties[PROP_TEXT] = default_kart; kartName->m_properties[PROP_TEXT_ALIGN] = "center"; - kartName->m_properties[PROP_ID] = StringUtils::insert_values("@p%i_kartname", playerID); + kartName->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_kartname", playerID); kartName->x = kart_name_x; kartName->y = kart_name_y; kartName->w = kart_name_w; @@ -673,8 +674,10 @@ void renumberKarts() g_player_karts[n].move( fullarea->x + splitWidth*n, fullarea->y, splitWidth, fullarea->h ); // FIXME: Not sure why this isn't updating the labels properly ?? - g_player_karts[n].getPlayerIDLabel()->m_properties[PROP_TEXT] = StringUtils::insert_values(_("Player %i ("), n + 1) + ")"; - g_player_karts[n].getPlayerIDLabel()->m_properties[PROP_ID] = StringUtils::insert_values("@p%i_label", n); + g_player_karts[n].getPlayerIDLabel()->m_properties[PROP_TEXT] = + StringUtils::insertValues(_("Player %i ("), n + 1) + ")"; + g_player_karts[n].getPlayerIDLabel()->m_properties[PROP_ID] = + StringUtils::insertValues("@p%i_label", n); } w->updateItemDisplay(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 2e1fede76..7e6ff0104 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -190,9 +190,8 @@ btTransform Track::getStartTransform(unsigned int pos) const void Track::loadTrack(const std::string &filename) { m_filename = filename; - m_ident = StringUtils::basename( - StringUtils::without_extension(m_filename)); - std::string path = StringUtils::without_extension(m_filename); + std::string path = StringUtils::removeExtension(m_filename); + m_ident = StringUtils::getBasename(path); // Default values m_use_fog = false; @@ -413,7 +412,7 @@ void Track::convertTrackToBullet(const scene::IMesh *mesh) TriangleMesh *tmesh = m_track_mesh; if(t) { std::string image = std::string(t->getName().c_str()); - material=material_manager->getMaterial(StringUtils::basename(image)); + material=material_manager->getMaterial(StringUtils::getBasename(image)); if(material->isZipper()) tmesh = m_non_collision_mesh; } @@ -509,7 +508,7 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml) video::ITexture* t=irrMaterial.getTexture(j); if(!t) continue; const std::string texture_name = - StringUtils::basename(t->getName().c_str()); + StringUtils::getBasename(t->getName().c_str()); if(texture_name!=name) continue; core::matrix4 *m = &irrMaterial.getTextureMatrix(j); m_animated_textures.push_back(new MovingTexture(m, *texture_node)); diff --git a/src/tracks/track_manager.cpp b/src/tracks/track_manager.cpp index 094fdf379..6bb55ae5d 100644 --- a/src/tracks/track_manager.cpp +++ b/src/tracks/track_manager.cpp @@ -31,7 +31,7 @@ TrackManager* track_manager = 0; -/** Constructor (currently empty). The real work happens in loadTrack. +/** Constructor (currently empty). The real work happens in loadTrackList. */ TrackManager::TrackManager() {} // TrackManager @@ -45,6 +45,17 @@ TrackManager::~TrackManager() delete *i; } // ~TrackManager +//----------------------------------------------------------------------------- +/** Adds a directory from which tracks are loaded. The track manager checks if + * either this directory itself contains a track, and if any subdirectory + * contains a track. + * \param dir The directory to add. + */ +void TrackManager::addTrackDir(const std::string &dir) +{ + m_track_dirs.push_back(dir); +} // addTrackDir + //----------------------------------------------------------------------------- /** Get TrackData by the track identifier. * \param ident Identifier = filename without .track diff --git a/src/tracks/track_manager.hpp b/src/tracks/track_manager.hpp index 33cbea86c..e398518ec 100644 --- a/src/tracks/track_manager.hpp +++ b/src/tracks/track_manager.hpp @@ -31,6 +31,8 @@ class Track; class TrackManager { private: + /** All directories in which tracks are searched. */ + std::vector m_track_dirs; typedef std::vector Tracks; Tracks m_tracks; std::map > m_groups; @@ -47,6 +49,7 @@ public: TrackManager(); ~TrackManager(); + void addTrackDir(const std::string &dir); const std::vector& getAllGroups() const { return m_all_groups; } size_t getNumberOfTracks() const { return m_tracks.size(); } diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index ba04101e7..8c53d81ef 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -27,7 +27,7 @@ namespace StringUtils { - bool has_suffix(const std::string& lhs, const std::string rhs) + bool hasSuffix(const std::string& lhs, const std::string rhs) { if (lhs.length() < rhs.length()) return false; @@ -36,10 +36,12 @@ namespace StringUtils // g++ versions (at least 2.95.3), which have a wrong template. To // avoid this issue, a more C-traditional way is used. return strcmp(lhs.c_str()+(lhs.length()-rhs.length()), rhs.c_str())==0; - } // has_suffix + } // hasSuffix -//--------------------------i--------------------------------------------------- - std::string path(const std::string& filename) + //--------------------------i----------------------------------------------- + /** Returns the path of a filename, i.e. everything till the last '/'. + */ + std::string getPath(const std::string& filename) { for(int i = int(filename.size()) - 1; i >= 0; --i) { @@ -49,10 +51,12 @@ namespace StringUtils } } return ""; - } // path + } // getPath -//----------------------------------------------------------------------------- - std::string basename(const std::string& filename) + //------------------------------------------------------------------------- + /** Returns the basename of a filename, i.e. everything after the last "/". + */ + std::string getBasename(const std::string& filename) { for(int i = int(filename.size()) - 1; i >= 0; --i) { @@ -62,10 +66,12 @@ namespace StringUtils } } return filename; - } // basename + } // getBasename -//----------------------------------------------------------------------------- - std::string without_extension(const std::string& filename) + //------------------------------------------------------------------------- + /** Removes the extension, i.e. everything after the last ".". + */ + std::string removeExtension(const std::string& filename) { for(int i = int(filename.size()) - 1; i >= 0; --i) { @@ -75,10 +81,12 @@ namespace StringUtils } } return filename; - } // without_extension + } // removeExtension -//----------------------------------------------------------------------------- - std::string extension(const std::string& filename) + //------------------------------------------------------------------------- + /** Returns the extension, i.e. everything after the last "." + */ + std::string getExtension(const std::string& filename) { for(int i = int(filename.size()) - 1; i >= 0; --i) { @@ -88,28 +96,25 @@ namespace StringUtils } } return filename; - } // extension + } // getExtension -//----------------------------------------------------------------------------- - std::string upcase (const std::string& str) + //------------------------------------------------------------------------- + /** Returns a string converted to upper case. + */ + std::string toUpperCase(const std::string& str) { std::string name = str; std::transform(name.begin(), name.end(), name.begin(), ::toupper); return name; - } // upcase + } // toUpperCase -//----------------------------------------------------------------------------- - std::string downcase (const std::string& str) - { - std::string name = str; - std::transform(name.begin(), name.end(), name.begin(), ::tolower); - return name; - } // downcase - -//----------------------------------------------------------------------------- -// Splits a string into substrings separated by a certain character, and -// returns a std::vector of all those substring. E.g.: -// split("a b=c d=e",' ') --> ["a", "b=c", "d=e"] + //----------------------------------------------------------------------------- + /** Splits a string into substrings separated by a certain character, and + * returns a std::vector of all those substring. E.g.: + * split("a b=c d=e",' ') --> ["a", "b=c", "d=e"] + * \param s The string to split. + * \param c The character by which the string is split. + */ std::vector split(const std::string& s, char c) { std::vector result; @@ -132,6 +137,50 @@ namespace StringUtils return result; } // split + // ------------------------------------------------------------------------ + /** Splits a : separated string (like PATH) into its individual components. + * It especially handles Windows-style paths (c:/mydir1:d:/mydir2) + * correctly, and removes a trailing "/" which can cause a problem with + * windows' stat function. + * \param path The string to split. + */ + std::vector splitPath(const std::string& path) + { + std::vector dirs=StringUtils::split(path,':'); + for(int i=(int)dirs.size()-1; i>=0; i--) + { + // Remove '/' at the end of paths, since this can cause + // problems with windows when using stat() + while(dirs[i].size()>=1 && dirs[i][dirs[i].size()-1]=='/') + { + dirs[i]=dirs[i].substr(0, dirs[i].size()-1); + } + // remove empty entries + if(dirs[i].size()==0) + { + dirs.erase(dirs.begin()+i); + continue; + } + } // for i +#ifdef WIN32 + // Handle filenames like d:/dir, which becomes ["d","/dir"] + for(int i=(int)dirs.size()-1; i>=0; i--) + { + if(dirs[i].size()>1) continue; + if(i==dirs.size()-1) // last element + { + dirs[i]+=":"; // turn "c" back into "c:" + } + else + { + dirs[i]+=":"+dirs[i+1]; // restore "d:/dir" back + dirs.erase(dirs.begin()+i+1); + } + } // for i +#endif + return dirs; + } // splitPath + // ------------------------------------------------------------------------ /** Converts a time in seconds into a string of the form mm:ss:hh (minutes, * seconds, 1/100 seconds. diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index b8a10c00e..b1267c336 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -28,19 +28,19 @@ namespace StringUtils { - bool has_suffix(const std::string& lhs, const std::string rhs); + bool hasSuffix(const std::string& lhs, const std::string rhs); /** Return the filename part of a path */ - std::string basename(const std::string& filename); + std::string getBasename(const std::string& filename); /** Return the path ( i.e. up to the last / ) */ - std::string path(const std::string& filename); + std::string getPath(const std::string& filename); - std::string without_extension(const std::string& filename); - std::string extension(const std::string& filename); + std::string removeExtension(const std::string& filename); + std::string getExtension(const std::string& filename); template - std::string to_string (const T& any) + std::string toString (const T& any) { std::ostringstream oss; oss << any ; @@ -56,7 +56,7 @@ namespace StringUtils fails false is returned and the value of \a x is unchanged, if true is returned the conversation was successfull. */ template - bool from_string(const std::string& rep, T& x) + bool fromString(const std::string& rep, T& x) { // this is necessary so that if "x" is not modified if the conversion fails T temp; @@ -74,9 +74,9 @@ namespace StringUtils } } - std::string upcase (const std::string&); - std::string downcase (const std::string&); + std::string toUpperCase(const std::string&); std::vector split(const std::string& s, char c); + std::vector splitPath(const std::string& path); // ------------------------------------------------------------------------ /** Replaces the first %s or %d in the string with the first value @@ -96,8 +96,8 @@ namespace StringUtils * \param v1,v2,v3 Value(s) to replace all %s or %d with. */ template - std::string insert_values(const std::string &s, const T1 &v1, - const T2 &v2, const T3 &v3) + std::string insertValues(const std::string &s, const T1 &v1, + const T2 &v2, const T3 &v3) { std::vector all_vals; std::ostringstream dummy; @@ -129,10 +129,10 @@ namespace StringUtils * \param v1,v2 Value(s) to replace all %s or %d with. */ template - std::string insert_values(const std::string &s, const T1 &v1, - const T2 &v2) + std::string insertValues(const std::string &s, const T1 &v1, + const T2 &v2) { - return insert_values(s, v1, v2, ""); + return insertValues(s, v1, v2, ""); } // ------------------------------------------------------------------------ /** Overloaded insert_values taking one value, see below for @@ -141,9 +141,9 @@ namespace StringUtils * \param v1 Value to replace. */ template - std::string insert_values(const std::string &s, const T1 &v1) + std::string insertValues(const std::string &s, const T1 &v1) { - return insert_values(s, v1, "", ""); + return insertValues(s, v1, "", ""); } } // namespace StringUtils