0

Everything compiles file. But when I step through the code in Visual Studio 12, the line where Boost checks if the folder actually exists jumps the else statement. The folder is in the correct path (same path as the .exe), and if I remember correctly, the same code worked in Ubuntu without a problem. I've read through the Boost documentation and I can't really see what I'm doing wrong.

main.cpp

#include "game.hpp"
#include "texturemanager.hpp"
#include "spritemanager.hpp"
#include "imagemanager.hpp"

int main()
{
  //Texture manager to hold all textures for the game. 
  TextureManager::GetInstance().LoadContent("Data/Images/Sprites");

  //Sprite manager to hold all backgrounds used in the game
  SpriteManager::GetInstance().LoadContent("Data/Images/Backgrounds");

  //Create the game. Takes in the parameters of the size of the screen
  Game game(640, 480);
  game.Run();
}

texturemanager.hpp

#ifndef TEXTUREMANAGER_HPP
#define TEXTUREMANAGER_HPP

#include <SFML/Graphics.hpp>
#include <map>
#include <string>
#include <memory>
#include <assert.h>
#include <boost/filesystem.hpp>

class TextureManager
{
public:
  typedef std::map<int, std::unique_ptr<sf::Texture>> resourceMap;

  //For creating a singleton class
  static TextureManager &GetInstance();

  //Load files from the folder loaded from the settings file
  void LoadContent(const std::string&);
  //Load files from folder and with a specific file name
  //To be added later to reduce memory usage
  //void LoadContent(const std::string&);

  //Get the texture
  const sf::Texture& Get(int) const;
  sf::Texture& Get(int);
protected:
private:
  //These are needed to create a singleton class
  TextureManager(){}
  TextureManager(TextureManager const&){}
  void operator=(TextureManager const&){}

  //Add a file to the resource map
  void Insert(boost::filesystem::path);

  //Hold the textures in memory
  resourceMap mTextureMap;
};

#endif

texturemanager.cpp

#include "texturemanager.hpp"

TextureManager& TextureManager::GetInstance()
{
  static TextureManager instance;
  return instance;
}

void TextureManager::LoadContent(const std::string& folder)
{
  //Create a temp vector for the file entries to go to
  std::vector<boost::filesystem::directory_entry> files;

  //Create the directory where all sprites will be stored
  boost::filesystem::path spriteDir(folder);

  spriteDir.make_preferred();

  //Check to see if the directory exists
  if(boost::filesystem::exists(spriteDir))
  {
    //Copy all of the entries into the directory vector
    copy(boost::filesystem::directory_iterator(spriteDir),
         boost::filesystem::directory_iterator(),
         back_inserter(files));
  }
  else
  {
    std::cout << folder + " Does not exist" << std::endl;
  }

  //Check to see if anything was stored
  if(files.size() > 0)
  {
    //Loop through each of the files
    for(unsigned int i = 0; i < files.size(); i++)
    {
      if(files[i].path().extension() == ".png")
      {
        //Convert the file to a string and push into vector
        Insert(files[i].path());
      }
    }
    //Empty the vector for reuse
    files.clear();
  }
}

void TextureManager::Insert(boost::filesystem::path tempFile)
{
  //Create and load resource
  std::unique_ptr<sf::Texture> tempTexture(new sf::Texture());

  if(!tempTexture->loadFromFile(tempFile.string()))
    throw std::runtime_error("ResourceHolder::load - Failed to load " + tempFile.string());


  std::string srtID = tempFile.stem().string();

  int id = std::atoi(srtID.c_str());

  //Insert and check success
  auto inserted = mTextureMap.insert(std::make_pair(id, std::move(tempTexture)));
  assert(inserted.second);
}
Jamal
  • 763
  • 7
  • 22
  • 32
Nuzut
  • 31
  • 6

1 Answers1

2

Relative paths are not relative to the executable itself, but relative to the working directory. So if you double click the exe the working directory will be set correctly to the same location as your executable, but if you start it in Visual Studio, it will use the working directory set in the settings. You find the option in your project settings under Debugging->Working Directory:

enter image description here

Unrelated to the question at hand, I strongly discourage you from using the singleton pattern for your texture manager, instead you should choose a design that doesn't require access to the manager from everywhere and reduce the dependencies as much as possible, thus making passing by const reference a good/clean way to go.

Lukas
  • 2,461
  • 2
  • 19
  • 32
  • Got bit by this one! Didn't even realize there was a distinction from the Working Directory of the debugger vs what the application path displayed in the titlebar of my console app. – jxramos Oct 06 '15 at 20:50