I just want to clarify the new way to write file names with Codea 3.x.
The file name used to be just a string such as
tt=readText(“Dropbox:file1”)
But since Codea 3.x introduced assets key stile, the code should be
tt= readText( asset.documents.Dropbox … “file1.txt”)
blanks are required before and after “…” in order to connect asset location description and file name with file type extension.
file name can be a variable
fileName=“file1.txt”
tt=readText(asset.documents.Dropbox … fileName)
However, when choosing the file directly from code editor, it can be written as
tt= readText( asset.documents.Dropbox._file1)
no blanks nor file type are required but an underscore.
Are there any other points to be noted in syntax for file name description?
@Makoto It depends if the file exists or not. Blanks aren’t required before the …
If the file exists, then you can just tap between the () and select it. If the file doesn’t exist or it has special characters in the name, then you might need “” or [] or … with the name. It also depends if you specify the extension name with the file name. Normally if the file exists, I just select it in between the (). If the file doesn’t exist yet, then I just try different things around the name until I don’t get a warning. I don’t know if there’s specific rules for what to do for each situation. It kind of varies because sometimes it works multiple ways.
Because you can’t use certain symbols in variable names in Lua (they can’t start with a number, they can’t contain a space, they can’t contain quotes, etc.) you will see them replaced with underscores when you select them via autocomplete or through the picker
For example, a file called "A Hero's Quest:Tavern Music" would be represented as asset.builtin.A_Hero_s_Quest.Tavern_Music (because Lua doesn’t let you put space (), or quote (') in variable names.
You could also access this file with the raw strings by doing:
@RonJeffries I think I mentioned something similar already. It used to be if you tried to read a file that didn’t exist, it returned nil and you could code for that. Now, if you try to read a file that doesn’t exist, the code exits with an error. I haven’t checked recently if that was corrected or not.
PS. Just tried it and the code exits with an error.
@RonJeffries there isn’t a good way to do it, but that’s a great question. I will add an exists property to the asset key system so you can check whether an asset exists in the file system
@Simeon I guess it just depends on the syntax. I didn’t have the “ “ around my file name. It didn’t give me an error in the editor, so I thought it was OK. It just gave an error message when I tried to run the code. I’ll just have to remember to put “ “ around the name.
@Simeon Here’s what I mean about the syntax. It’s like you need to try different things. Some times you need a single period, other times you need a double period , or double quotes or double brackets. I thought maybe if you didn’t get an editor error message, then it should work. So from what you said, everything should work OK. You just need to try different combinations until it does.
function setup()
str1=readText(asset.documents.Dropbox.test3) -- file exist, reads OK
str2=readText(asset.documents.Dropbox.."test3") -- file exists, returns nil
str3=readText(asset.documents.Dropbox.."test31") -- file doesn't exist, returns nil
print("str1 ",str1)
print("str2 ",str2)
print("str3 ",str3)
end
@dave1707 when you use quotes " you must use the full filename, including the extension.
function setup()
str1=readText(asset.documents.Dropbox.test3) -- file exist, reads OK
str2=readText(asset.documents.Dropbox.."test3.txt") -- (assuming the file has a .txt extension)
str3=readText(asset.documents.Dropbox.."test31") -- file doesn't exist, returns nil
print("str1 ",str1)
print("str2 ",str2)
print("str3 ",str3)
end
When you get the autocompleted identifiers for files the file extensions are not included — unless two or more files with the same name (but different extensions) live in the same folder. So if you had “test3.txt” and “test3.png” in your Dropbox you would get
asset.documents.Dropbox.test3_txt and asset.documents.Dropbox.test3_png
Whereas if you only have “test3.txt” in the folder you’d get an autocomplete identifier like:
asset.documents.Dropbox.test3
If you want to use the actual file name you can do that with the bracket syntax:
@RonJeffries here’s a little app that lets you check if a file exists
-- File Exists
function setup()
print("Checking asset.builtin.Effects")
local folder = asset.builtin.Effects
parameter.text("FileName", "Ripple.shader", function ()
exists = doesExist(FileName, folder)
end)
parameter.action("List Folder", function ()
for _,v in pairs(folder.all) do
print(v.name)
end
end)
exists = doesExist(FileName, folder)
end
function doesExist(name, folder)
return folder[name] ~= nil
end
function draw()
background(40, 40, 50)
strokeWidth(5)
fill(255)
textMode(CENTER)
if exists then
text("File Exists", WIDTH/2, HEIGHT/2)
else
text("File Does Not Exist", WIDTH/2, HEIGHT/2)
end
end
Basically you check if folder[fileName] ~= nil. If you get an asset key, then the file exists. If you get nil, it doesn’t.
So if asset.documents["MySprite.png"] is nil, then it’s not there.
Side note: this is different to asset.documents .. "MySprite.png". The concatenation (..) operator will create an asset key for you by appending a given file name to a folder name, this allows you to specify asset keys for files which don’t exist (so you can create them)
@RonJeffries.. is the concatenation operator, and in this case it is used to construct a new path given an existing folder and a file/folder name
So it might make more sense to expect folder .. "/text3.txt". As you are appending onto a path, though in this API we omit the path separator (/) because where and how to place path separators when concatenating path elements should be handled by the system
I’ll be writing a more interesting file and asset example soon
my thought is that “asset.documents” … “test.txt” is “asset.documentstest.txt” not “asset.documents.test.txt” but I suppose it’s just an overload of “…” with smarts.
At the moment you cannot specify an arbitrary location in Files. But this is why I introduced asset keys, it implements the architecture I need to get there
iOS restricts access to files, so Codea cannot read or write any files on your system outside of its own Documents folder. The only way Codea can access another folder is if we present the system file picker and you explicitly select a folder or file. Codea will be granted access to only that folder or file and can store a bookmark to it
This is what I’m planning to introduce with asset keys — something like you type asset. and in the autocomplete bar there is a button for “External Folder”, and tapping that brings up the file picker UI, selecting the folder then creates a bookmark for Codea and allows you to reference the folder in your code
I wish to have a sub-folder capability within Dropbox, taking advantage of the asset keys system.
I mean something like;
textRead(asset.documents.Dropbox.folder1[“test3.txt”])
Then I can save a set of data relating to one project in one folder together. It will make easier not only to manage numerous files for number of projects but also to implement auto linkage of required files in exporting a zipped project file to Xcode.
Currently, it seems Codea detects the files in the folder “Dropbox/???/Codea” only and classify them by their file types, e.g. text, image, sound, etc. However, it ignores subfolders under Codea folder.
Codea project editor deems “.folder1” following Dropbox as an asset and give me an error message “Asset ‘folder1’ does not exist”, even there is a subfolder “filder1” in the Codea folder.