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

Author Topic: File System Support, Part II  (Read 10458 times)

0 Members and 1 Guest are viewing this topic.

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« on: March 03, 2011, 05:04:19 pm »
Hi,

while playing around with SFML again for some time now, I would like to have another try at making a file system support request (previous one I found isn't from me though).

As far as I can tell, any reasonably sized project needs access to two directories to behave well on the three main OSs (Win, Lin, Mac - sorry BSD guys ;-)):


    Some sort of resource directory for files included with the project - sprites, textures, models, you know what I mean.
    This would probably be ./ under Windows (i.e. the directory the executable lives in), the Resources folder inside the Mac OS X application bundle, or (I'm not too sure here) somewhere in /usr/local for Linux.


    A writeable directory for written config files, savegames and so on.
    This again might be %appdata%/MyProjectName (or in the user's My Files/My Games or what's it called) under Windows, Library/Application Support/MyProjectName for Mac OS X, and ~/.myprojectname for Linux


The thing is, the OS usually provides methods of getting these directories in a reliable and future-proof way, but these methods are highly OS specific and a pain to code in cross-platform projects. I did this for myself in OS X for now (found a snippet on the net), but that means using Objective-C++ code in my projects, which in turn meant having to use specific compiler flags and so on and was generally a PITA to get working.

This can not be done via boost::filesystem by the way, b::f should be used for path translation and all that, but it's still pretty platform agnostic when it comes to where data is/should be actually stored.

What I would propose is simply having a class providing static functions like GetResourceDir() and GetWriteableDir() that only return a String containing absolute paths to these directories for the given platform the project was compiled on. The rest (checking if the WriteableDir exists already, if not creating it, ...) should still be up to the user / b::f.

So, comments, what do you think? I don't think this would be too much outside SFML's current scope.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
File System Support, Part II
« Reply #1 on: March 03, 2011, 06:03:05 pm »
For now I'll say no, but I'll probably consider this kind of features in the future, when SFML 2 is out and the most important/big tasks that I plan to add are implemented.
Laurent Gomila - SFML developer

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
File System Support, Part II
« Reply #2 on: March 03, 2011, 06:10:39 pm »
physfs does some of this (at least for the write directory part)

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« Reply #3 on: March 03, 2011, 06:43:01 pm »
Quote from: "l0calh05t"
physfs does some of this (at least for the write directory part)


Thanks, I didn't know about that one. Even has a good license :-)
I'll take a look at it and see what I can get out of it.

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« Reply #4 on: March 03, 2011, 07:00:59 pm »
OK, physfs doesn't do very much of what I need. The only platform specific directory I can query gives me /Users/myusername, which is far from where I would and should be putting written files.

devlin

  • Full Member
  • ***
  • Posts: 128
    • View Profile
File System Support, Part II
« Reply #5 on: March 03, 2011, 07:28:27 pm »
Shouldn't you... you know... ask the player where to install?

I personally loathe games that just install themselves in some folder of their own choice. (doubly so since my %AppData% is on an SSD with very limited amount of space - I prefer to have all my games apart from the one I'm currently playing on another physical drive entirely).

I can see the usefulness of the stuff you're suggesting if it only has the purpose of providing a good first guess though. That being said, writing an installer for any given OS is probably better to do outside of SFML though (like InstallShield etc for Windows).

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« Reply #6 on: March 03, 2011, 08:02:35 pm »
I have nothing against making it configurable, and plan to do so, but that first guess is what I need.

Apart from that, I strongly think that the way modern OSs (OS X, Linux, Win >= Vista) organize files makes a lot of sense for a majority of the users. Meaning that there is a read-only directory for static files and executables (no accidental changes to files by users/users' processes), and a central place for configurations and other written data (easy transition to a new machine). The way it's done in general is the same across all platforms here, though it may be %appdata% and My Documents in two seperate directories or ~/ and ~/Library in one directory.
If you are a more advanced user wanting to do something different, sure, that's fine, but instead of hating the software, why not just create a symlink from the preconfigured place to where you want it to be? I do that all the time.

But as I said in the beginning, I like configurability and want to implement it. And installers should ask you where to install (though I like OS X' way of doing applications even more, but I'm biased here :-)). But I wasn't even talking about the installer, my proposition is completely post-install related.


To think a little further down the road, I could see OSs moving away from directory structures and to applications (think iOS), at least hiding the implementation for the majority of users. That would make it even more necessary to ask the OS where a certain type of file needs to be placed.

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
File System Support, Part II
« Reply #7 on: March 04, 2011, 01:39:10 pm »
Quote from: "devlin"
Shouldn't you... you know... ask the player where to install?

I personally loathe games that just install themselves in some folder of their own choice. (doubly so since my %AppData% is on an SSD with very limited amount of space - I prefer to have all my games apart from the one I'm currently playing on another physical drive entirely).

I can see the usefulness of the stuff you're suggesting if it only has the purpose of providing a good first guess though. That being said, writing an installer for any given OS is probably better to do outside of SFML though (like InstallShield etc for Windows).


Well, this is really only an issue in windows. In linux (and macosx if I am not mistaken) there are standard directories for everything.

For example a linux game:
executable in /usr/bin (depending on distribution this could also be /usr/games)
data in /usr/share/appname (depending on distribution this could also be /usr/share/games/appname )
and user files /home/username/.appname

You typically don't get to choose where things go. Of course since everything uses the same structure you can distribute your partition mount points smartly.

And show me a single windows game where you can decide separately where data and executable go ;) And properly designed games will use the user directories as well for saving (saving anywhere else is just wrong on a multiuser system...)

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« Reply #8 on: March 04, 2011, 01:45:11 pm »
Quote from: "l0calh05t"
Quote from: "devlin"
Shouldn't you... you know... ask the player where to install?

I personally loathe games that just install themselves in some folder of their own choice. (doubly so since my %AppData% is on an SSD with very limited amount of space - I prefer to have all my games apart from the one I'm currently playing on another physical drive entirely).

I can see the usefulness of the stuff you're suggesting if it only has the purpose of providing a good first guess though. That being said, writing an installer for any given OS is probably better to do outside of SFML though (like InstallShield etc for Windows).


Well, this is really only an issue in windows. In linux (and macosx if I am not mistaken) there are standard directories for everything.

For example a linux game:
executable in /usr/bin (depending on distribution this could also be /usr/games)
data in /usr/share/appname (depending on distribution this could also be /usr/share/games/appname )
and user files /home/username/.appname

You typically don't get to choose where things go. Of course since everything uses the same structure you can distribute your partition mount points smartly.

And show me a single windows game where you can decide separately where data and executable go ;) And properly designed games will use the user directories as well for saving (saving anywhere else is just wrong on a multiuser system...)


FULL ACK.

Windows does get better with time though. Well, they're only a few decades late to the game, right? ;-) Maybe they will someday switch to a Unix base as well, so we have a working useable command prompt on all systems (not serious, but one can dream).

"Real" OS X apps (meaning not CLI) don't separate executable and data though, everything is in one folder. The OS treats this folder as a file though, and you can run it everywhere (even from trash, as far as I know). It is a convention to put these bundles into ~/Applications or /Applications though, and most applications offer to do that for you if you if you run them from somewhere else.

Silvah

  • Guest
File System Support, Part II
« Reply #9 on: March 04, 2011, 06:41:50 pm »
Quote from: "Kolja"
Maybe they will someday switch to a Unix base as well, so we have a working useable command prompt on all systems (not serious, but one can dream).
But Windows already has working and usable shell (and it's IMO better than anything POSIX-compliant at the moment)...

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« Reply #10 on: March 04, 2011, 06:54:34 pm »
In my experience bash has always been preferable to cmd.exe, but I haven't really used the latter in quite some time. Does Windows have something like grep/ack installed by now? Always missed that. Program output is usually less easily machine readable as well (e.g. dir.exe vs ls).

What bothers me more is the missing POSIX compliancy, as there are many really good tools for these. But I guess in the end it comes down to preference as well, and we shouldn't let this thread degenerate into discussions about that.

But I'd be happy to see what I'm missing if you happen to have a good tutorial at hand. I'd try it out the next time I happen to use a Windows system.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: File System Support, Part II
« Reply #11 on: March 04, 2011, 07:11:42 pm »
Sorry if I skipped an important note in one post but I haven't got a lot of time these days...

Quote from: "Kolja"
A writeable directory for written config files, savegames and so on.
This again might be %appdata%/MyProjectName (or in the user's My Files/My Games or what's it called) under Windows, Library/Application Support/MyProjectName for Mac OS X, and ~/.myprojectname for Linux

You might want to have a look at what I've done
SFML / OS X developer

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: File System Support, Part II
« Reply #12 on: March 04, 2011, 07:23:03 pm »
Quote from: "Hiura"
Sorry if I skipped an important note in one post but I haven't got a lot of time these days...

Quote from: "Kolja"
A writeable directory for written config files, savegames and so on.
This again might be %appdata%/MyProjectName (or in the user's My Files/My Games or what's it called) under Windows, Library/Application Support/MyProjectName for Mac OS X, and ~/.myprojectname for Linux

You might want to have a look at what I've done


I assume you mean the CPD part of the link? Thanks for that, that's at least a way to do it for now. I'm not sure getenv() is the best way to go here though. And it doesn't solve the problem for the readonly directory, but that is mostly a OS X problem as the CWD for a graphically started application is / there for some reason.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
File System Support, Part II
« Reply #13 on: March 04, 2011, 07:34:43 pm »
Yes, that's cpd. It works pretty well but if you know something better than getenv let me know. ;-)

This might also help you with your readonly folder on OS X : http://www.sfml-dev.org/forum/viewtopic.php?p=28142#28142 (I'm not sure if the app bundle is really readonly...)
SFML / OS X developer

Kolja

  • Newbie
  • *
  • Posts: 22
    • View Profile
File System Support, Part II
« Reply #14 on: March 04, 2011, 07:44:23 pm »
Thanks for the link, but I'm already doing that in a similar way. But that is exactly the problem I mean, you need Cocoa, .mm files and so on, and I think this is a small (and limited) field of objectives where SFML should provide a few helper functions to minimize the need for platform specific code (and what application using SFML doesn't need data files?).

Oh, and no, the Bundle is not read-only, but configuration files shouldn't be stored in there so that the user can delete and reinstall applications and their settings are remembered. But I'm not exactly sure about bundles installed to /Applications that are used by non-admin users. They should be read-only again, but again, not sure there.

And I have something better, at least for OS X:

Code: [Select]
std::string cfstringToStdString(const CFStringRef cfstr) {
  CFIndex bufferLength = 1 + CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8);
  char* buffer = new char[bufferLength];
  CFStringGetCString(cfstr, buffer, bufferLength, kCFStringEncodingUTF8);
  std::string result = buffer;
  delete[] buffer;
  return result;
}  


std::string getDataPath() {
  NSArray* allPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
  CFStringRef path = (CFStringRef)[allPaths objectAtIndex:0];
  return cfstringToStdString(path);
}


That should be the official way to do it.

[edit]
Just to be clear, that snipped needs #import <Cocoa/Cocoa.h> and compilation as an Objective-C(++) file.