diff --git a/asset.lua b/asset.lua new file mode 100644 index 0000000..4ce925e --- /dev/null +++ b/asset.lua @@ -0,0 +1,72 @@ +-- ubiquitousse.asset + +-- The asset cache. Each cached asset is indexed with a string key "type.assetName". +local cache = setmetatable({}, { __mode = "v" }) -- weak values + +--- Asset manager. Loads asset and cache them. +-- This file has no dependicy 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 asset.load for more details. Hopefully this will allow you to use asset which are more game-specific than "image" or "audio". +local asset +asset = setmetatable({ + --- A prefix for asset names + -- @impl ubiquitousse + prefix = "", + + --- 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, in this order: + -- * try to load the directory loader: a file named loader.lua in the same directory as the asset we are trying to load + -- * try to load the asset-specific loader: a file in the same directory and with the same name (except with the .lua extension) as the asset we are trying to load + -- Loaders are expected to return the new asset. + -- These loaders have acces to the following variables: + -- * directory: the asset directory (including prefix) + -- * name: the asset name (directory information removed) + -- * asset: the asset data. May be nil if this is the first loader to run. + -- @tparam assetName string the asset's full name + -- @return the asset + -- @impl ubiquitousse + load = function(assetName) + if not cache[assetName] then + -- Get directory and name + local path, name = assetName:match("^([^.]+)%.(.+)$") + if not path then + path, name = "", assetName + end + local dir = (asset.prefix..path):gsub("%.", "/") + + -- Setup env + local oName, oAsset, oDirectory = name, asset, directory + name, asset, directory = name, nil, dir + + -- Asset directory loader + local f = io.open(dir.."/loader.lua") + if f then + f:close() + asset = dofile(dir.."/loader.lua") + end + + -- Asset specific loader + local f = io.open(dir.."/"..name..".lua") + if f then + f:close() + asset = dofile(dir.."/"..name..".lua") + end + + -- Done + cache[assetName] = asset + + -- Restore env + name, asset, directory = oName, oAsset, oDirectory + end + + return cache[assetName] + end, +}, { + --- asset(...) is a shortcut for asset.load(...) + __call = function(self, ...) + return asset.load(...) + end +}) + +return asset diff --git a/draw.lua b/draw.lua index 261ea5a..3753152 100644 --- a/draw.lua +++ b/draw.lua @@ -53,10 +53,10 @@ draw = { fps = function() end, --- Sets the drawing color - -- @tparam number r the red component (0-255) - -- @tparam number g the green component (0-255) - -- @tparam number b the blue component (0-255) - -- @tparam[opt=255] number a the alpha (opacity) component (0-255) + -- @tparam number r the red component (0-1) + -- @tparam number g the green component (0-1) + -- @tparam number b the blue component (0-1) + -- @tparam[opt=1] number a the alpha (opacity) component (0-1) -- @impl backend color = function(r, g, b, a) end, diff --git a/init.lua b/init.lua index c7f64b9..624cd81 100644 --- a/init.lua +++ b/init.lua @@ -84,7 +84,8 @@ ubiquitousse = { audio = false, input = false, scene = false, - event = false + event = false, + asset = false }, --- Backend name. diff --git a/scene.lua b/scene.lua index b6fc173..b8df9e7 100644 --- a/scene.lua +++ b/scene.lua @@ -21,7 +21,7 @@ local m = uqt.module -- * all scene change callbacks are called after setting scene.current to the new scene but before changing scene.stack -- * all scene exit/suspend callbacks are called before scene enter/resume callbacks local scene -scene = { +scene = setmetatable({ --- The current scene table. -- @impl ubiquitousse current = nil, @@ -131,6 +131,11 @@ scene = { draw = function(...) if scene.current then scene.current:draw(...) end end -} +}, { + --- scene(...) is a shortcut for scene.new(...) + __call = function(self, ...) + return scene.new(...) + end +}) return scene diff --git a/todo.txt b/todo.txt index 8cd1b55..62ba984 100644 --- a/todo.txt +++ b/todo.txt @@ -2,7 +2,6 @@ Ubiquitousse, also known as "The World's Best Video Game Engine Of All Time", de More specifically, what is lacking to officially turn Ubiquitousse into a sacred text, is: - An i18n API. While some languages are clearly superior to others, the general consensus seems to think otherwise. Ubiquitousse should be able to get an ordered list of prefered languages and provide translation helpers. See The Pong. -- Asset management. See The Pong. - Some API are still lacking an API and/or implementation. Search "TODO" for more information. - A filesystem API, to access the game's filesystem. May also rewrite Lua's io functions, see the next item. - A sandboxing system. Ubiquitousse should be able to run in a Ubiquitousse game safely. Since Ubiquitousse can run itself, it will