Files
cell/prosperon/resources.cm

165 lines
4.7 KiB
Plaintext

Object.defineProperty(Function.prototype, "hashify", {
value: function () {
var hash = new Map()
var fn = this
function hashified(...args) {
var key = args[0]
if (!hash.has(key)) hash.set(key, fn(...args))
return hash.get(key)
}
return hashified
},
})
// 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"]
// Helper function: get extension from path in lowercase (e.g., "image.png" -> "png")
function getExtension(path) {
var idx = path.lastIndexOf('.')
if (idx < 0) return ''
return path.substring(idx + 1).toLowerCase()
}
// Return true if ext is in at least one of the recognized lists
function isRecognizedExtension(ext) {
if (!ext) return false
if (Resources.scripts.includes(ext)) return true
if (Resources.images.includes(ext)) return true
if (Resources.sounds.includes(ext)) return true
if (Resources.fonts.includes(ext)) return true
if (Resources.lib.includes('.' + ext)) return true // for .so or .dll
return false
}
function find_in_path(filename, exts = []) {
if (typeof filename !== 'string') return undefined
if (filename.includes('.')) {
var candidate = filename // possibly need "/" ?
if (io.exists(candidate) && !io.is_directory(candidate)) return candidate
return undefined
}
// Only check extensions if exts is provided and not empty
if (exts.length > 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 undefined
}
// 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)
}.hashify()
Resources.find_sound = function(file) {
return find_in_path(file, Resources.sounds)
}.hashify()
Resources.find_script = function(file) {
return find_in_path(file, Resources.scripts)
}.hashify()
Resources.find_font = function(file) {
return find_in_path(file, Resources.fonts)
}.hashify()
// .prosperonignore reading helper
function read_ignore(dir) {
var path = dir + '/.prosperonignore'
var patterns = []
if (io.exists(path)) {
var lines = io.slurp(path).split('\n')
for (var line of lines) {
line = line.trim()
if (!line || line.startsWith('#')) 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
}
Resources.getAllFiles[cell.DOC] = `
Return a list of recognized files in the given directory that are not matched by
.prosperonignore, skipping directories. Recognized extensions include scripts,
images, sounds, fonts, and libs.
:param dir: The directory to search.
:return: An array of recognized file paths.
`
// Categorize files by resource type
Resources.gatherStats = function(filePaths) {
var stats = {
scripts:0, images:0, sounds:0, fonts:0, lib:0, other:0, total:filePaths.length
}
for (var path of filePaths) {
var ext = getExtension(path)
if (Resources.scripts.includes(ext)) {
stats.scripts++
continue
}
if (Resources.images.includes(ext)) {
stats.images++
continue
}
if (Resources.sounds.includes(ext)) {
stats.sounds++
continue
}
if (Resources.fonts.includes(ext)) {
stats.fonts++
continue
}
stats.other++
}
return stats
}
Resources.gatherStats[cell.DOC] = `
Analyze a list of recognized files and categorize them by scripts, images, sounds,
fonts, libs, or other. Return a stats object with these counts and the total.
:param filePaths: An array of file paths to analyze.
:return: { scripts, images, sounds, fonts, lib, other, total }
`
return Resources