pioneerspacesim/pioneer — pull request #1499 by robn (2012-09-10 12:37:39+00:00)
Title: Lua module dependencies

Implements an `import()` function to let modules declare/import dependencies. There's a bunch of changes around how modules and Lua stuff in general work:

* Stuff in `modules/libs` is no longer loaded automatically. `import("foo")` will load `data/libs/foo.lua`, which is expected to return a table. This table is stored in the registry, and a reference to it returned from `import()`. The next time the same name is imported another reference to the original table is returned. The table no longer appears in the global namespace, so the module needs to store it in a local variable to use it.

* Core-provided modules get pre-seeded into the registry, so also need to be imported (eg `import("Game")`. This is done as a form of future-proofing, in case we move a module out into Lua.

* There's an internal version of `import()`, `pi_lua_import()` which has the same basic operation but is needed for C++ code to get access to Lua-provided functionality (eg `Event` and `NameGen`).

Things that suck right now (ie ideas welcome):

* Modules can still assign into the global table and so hurt other modules. But that's kind of the same as now, so perhaps we can ignore that.

* Console is kind of awkward. You can't really use `local` because each line is its own scope. But that means assigning to a global which makes it appear everywhere, or doing `import("foo").bar()` every time, which sucks. The only idea I've had so far is to give the whole console its own global table, but that's still going to have it holding onto a bit too much state for my liking.

* I'm not sure what to do with libs that want to extend other stuff, namely `StringInterp.lua` that adds `string.interp`. Yep, really, no ideas at all.

* Most modules need many imports to get anything done, which means a lot of boilerplate. Its good to be explicit, but its a bit icky. `local foo, bar, baz = import("foo", "bar", "baz")` was proposed but I don't really think that's significantly better.