Can I require "package.file" instead of "package/file.lua"?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Can I require "package.file" instead of "package/file.lua"?

Post by sroccaserra »

Hi, thanks for this awsome framework in this great programming language.

I try to package some existing Lua libs in a LÖVE project, but I have some troubles with "require".

A lot of existing Lua code use the following syntax to require the file "package/file.lua":

Code: Select all

require "package.file"
This doesn't seem to work for files packaged in my LÖVE game directory, am I right?
And if so, will this change in future versions?

For example I'd like to package an OOP or Zip lib with my LÖVE game, but I'd hate to have to change all its requires every time I upgrade the libs.

Cheers!

[Edit] More accurate details.
Last edited by sroccaserra on Thu Feb 05, 2009 9:08 am, edited 1 time in total.
osuf oboys
Party member
Posts: 215
Joined: Sun Jan 18, 2009 8:03 pm

Re: Can I require "package.file" instead of "package/file.lua"?

Post by osuf oboys »

You could write a require method which does what you want - either by overloading the existing require method or by the function a name of your choice, e.g. just 'require'.
If I haven't written anything else, you may assume that my work is released under the LPC License - the LÖVE Community. See http://love2d.org/wiki/index.php?title=LPC_License.
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Re: Can I require "package.file" instead of "package/file.lua"?

Post by sroccaserra »

Ok, I found out. [Edit] Or not.

I have a directory named "SomeGame", where my main.lua and all Lua source files reside.
Then, I start the game from outside the directory, with the command "love SomeGame". So, to require "SomeGame/package/file.lua", the following works:

Code: Select all

package.path = "./SomeGame/?.lua"
require "package.file"
[Edit] This worked on a PC, but doesn't work on a Mac.

So, my new question: is there a way to know the current Löve root directory? This would allow me to avoid naming it in the sourcecode, with something like:

Code: Select all

package.path = love.filesystem.rootDirectory().."/?.lua"
require "package.file"
Cheers!
Last edited by sroccaserra on Thu Feb 05, 2009 9:10 am, edited 1 time in total.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Can I require "package.file" instead of "package/file.lua"?

Post by bartbes »

What is the "root directory"? The dir LÖVE is installed in (e.g. program files), or the dir from where LÖVE is run?
In the last case it is getWorkingDirectory().
Sidenote: if you run it by dragging the .love/dir on the lua shortcut the working directory will probably be the dir where LÖVE is installed, this might be true for double-clicking too.
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Re: Can I require "package.file" instead of "package/file.lua"?

Post by sroccaserra »

Is there a template value that could be added to packag.path (like './?.lua') that would make "require 'package.file'" work? I couldn't find any.

Alternatively, has someone writen a package loader that accomplishes the same thing?

Cheers!
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Re: Can I require "package.file" instead of "package/file.lua"?

Post by sroccaserra »

I eventually wrote a Lua loader that allows me to require Lua files by calling "require 'package.file'" instead of "require 'package/file.lua'".
It's not great, but it's all I have so far.

Code: Select all

local loader = function(fileName)
                   local file = fileName:gsub("%.", "/")..'.lua'
                   return package.loaders[5](file) -- Makes use of the Löve loader, the only one able to find files in my tests
               end

table.insert(package.loaders, loader)
Did anybody have the same problem while trying to use some Lua lib?

Cheers!
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Can I require "package.file" instead of "package/file.lua"?

Post by bartbes »

I myself put LUBE in the general require search dir /usr/share/lua/5.1 (on linux), so the files were in the subdir LUBE, I was able to use the following code:

Code: Select all

require "LUBE.Client"
I don't see a problem?
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Re: Can I require "package.file" instead of "package/file.lua"?

Post by sroccaserra »

Ok, thanks.

And did you try to package the LUBE code within your .love file, for users that don't have LUBE installed? That's what I'm trying to do.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Can I require "package.file" instead of "package/file.lua"?

Post by bartbes »

I never distributed any of those projects, but in that case the statement has to be changed to:

Code: Select all

love.filesystem.require("Client.lua")
nothing to do about it.
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Re: Can I require "package.file" instead of "package/file.lua"?

Post by sroccaserra »

Yes, that's the problem: I can't change the source code of the libs, most of them making their requires with the "package.file" syntax.

However, I looked at the Lua C source code and reimplemented the "loader_Lua" (mapped to package.loaders[2], see "loadlib.c") and "findfile" functions in Lua, adapting it to go through the LÖVE loader (mapped to package.loader[5] if I got it right).

Code: Select all

local luaLoader = function(name)
                      -- Replace all '.' by '/'
                      name = name:gsub('%.', '/')
                      -- Iterate over package.path templates
                      for template in package.path:gmatch('[^;]+') do
                          -- Replace all '?' by name
                          local path = template:gsub('%?', name)
                          -- Trim './' at the beginning of the path, as it doesn't work with the LÖVE loader
                          path = path:gsub('^%./', '')
                          -- Use the LÖVE loader to find the file
                          local result = package.loaders[5](path)
                          if 'function' == type(result) then
                              return result
                          end
                      end
                  end

table.insert(package.loaders, luaLoader)
This does the trick for me, I can package Lua libs in my .love file without changing their source code.
I tested this on the Mac and Windows versions of LÖVE 0.5.0.

Thanks!
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 56 guests