Make dfhack.run_script usable from other scripts, and document it.

develop
Alexander Gavrilov 2012-06-14 12:46:12 +04:00
parent 2781723f7b
commit 7eb4fc19de
4 changed files with 34 additions and 11 deletions

@ -491,6 +491,13 @@ Currently it defines the following features:
Compares to coroutine.resume like dfhack.safecall vs pcall.
* ``dfhack.run_script(name[,args...])``
Run a lua script in hack/scripts/, as if it was started from dfhack command-line.
The ``name`` argument should be the name stem, as would be used on the command line.
Note that the script is re-read from the file every time it is called, and errors
are propagated to the caller.
* ``dfhack.with_suspend(f[,args...])``
Calls ``f`` with arguments after grabbing the DF core suspend lock.
@ -1148,6 +1155,11 @@ Internal API
These functions are intended for the use by dfhack developers,
and are only documented here for completeness:
* ``dfhack.internal.scripts``
The table used by ``dfhack.run_script()`` to give every script its own
global environment, persistent between calls to the script.
* ``dfhack.internal.getAddress(name)``
Returns the global address ``name``, or *nil*.

@ -766,6 +766,12 @@ returning. Intended as a convenience function.</p>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.saferesume(coroutine[,args...])</span></tt></p>
<p>Compares to coroutine.resume like dfhack.safecall vs pcall.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.run_script(name[,args...])</span></tt></p>
<p>Run a lua script in hack/scripts/, as if it was started from dfhack command-line.
The <tt class="docutils literal">name</tt> argument should be the name stem, as would be used on the command line.
Note that the script is re-read from the file every time it is called, and errors
are propagated to the caller.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.with_suspend(f[,args...])</span></tt></p>
<p>Calls <tt class="docutils literal">f</tt> with arguments after grabbing the DF core suspend lock.
Suspending is necessary for accessing a consistent state of DF memory.</p>
@ -1310,6 +1316,10 @@ Returns <em>true, was_only_planned</em> if removed; or <em>false</em> if none fo
<p>These functions are intended for the use by dfhack developers,
and are only documented here for completeness:</p>
<ul>
<li><p class="first"><tt class="docutils literal">dfhack.internal.scripts</tt></p>
<p>The table used by <tt class="docutils literal">dfhack.run_script()</tt> to give every script its own
global environment, persistent between calls to the script.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.internal.getAddress(name)</tt></p>
<p>Returns the global address <tt class="docutils literal">name</tt>, or <em>nil</em>.</p>
</li>

@ -264,16 +264,12 @@ static bool init_run_script(color_ostream &out, lua_State *state, void *info)
return true;
}
static command_result runLuaScript(color_ostream &out, std::string filename, vector<string> &args)
static command_result runLuaScript(color_ostream &out, std::string name, vector<string> &args)
{
ScriptArgs data;
data.pcmd = &filename;
data.pcmd = &name;
data.pargs = &args;
#ifndef LINUX_BUILD
filename = toLower(filename);
#endif
bool ok = Lua::RunCoreQueryLoop(out, Lua::Core::State, init_run_script, &data);
return ok ? CR_OK : CR_FAILURE;
@ -619,7 +615,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first, ve
{
auto filename = getHackPath() + "scripts/" + first + ".lua";
if (fileExists(filename))
res = runLuaScript(con, filename, parts);
res = runLuaScript(con, first, parts);
else
con.printerr("%s is not a recognized command.\n", first.c_str());
}

@ -273,19 +273,24 @@ end
-- Command scripts
dfhack.scripts = dfhack.scripts or {}
dfhack.internal.scripts = dfhack.internal.scripts or {}
function dfhack.run_script(file,...)
local env = dfhack.scripts[file]
local scripts = dfhack.internal.scripts
local hack_path = dfhack.getHackPath()
function dfhack.run_script(name,...)
local key = string.lower(name)
local file = hack_path..'scripts/'..name..'.lua'
local env = scripts[key]
if env == nil then
env = {}
setmetatable(env, { __index = base_env })
dfhack.scripts[file] = env
end
local f,perr = loadfile(file, 't', env)
if f == nil then
error(perr)
end
scripts[key] = env
return f(...)
end