Page 1 of 1

"require" fails in celx scripts

Posted: 13.06.2007, 10:03
by selden
Is there any way to make use of libraries of celx functions in celx scripts?

require "celx_utils"

fails with the popup message

Fatal Error
[string "c\Program Files\celestia\extras\Addons\poi..."]:3: attempt to call global 'require' (a nil value)

Specifying
ScriptSystemAccessPolicy "allow"
in celestia.cfg doesn't make any difference.

p.s. it'd be nice if the text in the error popups could be selected and pasted.

Posted: 13.06.2007, 12:45
by Vincent
Selden,

Specifying

Code: Select all

ScriptSystemAccessPolicy "allow"
in celestia.cfg is a good start.

Then, you must request permission to access the libraries by adding the following lines at the beginning of your script:

Code: Select all

celestia:requestsystemaccess()
wait(0)


Finally, AFAIR, the required file should be defined with a path relative to the celestia base directory.

Posted: 13.06.2007, 13:17
by selden
Vincent,

Thanks!

(Although I really think that "require" shouldn't need system access. That opens one up to many possible problems. Accessing a celx code library is much safer than writing to the system environment.)

Posted: 13.06.2007, 13:22
by selden
A related problem:

An Addon's "require"d Lua files are not found if they're in the Addon's subdirectory celxx.

ScriptedOrientation Lua scripts are found if they're in the Addon's subdirectory celxx. That subdirectory should be searched for an Addon's other Lua files, too.

Mixing an Addon's files in with Celestia's own files is not appropriate.

Posted: 13.06.2007, 16:10
by hank
selden wrote:A related problem:

An Addon's "require"d Lua files are not found if they're in the Addon's subdirectory celxx.

ScriptedOrientation Lua scripts are found if they're in the Addon's subdirectory celxx. That subdirectory should be searched for an Addon's other Lua files, too.

Mixing an Addon's files in with Celestia's own files is not appropriate.


Lua (5.1) lets you specify where it should look for "require"d modules. You do this by setting the 'package.path' variable to a string which contains a list of file patterns, separated by semicolons. Each file pattern is a filename template with a question mark where the module name should be substituted.

For example, the following:

Code: Select all

package.path = "lookhere/?.lua;lookthere/?.lua";
require "test";

would load the module "test" from "lookhere/test.lua" or "lookthere/test.lua".

- Hank

Posted: 13.06.2007, 18:50
by selden
Hank,

Thanks!

Posted: 13.06.2007, 21:47
by selden
Hank,

I'm sorry to report that package.path doesn't do what I need. :(

My test script (test_require.celx) is in
C:\Program Files\Celestia\extras\Addons\pointing_hubble\
My file of Lua functions (celutil.lua) is in
C:\Program Files\Celestia\extras\Addons\pointing_hubble\celxx\

My test script contains

Code: Select all

celestia:requestsystemaccess(); wait(0)

package.path = "./celxx/?.lua";

require "celutil";


My file of functions contains

Code: Select all

celestia:print("./celxx/celutil loaded" )


When I double-click on icon of test_require.celx, I get a "Fatal Error" popup that says
[string "C:\Program Files\Celestia\extras\Addons\poi..."]:20:module 'celutil' not found
no field package.preload['celutil']
no file '.\celxx\celutil.lua'
no file '.\celutil.dll'
no file 'C:\Program Files\Celestia\celutil.dll'
no file 'C:\Program Files\Celestia\loadalldll'


Apparently the Lua interpreter's definition of "." is not what I expected. :(

Posted: 13.06.2007, 23:24
by hank
selden wrote:Hank,

I'm sorry to report that package.path doesn't do what I need. :(

...

Apparently the Lua interpreter's definition of "." is not what I expected. :(

Lua doesn't recognize "." in a file pattern as a reference to the current working directory. You might try a relative path in the file pattern, i.e. "celxx/?.lua", but I'm not sure what the working directory would be here, and Lua may actually require an absolute path.

You could use the explicit path "C:\Program Files\Celestia\extras\Addons\pointing_hubble\celxx\?.lua". Although that would work, it's platform- and installation-specific, which is obviously undesirable. Instead, you could obtain the path to the current Lua source file using the debug library, and use that to construct the path for the library. Something like this:

Code: Select all

   local sourceinfo = debug.getinfo(1,"S");
   local sourcefile = sourceinfo.source;
   sourcefile = string.sub(sourcefile,2);
   local sourcedir = string.sub(sourcefile,string.find(sourcefile,".*%/"));
   package.path = sourcedir.."celxx/?.lua";

At least, I think something like that might work...

- Hank

Posted: 14.06.2007, 08:49
by selden
Hank,

Thanks, but...

This is all extremely ugly :(

What are the chances of adding the Addon's local directory and its subdirectory celxx to the search list of require so its search list is the same as the search list for ScriptedOrientation? Eliminating this inconsistency would help a lot.

Posted: 14.06.2007, 09:58
by selden
Hank,

Since I'm running under Windows, I had to change your code somewhat: the sourcefile string contains "\" not "/". The following worked for me:

Code: Select all

   local sourceinfo = debug.getinfo(1,"S");
   local sourcefile = sourceinfo.source;
   local n_1,n_2 = string.find(sourcefile,".*%\\")
    if (n_1 == nil) then n_1,n_2 =string.find(sourcefile,".*%/") end
   local sourcedir = string.sub(sourcefile,n_1,n_2);
   package.path = sourcedir.."celxx/?.lua";

require "celutil"

Posted: 14.06.2007, 17:04
by hank
selden wrote:Hank,

Thanks, but...

This is all extremely ugly :(

What are the chances of adding the Addon's local directory and its subdirectory celxx to the search list of require so its search list is the same as the search list for ScriptedOrientation? Eliminating this inconsistency would help a lot.

It may be ugly, but it works. There's some beauty in that, I think. The alternative is to wait for a future version of Celestia to provide a simpler solution with built-in code. Fortunately, with Lua, that's not the only option. But I would agree with you that pre-loading package.path with a sensible default would be useful for script writers. It shouldn't be too difficult to implement; just a simple matter of programming...

- Hank