Files
prosperon/resources.cm
2026-01-18 11:22:52 -06:00

153 lines
4.1 KiB
Plaintext

var io = use('cellfs')
function hashify(fn) {
var hash = {}
return function(...args) {
var key = args[0]
if (hash[key] == null) hash[key] = fn(...args)
return hash[key]
}
}
// 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 = []) {
if (!is_text(filename)) return null
if (search(filename, '.') != null) {
var 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
if (length(exts) > 0) {
for (var ext of exts) {
var candidate = filename + '.' + ext
if (io.exists(candidate) && !io.is_directory(candidate)) return candidate
}
} else {
// Fallback to extensionless file only if no extensions are specified
var 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 = hashify(function(file) {
return find_in_path(file, Resources.images)
})
Resources.find_sound = hashify(function(file) {
return find_in_path(file, Resources.sounds)
})
Resources.find_script = hashify(function(file) {
return find_in_path(file, Resources.scripts)
})
Resources.find_font = hashify(function(file) {
return find_in_path(file, Resources.fonts)
})
// .prosperonignore reading helper
function read_ignore(dir) {
var path = dir + '/.prosperonignore'
var patterns = []
if (io.exists(path)) {
var lines = array(io.slurp(path), '\n')
for (var line of lines) {
line = trim(line)
if (!line || starts_with(line, '#')) continue
patterns.push(line)
}
}
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 patterns = read_ignore(dir)
var all = io.globfs(patterns, dir)
var results = []
for (var f of all) {
var fullPath = dir + '/' + f
try {
var st = io.stat(fullPath)
// skip directories (filesize=0) or unrecognized extension
if (!st.filesize) continue
var ext = getExtension(f)
if (!isRecognizedExtension(ext)) continue
results.push(fullPath)
} catch(e) {}
}
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)
}
for (var path of filePaths) {
var ext = getExtension(path)
if (find(Resources.scripts, ext) != null) {
stats.scripts++
continue
}
if (find(Resources.images, ext) != null) {
stats.images++
continue
}
if (find(Resources.sounds, ext) != null) {
stats.sounds++
continue
}
if (find(Resources.fonts, ext) != null) {
stats.fonts++
continue
}
stats.other++
}
return stats
}
return Resources