godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add `FilePath` similar to `NodePath` #5029

Open me2beats opened 2 years ago

me2beats commented 2 years ago

Describe the project you are working on

Games with many "path/to/file"

Describe the problem or limitation you are having in your project

I have many scripts with "path/to/file". Problems:

uids solve refactoring problem, but:

storing file names in dictionaries (for example in a singleton)

using custom names fot uids https://github.com/godotengine/godot-proposals/issues/5026

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Adding FilePath could solve the problem

usually you just would set pairs some/path - path_alias in ProjectSettings, then just use get_path("path_alias") like var my_path = get_path("path_alias") which returns some/path that can be a file or a folder

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

So, in ProjectSettings you can configure some paths aliases like "my_path" for "my/path/to/file" and then just use get_path("my_path") anywhere in the project. These paths values will be updated automatically each time the file is moved/renamed

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not with a few lines

Is there a reason why this should be core and not an add-on in the asset library?

I think this would be used often

dalexeev commented 2 years ago

I don't think the FilePath type is needed (as analogous to NodePath). This could be added as a class that inherits from RefCounted, into which some String methods (get_file, get_extension, get_basename, plus_file, etc.) could be moved, but that would be a helper class for working with file paths, not a replacement String in methods that use file paths.

I'm sure that your problem with heavy use of file paths in scripts can be solved in another way.

Lielay9 commented 1 year ago

I've actually stumbled to a similar problem. Needing to store some paths to scenes in code, that will later be loaded (and hence can't be preloaded). So far I've either dragged the file to the script first or written it with preload and scrubbed it off once I've no longer gotten an error of the file not existing. That's how I've found my way here.

Adding a type would be an overkill. The only thing I would need is for the script to start yelling that the referenced path doesn't exist. That in mind I don't think there is even a need for a class. A single function that returns the string it receives and refuses to work unless it's a valid path to a resource (similar to preload) would suffice. The other functionality is already implemented in String anyway, other than automatic refactoring (which would be nice, but not a must).

For example something like this:

var path_to_resource: String = fref("res://path_to_resource.jpg") # or get_path like in the proposal
stebl commented 1 month ago

Ran into a use for this, wanted to comment.

I want to have the path autocomplete functionality in the resource inspector.

extends Resource
class_name MapTile

# Paths to .obj format mesh variations
@export var meshes: Array[FilePath]

Having a type for NodePath is extremely helpful for configuring scenes in the editor. This would be a similar use case.

Lielay9 commented 1 month ago

Ran into a use for this, wanted to comment.

I want to have the path autocomplete functionality in the resource inspector.

extends Resource
class_name MapTile

# Paths to .obj format mesh variations
@export var meshes: Array[FilePath]

Having a type for NodePath is extremely helpful for configuring scenes in the editor. This would be a similar use case.

You can use export_file("*.extension") var meshes: Array[String] with the caveat that paths don't update when content is moved.

stebl commented 1 month ago

@Lielay9 That's perfect, thank you! I don't think file paths update when they're in a preload(...) statement or similar, so status quo.

I retract my use case :)