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

Author Topic: SFML 2.0 Mac OSX in App Bundle  (Read 17974 times)

0 Members and 1 Guest are viewing this topic.

zenkimoto

  • Newbie
  • *
  • Posts: 17
    • View Profile
SFML 2.0 Mac OSX in App Bundle
« on: March 02, 2011, 07:24:14 am »
Hello,

I realize that the instructions say to create a new C++ command line project and include the dynamic/static libraries from cmake.  I got everything to work doing it that way.  However, is it possible to build a bundle with 2.0?  

I tried to create a new Cocoa project, modify it to include all the SFML libraries.  So far so good.  Everything works except for my working directory...  I have to reference:  "TestSFML.app/Contents/Resources/testimage.png" instead of just "testimage.png".  It seems that the working directory is where the bundle is located.  Anyways, I could be doing it all wrong....

I'm really just wondering if it is possible to build a bundle with 2.0 or do I just need to do a chdir() system call.  

Thanks!

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #1 on: March 04, 2011, 07:19:41 pm »
I've got two news for your.

First, the good news : Yes, you can do that.

Seconde, the good news : you can use this function to get the resource directory path :

Code: [Select]
// RessourcesDirectory.hpp

#ifndef RESSOURCESDIRECTORY_H
#define RESSOURCESDIRECTORY_H

#include <string>

std::string GetRPath(void);

#endif


Code: [Select]
// RessourcesDirectory.mm

#include "RessourcesDirectory.hpp"
#import <Foundation/Foundation.h>

std::string GetRPath(void) {
    // Get the resources dir path.
std::string rpath;
NSBundle* bundle = [NSBundle mainBundle];
if (bundle == nil) {
NSLog(@"bundle is nil... thus no resources path can be found.");
} else {
NSString* path = [bundle resourcePath];
rpath = [path UTF8String] + std::string("/");
}
   
    return rpath;
}


Just add these two files into your project (watch out : the second file extension has to be .mm).

Have fun.
SFML / OS X developer

zenkimoto

  • Newbie
  • *
  • Posts: 17
    • View Profile
SFML 2.0 Mac OSX in App Bundle
« Reply #2 on: March 04, 2011, 10:43:41 pm »
Hiura:

Thanks for your reply!!  Haha, so it's all around good news?


I will give that a try.  Thanks for the code to get the path of the resources directory.  

So, do we have to include this function to get the resource path from SFML 2.0+?  The project template from 1.6 did not require this.  Did 1.6 change the working directory to the resources folder on a OS X build?

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #3 on: March 05, 2011, 12:00:15 am »
Quote from: "zenkimoto"
Did 1.6 change the working directory to the resources folder on a OS X build?


Yup. But I dunno whether Hiura wishes to do so for SFML 2.0.
Want to play movies in your SFML application? Check out sfeMovie!

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #4 on: March 05, 2011, 08:23:09 am »
I haven't made up my mind yet but currently I don't think I'll change the working dir. The problem is – of that I know – if there is at least one application which needs the 'correct' working dir then I should not change it.

But you still can argue with me and make me change my mind.  :wink:
SFML / OS X developer

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #5 on: March 05, 2011, 12:56:20 pm »
To my mind:

The Resources directory should be the working directory because the equivalent to the data directory next to the Windows executable IS the Resources directory in Mac OS X. Thus it allows you to put a data directory next to your exe on Windows, like you usually have all of your data in the Resources directory of the app on Mac OS X. And for both, you'll ask to open the image "data/something.png" for example.

