Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Facility to get standard paths  (Read 18725 times)

0 Members and 1 Guest are viewing this topic.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Facility to get standard paths
« Reply #15 on: August 28, 2015, 11:43:31 am »
It's on my list once some current issues (both SFML and work code) are fixed. :)

silverweed

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Re: Facility to get standard paths
« Reply #16 on: September 15, 2015, 12:31:31 pm »
Is there already any idea how would this be implemented in the API? Global namespaced variables like sf::Path::Home? Also, would we also need some basic functions to check if a path exists/create a directory/etc in a portable way?

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Facility to get standard paths
« Reply #17 on: September 15, 2015, 03:25:34 pm »
You'd most likely construct a "sf::Path" object, which would essentially be a string representation of a path providing some additional features, such as concatenation, access to attributes, etc.

Some mockup stuff, nothing decided or even set in stone yet:

// On Windows this would produce something like "C:\Users\Mario\Documents\My Awesome SFML Game"
// On Linux this would be "~/My Awesome SFML Game"
sf::Path localPath = sf::Path::Documents + "My Awesome SFML Game";

// Load a texture from below working directory
sf::Path assetPath = sf::Path::WorkingDirectory + ".." + "data";
texture.loadFromFile(assetPath + "texture.png");

// Iterate over all file system entries
for (auto &filepath : (localPath + "saves").getFiles())
{
    // ...
}
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Facility to get standard paths
« Reply #18 on: September 15, 2015, 04:10:12 pm »
Variables are a bad idea, they limit the initialization to static functions run at program startup. Use functions and you have the full flexibility: either compute paths on-demand, or at program startup, or on first use.

Furthermore, I think you're underestimating the complexity of a sf::Path in a boost::filesystem::path style manner. Even seemingly simple operations like reducing a path (./dir/.. to .) can hide a lot of pitfalls, see here for example. Things like symbolic links and their platform difference add further to the complexity; in the end SFML would need a filesystem library as a backend. As long as the class doesn't provide much more than string concatenation, we can as well use strings directly.

Jesper Juhl, you said you could provide a proof-of-concept, do you still have the time and motivation? :)
« Last Edit: September 15, 2015, 04:14:04 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Facility to get standard paths
« Reply #19 on: September 15, 2015, 07:33:30 pm »
Meh, I'm too spoiled from being able to write getters. :D

Path complexity: Haven't taken a look at boost's implementation, but similar to other SFML stuff, I think just the most common basics should be enough. It doesn't have to be a full fledged out implementation where you're able to set or access every tidbit.

Regarding path alternatives resolving to the same real path (like using "." or ".."): On Windows there are API calls to resolve all of these. I'm not sure about the other systems, but there should be something like that I guess.

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: Facility to get standard paths
« Reply #20 on: September 15, 2015, 09:10:28 pm »
I made my own Path sort of class implementations. Path reduction was not that hard, as Mario said about API calls, both Windows and Linux have functions to get the "realpath" (as Linux calls it) from a path string.

Linux
Windows

If inspiration is needed/desired/wanted/etc, here's mine. It's not quite complete. I think I didn't get into much permissions stuff on Windows, and I don't have an OSX machine, so that is lacking.

Here's an example of using it:
(click to show/hide)

PS: Just to make it clear, I'm not intending to step on anyone's toes, or force my project on to you guys. I'm just offering another example of how someone else did it, and a place to get guidance/etc from!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Facility to get standard paths
« Reply #21 on: September 15, 2015, 09:25:41 pm »
Maybe asked differently: why not a string, why do we need a dedicated path class?

Keep in mind that we're discussing about getting standard paths here, not about providing filesystem functionality like resolving symlinks, checking the type of a file, etc.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Facility to get standard paths
« Reply #22 on: September 15, 2015, 09:32:28 pm »
I haven't been able to find the time to implement anything yet (although I've implemented all of these in the past for AiX, Solaris, Linux, OS X and Windows, so I know it is possible), but originally I was thinking of something like:
string getExecPath(); // full path to executable (/proc/self/exe)
string getExecDir(); // directory containing executable
string getCWD(); // get current working directory
string getHomeDir(); // users home dir $HOME or %HOME%
string getTempDir(); // /tmp, /var/tmp or %TEMP%
string getDataDir(); // /var/app/foo or %APPDATA%
string getRootDir(); // C:/ or /
 
