Add function generate_working_directory()

Reporter: time-killer-games  |  Status: open  |  Last Modified: April 17, 2019, 04:37:39 PM

This code was tested in the GameMaker equivalent with the help of my File Manager extension and it is verified working.

This function will set the working directory to the app bundle's Resources folder like GM4Mac 7.5, GMStudio 1.4, GMS 2.x and most Mac apps do, if the executable is in an app bundle. If the executable is not in an app bundle, use the getcwd function.

ONLY use working_directory for loading read-only included files! When SAVING, use game_save_id. Mac app bundles must be read-only, otherwise your app will not work anymore after being code-signed because you were stupid enough to tamper with it. Your app will also get rejected from the Mac App Store if you do that. We still need to add game_save_id because not only is it the GM sandbox directory, Mac Apps require sandboxing as an operating system requirement, unless you distribute outside their store without code-signing.

time-killer-games  
@JoshDreamland @fundies Ready for you guys to review.
codecov[bot]  

Codecov Report

Merging #1674 into master will not change coverage.
The diff coverage is 0%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1674   +/-   ##
=======================================
  Coverage   18.82%   18.82%           
=======================================
  Files         169      169           
  Lines       16782    16782           
=======================================
  Hits         3159     3159           
  Misses      13623    13623
Impacted Files Coverage Δ
...m/SHELL/Platforms/General/POSIX/POSIXdirectory.cpp 0% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fb9d867...aef8920. Read the comment docs.

time-killer-games  

if (os_type == os_macosx) {
  /*
    This function will set the working directory to the app bundle's Resources folder 
    like GM4Mac 7.5, GMStudio 1.4, GMS 2.x and most Mac apps do, if the executable is in
    an app bundle. If the executable is not in an app bundle, use the getcwd function
    
    ONLY use get_working_directory() for loading read-only included files! When SAVING, use game_save_id
    
    *_bname = base name - removes the full path from the string leaving just the file or folder name
    *_dname = directory name - removes final slash and base name from full path to file or folder name
    *_pname = path name - removes the base name from a full path while keeping the dir and final slash
    *_ename = extension name - includes everything in bname at and following the period if one exists
  */
  
  var success = false; 
  var exe_pname = get_program_directory();             // = "/Path/To/YourAppBundle.app/Contents/MacOS/";
  var macos_dname = filename_dir(exe_pname);           // = "/Path/To/YourAppBundle.app/Contents/MacOS";
  var macos_bname = filename_name(macos_dname);        // = "MacOS";
  var contents_dname = filename_dir(macos_dname);      // = "/Path/To/YourAppBundle.app/Contents";
  var contents_bname = filename_name(contents_dname);  // = "Contents";
  var app_dname = filename_dir(contents_dname);        // = "/Path/To/YourAppBundle.app";
  var app_ename = filename_ext(app_dname);             // = ".app";
  var contents_pname = filename_path(macos_dname);     // = "/Path/To/YourAppBundle.app/Contents/";
  var resources_pname = contents_pname + "Resources/"; // = "/Path/To/YourAppBundle.app/Contents/Resources/";
  
  // if "/Path/To/YourAppBundle.app/Contents/MacOS/YourExe" and "/Path/To/YourAppBundle.app/Contents/Resources/" exists
  if (macos_bname == "MacOS" && contents_bname == "Contents" && app_ename == ".app" && directory_exists(resources_pname)) {
    // set working directory to "/Path/To/YourAppBundle.app/Contents/Resources/" and allow loading normal included files
    success = set_working_directory(resources_pname);
  }
  
  /*
    if (success) show_message("Success!"); else show_message("Failure!");
    get_string_async("The current value of working_directory equals:", get_working_directory()); 
  */
}

Above you will see the GML equivalent of the code I wrote for this pull request and it uses my "File Manager" extension which may be downloaded here.

Uncommenting this part:

  /*
    if (success) show_message("Success!"); else show_message("Failure!");
    get_string_async("The current value of working_directory equals:", get_working_directory()); 
  */

...resulted in the "Success!" message and the working directory shown in the input box was indeed the correct "Resources" folder in the app bundle.

The source code to "File Manager" is doing all the same things this pull request is doing under-the-hood, so everything has been tested and is verified working.

Please sign in to post comments, or you can view this issue on GitHub.