Now.. why would one wish to read/write next to the app... in my opinion it's not a good idea. Especially because you don't know where the user put the app (thus you don't know whether you can write), and well.. I can't see any reason why you'd need to read next to the app. Because I suppose that would be some data for the app, and that should always be in the Resources directory or in some other specific directory of the OS. And if it's a user document, then you have to ask him where it is, like in any document-based application.

Besides, with SFML 1, I've never ever seen someone needing to read/write next to the app. "Probably" because of these reasons.
Want to play movies in your SFML application? Check out sfeMovie!

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #6 on: March 05, 2011, 01:51:59 pm »
Sorry, I'm not convinced (yet).

Quote from: "Ceylo"
The Resources directory should be the working directory because the equivalent to the data directory next to the Windows executable IS the Resources directory in Mac OS X.
If some OS(es) have a poor design we might not want to copy it – or, in this case, behave likewise – but let the user have the choice event if it means the user can make a bad choice. IMO, forcing the user to use/do/... something is bad.

Quote from: "Ceylo"
Thus it allows you to put a data directory next to your exe on Windows, like you usually have all of your data in the Resources directory of the app on Mac OS X. And for both, you'll ask to open the image "data/something.png" for example.
No offence, but this is kind of a poor app design : it's clearly more powerful to use abstraction here (e.g. have a 'give_me_my_wonderful_resources_directory_path' function). More generally, if you have any resources path it's way more convenient to update the path only in one place when you move the resources (e.g. you create a new subdirectory).

Quote from: "Ceylo"
Now.. why would one wish to read/write next to the app... in my opinion it's not a good idea.
So we shouldn't use the app working dir on Windows to store our data. Thus we won't use it on OS X too. Hence we don't need this feature.

I'm teasing a little bit but this is quite an interesting topic so don't hesitate to push me around too. :wink:
SFML / OS X developer

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #7 on: March 05, 2011, 02:13:57 pm »
Quote from: "Hiura"
Sorry, I'm not convinced (yet).

Quote from: "Ceylo"
The Resources directory should be the working directory because the equivalent to the data directory next to the Windows executable IS the Resources directory in Mac OS X.
If some OS(es) have a poor design we might not want to copy it – or, in this case, behave likewise – but let the user have the choice event if it means the user can make a bad choice. IMO, forcing the user to use/do/... something is bad.

The user is not forced. He can still do chdir("../../.."), which is quite easier than finding the full path of the application, and adding "name.app/Contents/Resources".

Quote from: "Hiura"
No offence, but this is kind of a poor app design : it's clearly more powerful to use abstraction here (e.g. have a 'give_me_my_wonderful_resources_directory_path' function). More generally, if you have any resources path it's way more convenient to update the path only in one place when you move the resources (e.g. you create a new subdirectory).

I'm not sure I perfectly understand but.. what prevents you from setting your "wonderful resources directory path" as working directory, whatever you decide to do with SFML? What I mean is that in most cases the Resources directory is the best place to put your data, and that's why it should be the default working directory for SFML apps. This, however, does not prevent you from using another working directory for your app.
Want to play movies in your SFML application? Check out sfeMovie!

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #8 on: March 05, 2011, 02:48:53 pm »
Quote from: "Ceylo"
The user is not forced. He can still do chdir("../../.."), which is quite easier than finding the full path of the application, and adding "name.app/Contents/Resources".
It still looks hacky... in both ways (SFML change or user change).

I think we are mixing up the meaning of 'working directory'. Are we working in our resources directory or elsewhere ? Must we work in our resources directory or not ? I think that's two separate thing and we shouldn't change this. But still – I might be wrong.

I'm not looking for the most easy thing for the user but for the most logical. And on that point I'm still not sure what is the most logical.
SFML / OS X developer

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #9 on: March 05, 2011, 02:58:31 pm »
Quote from: "Hiura"
I'm not looking for the most easy thing for the user but for the most logical. And on that point I'm still not sure what is the most logical.

Uh.. okay. I was rather thinking with usability in mind.


Thus.. I can't say whether the Resources directory is the one you should "work" in, but it's definitely the one where you should "read" your app resources (with the reasons I gave earlier).
Want to play movies in your SFML application? Check out sfeMovie!

zenkimoto

  • Newbie
  • *
  • Posts: 17
    • View Profile
SFML 2.0 Mac OSX in App Bundle
« Reply #10 on: March 05, 2011, 08:05:40 pm »
Oh sorry!  I didn't mean to start a war here! :-)

I just looked at the 1.6 code and I found where it checks for the resources directory.  

Now, let me add a few thoughts.  Application bundles are the standard way of building apps in OS X.  In a Mac OS X bundle, the resources directory is where all the assets exist.  Now, I don't think it is bad/good design, but a different design; it's just different from your typical Windows, Linux, etc application.

Now my opinion...  I would have to agree with Ceylo here and let me tell you why.  SFML is supposed to be a cross platform library.  The library itself should handle all the idiosyncrasies of the various platforms.  For instance, as a user of SFML and if I were to write code for say Windows and Mac OS X, I would have to do this now:

#IF WIN32
Image.LoadFromFile("image.png");
#ELSE IF OSX
Image.LoadFromFile(GetResourcesDirectory() + "image.png");
#ENDIF

Basically you get the idea.  The user of the cross platform library would need to differentiate which system he/she is using.  Using the 1.6 method, Image.LoadFromFile("image.png") would work across any system and it wouldn't matter as the same C++ code would work.

zenkimoto

  • Newbie
  • *
  • Posts: 17
    • View Profile
SFML 2.0 Mac OSX in App Bundle
« Reply #11 on: March 05, 2011, 08:13:48 pm »
What about a compromise where we instead of changing the working directory, we append the "application.app/Contents/Resources" to the path when loading assets if the application is a Mac OS X bundle?

zenkimoto

  • Newbie
  • *
  • Posts: 17
    • View Profile
SFML 2.0 Mac OSX in App Bundle
« Reply #12 on: March 05, 2011, 08:21:22 pm »
Here I am adding fuel to the flame war.  Haha :-)

