Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS: search for data within .app bundle if not found besides app #7361

Closed
wants to merge 1 commit into from

Conversation

artificiel
Copy link
Contributor

@artificiel artificiel commented Mar 2, 2023

(this started as an issue, morphed into a discussion, but since I had super-circumscribed and functional code on hand to support the argument I went for the PR)

when bundling stuff with OF_BUNDLE_DATA_FOLDER = 1 in macOS, things in there are not automatically found at runtime.

this PR augments defaultDataPath() to check if there is a ../Resources/data/ if the usual one fails.

NOTE: this means that a data directory besides an app will override one that would have been internally bundled -- it could lead to confusion if by coincidence a user has a data folder besides the app. however there is also value to being able to conveniently override the internal data (less hassle than fishing in the package contents).

  1. maybe it should be the other way around? (bundled has precedence if it exists? no confusion possible) but then it means most of the times exceptions are triggered to fall back on the traditional external data. (maybe not dramatic as file access is generally not a hot spot?)

  2. or maybe a compile-time #define would switch between cases based on if OF_BUNDLE_DATA_FOLDER = 1? so the app is built coherently for only one case? not sure what would be the pattern for that.

  3. BUT... maybe the real fix is to work at higher level and allow multiple data folders: not look for the existence of a data folder but the existence of the actual file within a list of potential data folders (like the good old MaxMSP "search paths"). this would allow to have a bundled data for required ressources (ex: shaders, interface elements, etc), and an external data for user ressources (ex: movies). with a configurable list, a few places could be searched, like ~/Documents/AppName/ to keep the app and data separated in some good practice manner (looking at iCloud)... also maybe bridge ofxiPhoneGetDocumentsDirectory() (useful for file sharing) & al.

it could be argued that a developper toggling OF_BUNDLE_DATA_FOLDER = 1 is aware that the stuff will be elsewhere and could then be expected to call ofSetDataPathRoot("../Resources/data/") to fish the ressources there but it's an additional step to perform "consciously" (and it changes the default data path), and thinking about this at this point I find that (3) - (multiple data folders) is interesting as a general feature (but requires more design and work than the scope of this PR)

SO: the current PR makes it so that a bundled data folder works transparently, with no impact on "normal" macOS apps (and a very slight risk of confusion for bundled apps users, which is much better than not working), holding the fort until a generalized multi-datapath strategy is implemented, if that is determined to be a good idea.

#changelog #osx

@dimitre
Copy link
Member

dimitre commented Mar 2, 2023

Hey @artificiel check it out this conversation here chalet-org/chalet#231
Question: is Contents/Resources the best folder to store data folder?

@artificiel
Copy link
Contributor Author

ah! chalet, interesting, @rewrking puts the finger on the same lines of code this PR is about, so yes, this would fix that chalet problem (if it's still a problem). it does reinforce the case for multiple paths, as indeed "required ressources" like shaders are not the same as "user ressources" like assets. (although i've seen very few apps that offer an "asset management experience" in terms of end-user-facing interface, this would ease the way towards it (and an appstore distributed-app has a kind of implicit "real" end-user in mind (vs the developer-users-working-on-a-single-instance-of-a-project we mostly are)).

and to confirm: yes: "Contents/resources" is the right place: the build phase correctly uses ${UNLOCALIZED_RESOURCES_FOLDER_PATH} which is recommended by Apple:

UNLOCALIZED_RESOURCES_FOLDER_PATH : Specifies the directory that contains the product’s unlocalized resources. Default value: | $CONTENTS_FOLDER_PATH/Contents/Resources/

to which the Xcode script appends data/ which is pretty reasonable to maintain familiarity (and segregation if other things end up in Resources/). (the only minor thing i see would be to pass ${UNLOCALIZED_RESOURCES_FOLDER_PATH} as a #define to the compile so the ../Resources/data/ is not hard-coded in ofFileUtils.cpp)

so there is a bit of untangling of scenarios to be had about "end end user" vs "C++ interface user" design, but i still think that (a) this PR is immediately useful as it simplifies the developer-user's life (shader.load("shaders/blur"); works regardless if the data is bundled or not) will little to no drawback and (b) the real solution is to allow multiple search paths, which opens up many other possibilities (not just this apple-specific bundle case).

@dimitre
Copy link
Member

dimitre commented Mar 3, 2023

+1 for this change

@dimitre dimitre mentioned this pull request Mar 3, 2023
@dimitre
Copy link
Member

dimitre commented Mar 7, 2023

@Artificel finally filesystem PR is merged #7110
and I've got some ideas of how to cleanup ofToDataPath, and included the functionality you are proposing here
#7368

Please take a look if you have the time.

@artificiel
Copy link
Contributor Author

great!

@artificiel
Copy link
Contributor Author

covered by #7368

@artificiel artificiel closed this Mar 9, 2023
@artificiel artificiel deleted the macos-data branch September 12, 2023 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants