Creating an imageSheet using an absolute path in desktop

It seems that graphics.newImageSheet assumes relative/logical path + the root constant. Is it possible to create an imageSheet using an absolute path like “C:\path\to\file.png” in Win or “/path/to/file.png” in OSX? We have a desktop app that integrates with a second app over a local webserver get the paths from there. It’s not a technical limitation, i.e. win32 apps can do this with certain limitations and OSX apps when you declare the right entitlements.

No.

Corona image assets can only be accessed from the system.* directories for that app/game:

https://docs.coronalabs.com/daily/api/library/system/index.html#constants

The resource directory is the default: https://docs.coronalabs.com/daily/api/library/system/ResourceDirectory.html

Dang, that’s going to be a problem…

If you have a local web server, can’t you just let your app download the images to the system.DocumentsDirectory and access them from there instead?

We actually do and that was the original solution :slight_smile: But when have a hundred of them, downloading adds up while sharing a folder is near instantaneous.

But I think I found a workaround. The system.TemporaryDirectory evaluates to the user temp directories in Win (AppData/…) and Mac (~/Library/Application Data/…). It works a bit differently in both (and in Simulator!), so it’ll need some platform specific code.

That said, I really think the system temp should be an option in Corona. It’s there for a reason and easy to find using environment variables.

If you’re on  a windows system, you can use mklink /j to create a Junction.

This is how I maintain a common source for my (upcoming) revamp of SSK in all my test projects:

-- 1. cd to the folder where you want the link (usually root of your game) -- 2. decide on a name of the folder (junction). Below it will be called ssk2 -- 3. Call mklink using form shown below to make junction -- Caution: Git tools generally treat this like a folder and copy the contents into the repository. -- So, if you're keeping these projects on a git and do not want the common folder(s) -- saved in the repository, add them to your ignore list. -- -- Ex: in my case, my projects with junctions all ignore the folder ssk2 -- to from mklink /j .\ssk2 X:\Work\00\_CurentProjects\Corona\SSK2\ssk2

I am having this problem as well. I am developing a desktop tool to create levels for other Corona games. A planned feature is that the user can select their own textures, which of right now, is not that simple to achieve. What i am doing to be able to load images and other stuff on other folders is using double dot, like so:

display.newImage("../../../myImage.png")

This sort of works if you get on what directory you are in, using system.pathForFile, and then parsing the string to know how many subdirectories there are until directory root. (Tested only on macOS)

It would be great if there was a constant like system.UserDirectory and system.RootDirectory.

You could also execute io.popen with native copy commands to get the assets to the temporary directory.

Creative :slight_smile: Does that work the same way in Win/OSX/Simulator? I agree, system.RootDirectory, system.GlobalTempDirectory, system.UserDirectory or system.ApplicationDirectory (%appdata% in Win, ~/Library/Application Data/ in Mac) would definately be needed for desktop

I have no idea, what i have tested on is on the simulator, for now. I don’t know if it will be the same for macOS, since apps are inside a container (Which is a folder). I will test that today, and come back with some results and code.

Please keep in mind that on device things are sandboxed and you cannot reach outside of your project. So doing:

local img = display.newImageRect("…/…/…/…/someimage.jpg")

won’t work on device if you’ve backed out of your project past your main.lua. Symlinks should work but the files have to be referenced from within the app’s project sandbox folder tree.

Rob

@rob: Are you saying that in general or for desktop also? This question was in the desktop app context and in my experience is that there is no OS-limit on accessing paths beyond the sandbox. I.e. you can for example give a path like c:\path\to\file to just standard lua io-library and it’ll read that just fine. Also reading/writing system temp is perfectly fine behaviour for a win32 / macOS (given the right entitlement) app.

macOS apps can be sandboxed depending on their entitlements and how they are deployed from the store. But in general Desktops potentially can access paths outside of the app.

But the problem of backing up a path using …/ is making a huge assumption on desktop’s that the app is going to be installed in a specific folder. Not everyone installs apps in /Applications on macOS or on C:\Program Files (x86)\YourCompanyName\YourAppName on Windows. If you use the …/ (Parent directory) multiple times you may not find yourself looking in the right place. If you want to use an absolute path you can do so unless as I mentioned above you deployed your macOS app in a sandboxed fashion.

On Mobile, you are sandboxed and certainly don’t have access to folders outside the sandbox (well, Android you can absolute path to public folders if you know the path). 

Yes, we are aware of that. What i am planning on doing, to be able to get the number of “…”, is to do a system.getPathForFile, on the apps root. That way, i can parse the string to see how many folders to get to the real root.