Anyways, I just wanted to add one more thing.  I checked the SDL library to see how they handle Mac OS X bundles, they essentially check to see if the application is a bundle, if not then fall back on the working directory.

Let me copy and paste the code here:


Code: [Select]

#ifdef __APPLE__
#import <Foundation/Foundation.h>

#include "SDL_rwopsbundlesupport.h"

/* For proper OS X applications, the resources are contained inside the application bundle.
 So the strategy is to first check the application bundle for the file, then fallback to the current working directory.
 Note: One additional corner-case is if the resource is in a framework's resource bundle instead of the app.
 We might want to use bundle identifiers, e.g. org.libsdl.sdl to get the bundle for the framework,
 but we would somehow need to know what the bundle identifiers we need to search are.
 Also, note the bundle layouts are different for iPhone and Mac.
*/
FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
{
    FILE* fp = NULL;

// If the file mode is writable, skip all the bundle stuff because generally the bundle is read-only.
if(strcmp("r", mode) && strcmp("rb", mode))
{
return fopen(file, mode);
}

NSAutoreleasePool* autorelease_pool = [[NSAutoreleasePool alloc] init];


NSFileManager* file_manager = [NSFileManager defaultManager];
NSString* resource_path = [[NSBundle mainBundle] resourcePath];

NSString* ns_string_file_component = [file_manager stringWithFileSystemRepresentation:file length:strlen(file)];

NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
if([file_manager fileExistsAtPath:full_path_with_file_to_try])
{
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
}
else
{
fp = fopen(file, mode);
}

[autorelease_pool drain];

return fp;
}
#endif

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #13 on: March 05, 2011, 10:40:11 pm »
Quote from: "zenkimoto"
Oh sorry!  I didn't mean to start a war here! :-)
No, don't be sorry! It's very good in fact : I'd like to make the better port as I can so if you help me with idea I'm happy.

Quote from: "zenkimoto"
What about a compromise where we instead of changing the working directory, we append the "application.app/Contents/Resources" to the path when loading assets if the application is a Mac OS X bundle?
This cannot be done in SFML the same way it is done in SDL (it would mean I have to modify Image, Sound, Music, ...).

Quote
#IF WIN32
Image.LoadFromFile("image.png");
#ELSE IF OSX
Image.LoadFromFile(GetResourcesDirectory() + "image.png");
#ENDIF
I agree : it would be shorter for the user. Notice I said 'shorter' and not 'easier' as it is not very complicated at all (just copy/past the code above). But the problem persists with Unix : a "good" application will be installed in /usr subdirectories (bin/share/... I don't know exactly), won't it ?
SFML / OS X developer

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
SFML 2.0 Mac OSX in App Bundle
« Reply #14 on: March 05, 2011, 10:53:03 pm »
Quote from: "zenkimoto"
What about a compromise where we instead of changing the working directory, we append the "application.app/Contents/Resources" to the path when loading assets if the application is a Mac OS X bundle?

To me this doesn't really change the issue. You shouldn't have to change anything in order to build your app for both Windows and Mac OS X. And in both case, you should be able to use the default repository for each OS, not something specific to SFML.
Want to play movies in your SFML application? Check out sfeMovie!