« Last Edit: September 16, 2015, 08:21:28 am by Jesper Juhl »

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: Facility to get standard paths
« Reply #23 on: September 15, 2015, 11:44:33 pm »
On Android you would only have 3 path which are useful.
  • Assets storage, only available through the assetsmanager because it's inside the APK (zip compressed)
  • Internal Storage, it's like a home directory for every app. The path is stored in the ANativeActivity as const char*
  • External Storage (SD card or similar), only available if the the app has read/write right for the external folder, which can be set in the manifest. This path is also stored in the ANativeActivity as const char*

I don't know what you should do for the other paths listed in Jesper's last post, because I'm not even sure if you have read access of the root folder etc. (can't test it at the moment).

So you should definitly keep that limitation in your mind when deciding the final API



AlexAUT

silverweed

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Re: Facility to get standard paths
« Reply #24 on: September 16, 2015, 09:36:29 am »
Variables are a bad idea, they limit the initialization to static functions run at program startup. Use functions and you have the full flexibility: either compute paths on-demand, or at program startup, or on first use.
That's true, but since the idea is to get "standard" paths, how complicated should it get to initialize those paths?

I think the question which needs to be sorted out first is: should we just provide those paths (either as objects, variables or getter functions), without bothering to check if they actually exist on the machine SFML is installed on, or should we also ensure the paths we retreive from the API are always valid?

Of course from the user's viewpoint the second choice is the obvious one but, as you said before, it can get pretty complicated to implement, while the first option would be slightly less than trivial if I'm not mistaken.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Facility to get standard paths
« Reply #25 on: September 16, 2015, 10:02:12 am »
Quote
That's true, but since the idea is to get "standard" paths, how complicated should it get to initialize those paths?
Since you most likely have to do system calls, doing them at global startup may be impossible on some OSes, like Android and iOS. We must use functions to keep maximum flexibility for implementation.

Quote
I think the question which needs to be sorted out first is: should we just provide those paths (either as objects, variables or getter functions), without bothering to check if they actually exist on the machine SFML is installed on, or should we also ensure the paths we retreive from the API are always valid?
Since we don't want to turn SFML into another filesystem library, I'd say just provide the paths.
Laurent Gomila - SFML developer

silverweed

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Re: Facility to get standard paths
« Reply #26 on: September 16, 2015, 11:23:15 am »
Since we don't want to turn SFML into another filesystem library, I'd say just provide the paths.
Yeah, seems the best choice to me too.

Klaim

  • Full Member
  • ***
  • Posts: 137
    • View Profile
Re: Facility to get standard paths
« Reply #27 on: September 19, 2015, 03:32:30 am »
Quote
I think the question which needs to be sorted out first is: should we just provide those paths (either as objects, variables or getter functions), without bothering to check if they actually exist on the machine SFML is installed on, or should we also ensure the paths we retreive from the API are always valid?
Since we don't want to turn SFML into another filesystem library, I'd say just provide the paths.

By the way, the unicode mess on Windows might be a major issue for providing any kind of path using just std::string. The basic issue is that if the path have unicode characters, they are provided by the Windows API as either UTF-16 in wide chars, or as ANSI something in chars with non-ansi characters replaced by '?'.
Therefore, you need to use the UTF-16 way on Windows to get something useful, then you need to decide what is the encoding of your output std::string, then convert from one to the other.
The solution boost::filesystem took is to keep the internal representation of the system (UTF-16 on windows) to avoid conversions as much as possible, but then if you as a string from it it will do a dumb conversion OR use a codecvt you provide, which migth do the right thing (or not). Unfortunately there is a strange behaviour where no conversion happen if the type used for storage (char/wchar_t) is same between the two encodings (which mean that a linux OS which is not UTF-8 might have no conversion, or I'm wrong, which might be possible for these kinds of details which I couldn't manage to properly check so far).
In my dayjob I had to work on these kind of issues recently. We chose that any std::string in the API is expected to be UTF-8. We have a path type which currently uses boost:::filesystem::path inside (it's open source by the way but I wouldn't call it a perfect example), then do the conversion when you need a string (so UTF-8) depending on the plateform we are on, so that whatever the boost representation, we always end up with UTF-8.

I don't know what is the policy of SFML regarding encoding of API-provided strings, but if there is none, providing a system paths api will requires that.

 

anything