For example, i have a file inside my container: file.txt, i do a system.getPathForFile(“file.txt”), that gives me the full path of the file: “/Users/MyUser/Documents/Projects/TestProject/file.txt”. Now i can parse that string and i know that it has 5 folders. now to find a global file, say, on “/Users/MyUser/Desktop/other.txt”, i now know i must append 5 “…” to the path, like with a for. like so: “…/…/…/…/…/Users/MyUser/Desktop/other.txt” 

I am developing a desktop application, a level editor to be precise, which would never make it’s way to Android or iOS, not with the current design at least.

I know that this is not really necessary to open files with io.open, but for display.newImage and the other Corona APIs this does the trick. (on macOS simulator, at least)

Question:  “When it is time to build these projects, how do you guys plan to get the content in the right place(s)?”  

I am quite sure that Corona won’t be able to build a project that has …/ paths in it.  I’ve done the same experiments you guys are doing and none of them panned out for long-term durability or clarity of organization.  

(I also experimented with various git structures/relationships and they turned out to be painful and unreliable too.)

I agree with Rob that your best choice here is a symbolic link (OS X) or Junction (Windows) to a folder(s).

I forgot to mention (and it seems this may be relevant), if you’re developing tools to access arbitrary folders and drives on OS X and Windows, I have a module for this coming soon in SSK 2.

Till new version of SSK is released, you can get your hands on the old version of that module here:

(Has dependencies on SSK so you may need to do a little work to extract it as a standalone module).

https://github.com/roaminggamer/SSKLegacy/tree/master/ssk/RGFiles

-- -- Module Legend -- ssk.RGFiles.\* documents.getRoot() documents.getPath( path ) resource.getRoot() resource.getPath( path ) temporary.getRoot() temporary.getPath( path ) desktop.getDesktopRoot() desktop.getDesktopPath( path ) desktop.getMyDocumentsRoot() desktop.getMyDocumentsPath( path ) desktop.getDrivePath( path ) by current OS. desktop.explore( path ) util.exists( path ) util.dumpAttributes() util.isFile( path ) util.readFile( path ) util.readFileToTable( path ) util.writeFile( data, path ) util.appendFile( data, path ) util.rmFile( path ) util.mvFile( src, dst ) util.cpFile( src, dst ) util.isFolder( path ) util.repairPath( path, forceForward ) util.rmFolder( path ) util.mkFolder( path ) util.mvFolder( src, dst ) util.cpFolder( src, dst ) util.saveTable( tbl, path, secure ) util.loadTable( path, secure ) Misc - Utilities ---------------- util.getFilesInFolder() util.keepFileTypes() util.getLuaFiles() util.getResourceFiles() util.flattenNames() util.findAllFiles()

-Ed

Well, I’d say the best choice would be to provide desktop specific endpoints like system.UserFolder, system.Desktop, system.ApplicationData and system.GlobalTemp, everything else is a hack to workaround limitations. From my perspective junctions and symlinks are asking/using too much power to solve a problem that does not require it. Junctions are a pretty low level operation that could definitely be a permission issue with non-admin users or in machines under corporate IT. Also if you create a symlink outside of the sandbox without declaring the entitlement, it could be seen as a problem in the Mac Appstore review (if caught). 

PS. Nice to meet SSK :slight_smile:

I have created a feature request to add these constants to Corona desktop. It can be found here. Vote it up if you would find it useful.

system.DocumentsDirectory, system.TemporaryDirectory and system.CachesDirectory should be in user specific locations for desktop builds.

For instance on Windows:

%HOMEPATH%\AppData\Roaming\<CompanyName>\<AppName>\Documents

%HOMEPATH%\AppData\Local\<CompanyName>\<AppName>\CachedFiles

%HOMEPATH%\AppData\Local\<CompanyName>\<AppName>\TemporaryFiles

On macOS it seems to be:

~/Library/Application Support/AppName/Documents

~/Library/Application Support/AppName/tmp                 – could be for both TemporaryDirectory and CachesDirectory

Of course on Unix based systems ~ is the user’s home directory. On macOS that’s /Users/username/ using me as an example /Users/rmiracle

This seems to be a different question than how I can you reference files relative to your app bundle which for mac OS is /Applications/ but isn’t guaranteed to be. 

I should have also added, Windows has a bunch of environment variables to help you find places to store files of certain types. This page gives you a good rundown of these variables:

http://www.rapidee.com/en/environment-variables