Last active
December 26, 2017 16:24
-
-
Save willnationsdev/00d97aa8339138fd7ef0d6bd42748f6e to your computer and use it in GitHub Desktop.
Create flat or tiered view dictionaries of directories in Godot Engine.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A collection of static functions for searching through the res:// directory. | |
tool | |
extends Reference | |
##### CLASSES ##### | |
##### SIGNALS ##### | |
##### CONSTANTS ##### | |
enum Mode { SORT_FILESYSTEM, SORT_CUSTOM } | |
##### EXPORTS ##### | |
##### MEMBERS ##### | |
##### NOTIFICATIONS ##### | |
##### OVERRIDES ##### | |
##### VIRTUALS ##### | |
##### PUBLIC METHODS ##### | |
# p_match is a string that filters the list of files. | |
# If p_match_is_regex is false, p_match is directly string-searched against the FILENAME. | |
# If it is true, a regex object compiles p_match and runs it against the FILEPATH. | |
static func get_flat_view_dict(p_dir = "res://", p_match = "", p_match_is_regex = false): | |
var regex = null | |
if p_match_is_regex: | |
regex = RegEx.new() | |
regex.compile(p_match) | |
if not regex.is_valid(): | |
print("regex failed to compile: ", p_regex) | |
return [] | |
var dirs = [p_dir] | |
var first = true | |
var data = [] | |
while not dirs.empty(): | |
var dir = Directory.new() | |
var dir_name = dirs.back() | |
dirs.pop_back() | |
if dir.open(dir_name) == OK: | |
dir.list_dir_begin() | |
var file_name = dir.get_next() | |
while file_name != "": | |
if not dir_name == "res://": | |
first = false | |
# ignore hidden, temporary, or system content | |
if not file_name.begins_with(".") and not file_name.get_extension() in ["tmp", "import"]: | |
# If a directory, then add to list of directories to visit | |
if dir.current_is_dir(): | |
dirs.push_back(dir.get_current_dir() + "/" + file_name) | |
# If a file, check if we already have a record for the same name | |
else: | |
var path = dir.get_current_dir() + ("/" if not first else "") + file_name | |
# grab all | |
if not p_match: | |
data.append(path) | |
# grab matching strings | |
elif not p_match_is_regex and file_name.find(p_match, 0) != -1: | |
data.append(path) | |
# grab matching regex | |
else: | |
var regex_match = regex.search(path) | |
if regex_match != null: | |
data.append(path) | |
# Move on to the next file in this directory | |
file_name = dir.get_next() | |
# We've exhausted all files in this directory. Close the iterator. | |
dir.list_dir_end() | |
return data | |
static func get_tiered_view_dict(p_dir = "res://", p_sort = SORT_FILESYSTEM, p_match = "", p_match_is_regex = false, p_funcref = null): | |
# Initialize the tree dict | |
var r_root = { | |
"children": {} | |
} | |
if p_sort == SORT_CUSTOM and not p_funcref: | |
print("Invalid function reference in custom res tiered view.") | |
return r_root | |
if not Mode.has(p_sort): | |
print("Unrecognized mode in res tiered view") | |
return r_root | |
# fetch all new files from res:// | |
var this = load("res://res_utility.gd") | |
assert(this) | |
var temp_files = this.get_flat_view_dict(p_dir, p_match, p_match_is_regex) | |
match p_sort: | |
Mode.SORT_FILESYSTEM: | |
# for each file path in res | |
for a_filepath in temp_files: | |
var file = r_root | |
# get the names of items that should exist along that file path | |
var file_names = a_filepath.replace("res://","").split("/") | |
file_names.invert() | |
# keep going till we've exhausted every item in the list | |
while file_names.size(): | |
var file_name = file_names[file_names.size()-1] | |
var found_file = null | |
# check to see if any children share a name with the current item | |
for a_file in file["children"]: | |
if a_file.get_file() == file_name: | |
found_file = file["children"][a_file] | |
break | |
# if not, we need to create this item | |
if not found_file: | |
found_file = { | |
"children": {} | |
} | |
file["children"][path] = found_file | |
file = found_file | |
# Remove this item from our list | |
file_names.resize(file_names.size()-1) | |
Mode.SORT_CUSTOM, _: | |
for a_filepath in temp_files: | |
# let the function decide how to populate r_root with the file path. | |
p_funcref.call_func(r_root, a_filepath) | |
return r_root | |
##### PRIVATE METHODS ##### | |
##### CONNECTIONS ##### | |
##### SETTERS AND GETTERS ##### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment