Giter VIP home page Giter VIP logo

cargo's Introduction

Cargo

Cargo makes it easy to manage assets in a Love2D project by exposing project directories as Lua tables. This means you can access your files from a table automatically without needing to load them first. Assets are lazily loaded, cached, and can be nested arbitrarily.

You can also manually preload sets of assets at a specific time to avoid loading hitches.

Example

If you have a project structured like this:

├── main.lua
└── assets
    ├── config
    │   └── player
    │       └── stats.lua
    ├── fonts
    │   └── my_font.ttf
    └── images
        └── player.png

Then you can do this:

assets = require('cargo').init('assets')

function love.load()
  print(assets.config.player.stats.maxHealth)
  myFont = assets.fonts.my_font(16)
end

function love.draw()
  love.graphics.draw(assets.images.player)
end

And it will just work. You can also do the following to expose your entire project as part of the Lua global scope:

setmetatable(_G, {
  __index = require('cargo').init('/')
})

In this example, if you have an image located at images/player.png, you can just call love.graphics.draw(images.player) without having to call love.graphics.newImage.

Advanced

There are two ways to tell cargo to load a directory. The first is by passing in the name of the directory you want to load:

assets = cargo.init('my_assets')

The second is by passing in an options table, which gives you more power over how things are loaded:

assets = cargo.init({
  dir = 'my_assets',
  loaders = {
    jpg = love.graphics.newImage
  },
  processors = {
    ['images/'] = function(image, filename)
      image:setFilter('nearest', 'nearest')
    end
  }
})

After something has been loaded, you can set it to nil to clear it from the cargo table. Note that it will only be garbage collected if nothing else references it.

You can also preload all of the assets in a cargo table by calling it (or any of its children) as a function:

assets = cargo.init('media')()     -- Load everything in 'media'
assets = cargo.init('media')(true) -- Load everything in 'media', recursively

assets.sound.background()          -- Preload all of the background music

Loaders

The loaders option specifies how to load assets. Cargo uses filename extensions to determine how to load files. The keys of entries in the loaders table are the file extensions. These map to functions that take in a filename and return a loaded asset. In the above example, we run the function love.graphics.newImage on any filenames that end in .jpg.

Here is a list of default loaders used:

Extension Loader
lua love.filesystem.load
png love.graphics.newImage
jpg love.graphics.newImage
dds love.graphics.newImage
ogv love.graphics.newVideo
glsl love.graphics.newShader
mp3 love.audio.newSource
ogg love.audio.newSource
wav love.audio.newSource
flac love.audio.newSource
txt love.filesystem.read
fnt love.graphics.newFont

The loader for .ttf and .otf files is special. Instead of directly returning an asset, this loader returns a function that accepts a size for the font and returns a new font with the specified size.

The loader for .fnt files requires the image file path to be set in the file as it won't be passed to love.graphics.newFont.

To have cargo ignore files with a certain extension, specify false as the loader.

Processors

Sometimes, it can be helpful to do some extra processing on assets after they are loaded. This extra work can be configured by the processors option. The keys are Lua patterns that match filenames, and the values are functions that get passed the asset and the filename of the asset. In the above example, we set the scaling filter on all assets in the images/ directory, regardless of extension.

License

MIT, see LICENSE for details.

cargo's People

Contributors

bartbes avatar bjornbytes avatar drhayes avatar john-cheesman avatar tesselode avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cargo's Issues

Cargo fails to handle filenames containing multiple `.`s when recursively preloading

Hiya! I shoved my own little loader into Cargo for FMOD banks, which come with the .bank extension. But, they also usually come in pairs, for example Master.bank and Master.strings.bank. Seems like switching up the "key" pattern used in the __call function for directory loading so that it requires the extension contain no .s fixes it, but I'm not sure whether this breaks something else I'm not aware of? I'm aware that paths with dots in them can't be accessed using that nice neat and tidy field syntax but in my particular use case I don't actually need to access the result of the loader; I just want the loader to be called on the path.

local key = f:gsub('%.[^.]-$', '')

EDIT: I want to clarify how it fails. If I set both a loader for .bank and .strings.bank, Cargo would end up loading either Master.bank twice or Master.strings.bank twice, since it would chop off the entirety of .bank and the entirety of .strings.bank and end up with the Master key twice. With this change, it instead gets Master and Master.strings as keys. In my particular case this works because .strings.bank isn't a special extension on its own - .strings is just an extra identifier which comes before the .bank extension.

Feature request: allow ignoring certain folders

Right now I'm working on a mini game framework kind of thing, and I have a certain way I want to load assets from certain folders. It would be nice if I could tell cargo to not bother loading those folders, since I'm doing it myself. It's nothing critical, but it would be nice to avoid wasting resources.

Loading screens

Great library!
Would it be possible to force loading of assets in a loading screen?
Perhaps just getting the asset table element is enough?
Thank you!

Deprecation warnings in 11.0

Love 11.0 came out April 1st, 2018. When I start my game that uses cargo I get the following two deprecation warnings:

LOVE - Warning: lib/cargo.lua:54: Using deprecated function love.filesystem.isDirectory (replaced by love.filesystem.getInfo)
LOVE - Warning: lib/cargo.lua:60: Using deprecated function love.filesystem.exists (replaced by love.filesystem.getInfo)

Add OTF support out of the box

Your default loaders don't match OTF font files. Totally simple change around line 37 that looks a lot like the TTF line. That would bring it to parity with what love2d supports, too. :)

loader problem after new love2d version

since the new love2d version, I get these error:

Error: lib/Cargo/cargo.lua:62: bad argument #2 to 'loader' (string expected, got no value)

If did hat hotfix:
local asset = nil
if extension ~= "wav" then
asset = loader(file)
else
asset = loader(file,"static")
end

since I only have png's and wav's

best regards

þorN

Returning nil instead of asset?

I have this has my main.lua

`Gamestate = require 'libs.hump-gamestate'
Camera = require 'libs.hump-camera'
Vector = require 'libs.hump-vector'
require 'libs.colors-rgb'

music = require('libs.cargo').init('music')
image = require('libs.cargo').init('image')
sound = require('libs.cargo').init('sound')
fonts = require('libs.cargo').init('fonts')
state = require('libs.cargo').init('state')

require 'state.welcome'

function love.load()
Gamestate.registerEvents()
Gamestate.switch(welcome)
end`

and in my welcome.lua I have this

`welcome = {}

function welcome:draw()
love.graphics.setFont(baseFont)
love.graphics.print("Test",10,10)

end

function welcome:update(dt)

end

function welcome:load()
baseFont = fonts.main_font(16)
end`

but it is giving me this error message:

`Error

state/welcome.lua:4: bad argument #1 to 'setFont' (Font expected, got nil)

Traceback

[C]: in function 'setFont'
state/welcome.lua:4: in function 'draw'
[C]: in function 'xpcall'`

Loader per directory, not just per file

Would it be possible to run/add a loader function that gets all files in a directory as an argument, instead of one loader function per file? My use case is loading multiple .pngs and putting them inside an ArrayImage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.