var io = use('cellfs') // Merge of the old resources.js and packer.js functionalities var Resources = {} // Recognized resource extensions Resources.scripts = ["js"] Resources.images = ["qoi", "png", "gif", "jpg", "jpeg", "ase", "aseprite"] Resources.sounds = ["wav", "flac", "mp3", "qoa"] Resources.fonts = ["ttf"] Resources.lib = [".so", ".dll", ".dylib"] // Helper function: get extension from path in lowercase (e.g., "image.png" -> "png") function getExtension(path) { var last = null replace(path, ".", function(m,pos) { last = pos return m }) if (last == null) return null return lower(text(path, last + 1)) } // Return true if ext is in at least one of the recognized lists function isRecognizedExtension(ext) { if (!ext) return false if (search(Resources.scripts, ext) != null) return true if (search(Resources.images, ext) != null) return true if (search(Resources.sounds, ext) != null) return true if (search(Resources.fonts, ext) != null) return true if (search(Resources.lib, '.' + ext) != null) return true // for .so or .dll return false } function find_in_path(filename, exts) { var _exts = exts || [] if (!is_text(filename)) return null var candidate = null if (search(filename, '.') != null) { candidate = filename // possibly need "/" ? if (io.exists(candidate) && !io.is_directory(candidate)) return candidate return null } // Only check extensions if exts is provided and not empty var cand = null if (length(_exts) > 0) { arrfor(_exts, function(ext) { candidate = filename + '.' + ext if (io.exists(candidate) && !io.is_directory(candidate)){ cand = candidate return true } }, null, true) if (cand != null) return cand } else { // Fallback to extensionless file only if no extensions are specified candidate = filename if (io.exists(candidate) && !io.is_directory(candidate)) return candidate } return null } // Return a canonical path (the real directory plus the path) Resources.canonical = function(file) { return io.realdir(file) + file } // The resource finders Resources.find_image = function(file) { return find_in_path(file, Resources.images) } Resources.find_sound = function(file) { return find_in_path(file, Resources.sounds) } Resources.find_script = function(file) { return find_in_path(file, Resources.scripts) } Resources.find_font = function(file) { return find_in_path(file, Resources.fonts) } // .prosperonignore reading helper function read_ignore(dir) { var path = dir + '/.prosperonignore' var patterns = [] var lines = null if (io.exists(path)) { lines = array(io.slurp(path), '\n') arrfor(lines, function(line) { var trimmed = trim(line) if (!trimmed || starts_with(trimmed, '#')) return patterns[] = trimmed }) } return patterns } // Return a list of recognized files in the directory (and subdirectories), // skipping those matched by .prosperonignore. Directory paths are skipped. Resources.getAllFiles = function(dir) { var _dir = dir || "" var patterns = read_ignore(_dir) var all = io.globfs(patterns, _dir) var results = [] arrfor(all, function(f) { var fullPath = _dir + '/' + f var _stat = function() { var st = io.stat(fullPath) // skip directories (filesize=0) or unrecognized extension if (!st.filesize) return var ext = getExtension(f) if (!isRecognizedExtension(ext)) return results[] = fullPath } disruption { // skip files that can't be stat'd } _stat() }) return results } // Categorize files by resource type Resources.gatherStats = function(filePaths) { var stats = { scripts:0, images:0, sounds:0, fonts:0, lib:0, other:0, total:length(filePaths) } arrfor(filePaths, function(path) { var ext = getExtension(path) if (find(Resources.scripts, ext) != null) { stats.scripts++ return } if (find(Resources.images, ext) != null) { stats.images++ return } if (find(Resources.sounds, ext) != null) { stats.sounds++ return } if (find(Resources.fonts, ext) != null) { stats.fonts++ return } stats.other++ }) return stats } return Resources