--- ubiquitousse.asset -- No dependencies. --- Asset manager. Loads asset and cache them. -- This file has no dependency to either ubiquitousse or a ubiquitousse backend. -- This only provides a streamlined way to handle asset, and doesn't handle the actual file loading/object creation itself; you are expected to provide your own asset loaders. -- See the __call method for more details on how assets are loaded. Hopefully this will allow you to use asset which are more game-specific than "image" or "audio". local asset_mt = { --- Load (and cache) an asset. -- Asset name are similar to Lua module names (directory separator is the dot . and no extention should be specified). -- To load an asset, ubiquitousse will try every loaders in the loader list with a name that prefix the asset name. -- The first value returned will be used as the asset value. -- Loaders are called with the arguments: -- * path: the asset full path, except extension -- * ...: other arguments given after the asset name. Can only be number and strings. -- @tparam assetName string the asset's full name -- @tparam ... number/string other arguments for the asset loader -- @return the asset -- @impl ubiquitousse __call = function(self, assetName, ...) local cache = self.cache local hash = table.concat({assetName, ...}, ".") if not cache[hash] then for prefix, fn in pairs(self.loaders) do if assetName:match("^"..prefix) then cache[hash] = fn((self.prefix..assetName):gsub("%.", "/"), ...) if cache[hash] then break end end end assert(cache[hash], ("couldn't load asset %q"):format(assetName)) end return cache[hash] end, --- Preload a list of assets. -- @impl ubiquitousse load = function(self, list) for _, asset in ipairs(list) do self(asset) end end, --- Allow loaded assets to be garbage collected. -- Only useful if the caching mode is set to "manual" duritng creation. -- @impl ubiquitousse clear = function(self) self.cache = {} end } asset_mt.__index = asset_mt local asset = { --- Create a new asset manager. -- If the caching "mode" is set to auto (default), the asset manager will allow assets to be automaticaly garbage collected by Lua. -- If set to "manual", the assets will not be garbage collected unless the clear method is called. -- "manual" mode is useful if you have assets that are particularly slow to load and you want full control on when they are loaded and unloaded (typically a loading screen). -- @tparam directory string the directory in which the assets will be loaded -- @tparam loaders table loaders table: {prefix = function, ...} -- @tparam mode string[opt="auto"] caching mode -- @impl ubiquitousse new = function(dir, loaders, mode) local cache = {} if mode == nil or mode == "auto" then setmetatable(cache, { __mode = "v" }) end return setmetatable({ --- A prefix for asset names -- @impl ubiquitousse prefix = dir..".", --- The asset cache. Each cached asset is indexed with a string key "type.assetName". -- @impl ubiquitousse cache = cache, --- The loaders table. -- @impl ubiquitousse loaders = loaders }, asset_mt) end } return asset