Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
This has been semi-suggested several times before (see "Access resource files dynamically" here and the second paragraph of Lummox JR's second comment here), but there doesn't appear to be a formal request.

It would be helpful if files in the cache could be accessed at runtime by filename. This would allow for storing file names in savefiles, instead of saving the entire file or hard-coding an associative-list of file cache references ("turfs.dmi"='turfs.dmi', "dragon.dmi"='dragon.dmi', ect).

For my purposes, I'm working on a map saver/loader, and would like to be able save any non-initial icon values without saving the entire icon or forcing the user to put together and maintain the aforementioned cache reference list. It would also allow for developers to write a clean process to save overlay data without flattening and saving the icon.

It has been suggested that file() be given a second parameter to specify if it's from the cache, but I think file_rsc(filename) would also be appropriate (and in-line with fcopy/fcopy_rsc).

Simple example use-case:
var/savefile/S = new/savefile("test.sav")
var/savefile/S = new/savefile("test.sav")
I = file_rsc(filename)
src.icon = I
src<<"File '[filename]' no longer in cache!"

In the above example, I assume file_rsc() would return null if the file could not be found in the cache. I think this makes more sense then throwing an error, because files disappearing from the cache may be a common occurrence (ie for old savefiles), and there's no real way for a developer to avoid the error.
I'd absolutely love to see this feature since it could be great for games that use a lot of user-uploaded content.
+1 this should of been available a long long time ago IMO ...
This was merged in from a separate thread

My suggestion is fairly simple; add a function, say cfile() ("c[ache]file"), that when given a filename such as "icon.dmi", returns a cache reference if a file in the cache has the same name.

An example is that the two code segments below would be functionally identical:

MyOtherObject.icon = 'black.dmi' // Ensure black.dmi is in the .rsc
MyObject.icon = 'black.dmi'

MyOtherObject.icon = 'black.dmi' // Ensure black.dmi is in the .rsc
MyObject.icon = cfile("black.dmi")

in both cases, MyObject.icon == MyOtherObject.icon would be true.

If the file was not in cache, then this would react the same way as file() does when passed a file that does not exist.
In response to Topkasa
Doesn't fcopy_rsc() already do this?

var/obj/obj1 = new
obj1.icon = 'bleh.dmi'

world << "\ref[obj1.icon]"

var/obj/obj2 = new
obj2.icon = fcopy_rsc("bleh.dmi")
world << "\ref[obj2.icon]"
In response to Topkasa
fcopy_rsc() requires that the original, non-cached file exists. It pulls that file into the .rsc except if it's already in.

I need different functionality; I need to get a reference to a file in the .rsc *without* needing the original file to be present.
In response to Topkasa
Can you provide a use-case?

alternatively, you can do something like this:

for(var/x in savedIcons)

savedIcons["[x]"] = "\ref[x]"
savedIcons -= x
for(var/x in savedIcons)
world << "[x] = [savedIcons[x]]"

//global or datum definition
var/savedIcons = list('bleh.dmi', 'icons.dmi', 'red.dmi')
In response to Topkasa
That is a workaround, and I am using it, but I would rather see a 'proper' solution to this.

My use-case is a map loader that parses a DMM-compatible spec into map data for dynamic loading. I need to be able to support things like the 'Black.dmi' in this line:

"a" = (/turf/Floor/Generic/Basic{icon = 'Project/Icons/UI/Black.dmi'; icon_state = "Black"},/area)

Keeping a massive array of Filename-CacheRef entries is doable, but clunky compared to a proper cache-file proc.