lua: Add app.params and --script-param

Now parameters for scripts can be specified from the CLI with
--script-params and from gui.xml or .aseprite-keys from <param>
sections.
This commit is contained in:
David Capello 2018-12-10 16:44:49 -03:00
parent 58c1ee1e0e
commit b2cafe4108
14 changed files with 83 additions and 14 deletions

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -63,6 +64,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames")) , m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
, m_script(m_po.add("script").requiresValue("<filename>").description("Execute a specific script")) , m_script(m_po.add("script").requiresValue("<filename>").description("Execute a specific script"))
, m_scriptParam(m_po.add("script-param").requiresValue("name=value").description("Parameter for a script executed from the\nCLI that you can access with app.params"))
#endif #endif
, m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data")) , m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data"))
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite\nor include frame tags in JSON data")) , m_listTags(m_po.add("list-tags").description("List tags of the next given sprite\nor include frame tags in JSON data"))

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -77,6 +78,7 @@ public:
const Option& filenameFormat() const { return m_filenameFormat; } const Option& filenameFormat() const { return m_filenameFormat; }
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
const Option& script() const { return m_script; } const Option& script() const { return m_script; }
const Option& scriptParam() const { return m_scriptParam; }
#endif #endif
const Option& listLayers() const { return m_listLayers; } const Option& listLayers() const { return m_listLayers; }
const Option& listTags() const { return m_listTags; } const Option& listTags() const { return m_listTags; }
@ -135,6 +137,7 @@ private:
Option& m_filenameFormat; Option& m_filenameFormat;
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
Option& m_script; Option& m_script;
Option& m_scriptParam;
#endif #endif
Option& m_listLayers; Option& m_listLayers;
Option& m_listTags; Option& m_listTags;

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello // Copyright (C) 2016-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -15,6 +16,7 @@ namespace app {
class AppOptions; class AppOptions;
class Context; class Context;
class DocExporter; class DocExporter;
class Params;
struct CliOpenFile; struct CliOpenFile;
class CliDelegate { class CliDelegate {
@ -30,7 +32,10 @@ namespace app {
virtual void saveFile(Context* ctx, const CliOpenFile& cof) { } virtual void saveFile(Context* ctx, const CliOpenFile& cof) { }
virtual void loadPalette(Context* ctx, const CliOpenFile& cof, const std::string& filename) { } virtual void loadPalette(Context* ctx, const CliOpenFile& cof, const std::string& filename) { }
virtual void exportFiles(Context* ctx, DocExporter& exporter) { } virtual void exportFiles(Context* ctx, DocExporter& exporter) { }
virtual void execScript(const std::string& filename) { } #ifdef ENABLE_SCRIPTING
virtual void execScript(const std::string& filename,
const Params& params) { }
#endif // ENABLE_SCRIPTING
}; };
} // namespace app } // namespace app

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -134,6 +135,9 @@ void CliProcessor::process(Context* ctx)
} }
// Process other options and file names // Process other options and file names
else if (!m_options.values().empty()) { else if (!m_options.values().empty()) {
#ifdef ENABLE_SCRIPTING
Params scriptParams;
#endif
Console console; Console console;
CliOpenFile cof; CliOpenFile cof;
SpriteSheetType sheetType = SpriteSheetType::None; SpriteSheetType sheetType = SpriteSheetType::None;
@ -431,7 +435,17 @@ void CliProcessor::process(Context* ctx)
// --script <filename> // --script <filename>
else if (opt == &m_options.script()) { else if (opt == &m_options.script()) {
std::string filename = value.value(); std::string filename = value.value();
m_delegate->execScript(filename); m_delegate->execScript(filename, scriptParams);
}
// --script-param <name=value>
else if (opt == &m_options.scriptParam()) {
const std::string& v = value.value();
auto i = v.find('=');
if (i != std::string::npos)
scriptParams.set(v.substr(0, i).c_str(),
v.substr(i+1).c_str());
else
scriptParams.set(v.c_str(), "1");
} }
#endif #endif
// --list-layers // --list-layers

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello // Copyright (C) 2016-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -33,7 +34,10 @@ public:
void afterOpenFile(const CliOpenFile& cof) override { } void afterOpenFile(const CliOpenFile& cof) override { }
void saveFile(Context* ctx, const CliOpenFile& cof) override { } void saveFile(Context* ctx, const CliOpenFile& cof) override { }
void exportFiles(Context* ctx, DocExporter& exporter) override { } void exportFiles(Context* ctx, DocExporter& exporter) override { }
void execScript(const std::string& filename) override { } #ifdef ENABLE_SCRIPTING
void execScript(const std::string& filename,
const Params& params) override { }
#endif
bool helpWasShown() const { return m_helpWasShown; } bool helpWasShown() const { return m_helpWasShown; }
bool versionWasShown() const { return m_versionWasShown; } bool versionWasShown() const { return m_versionWasShown; }

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello // Copyright (C) 2016-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -127,12 +128,13 @@ void DefaultCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
LOG("APP: Export sprite sheet: Done\n"); LOG("APP: Export sprite sheet: Done\n");
} }
void DefaultCliDelegate::execScript(const std::string& filename)
{
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
if (!App::instance()->scriptEngine()->evalFile(filename)) void DefaultCliDelegate::execScript(const std::string& filename,
const Params& params)
{
if (!App::instance()->scriptEngine()->evalFile(filename, params))
throw std::runtime_error("Error executing script"); throw std::runtime_error("Error executing script");
#endif
} }
#endif // ENABLE_SCRIPTING
} // namespace app } // namespace app

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello // Copyright (C) 2016-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -20,7 +21,10 @@ namespace app {
void saveFile(Context* ctx, const CliOpenFile& cof) override; void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const CliOpenFile& cof, const std::string& filename) override; void loadPalette(Context* ctx, const CliOpenFile& cof, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override; void exportFiles(Context* ctx, DocExporter& exporter) override;
void execScript(const std::string& filename) override; #ifdef ENABLE_SCRIPTING
void execScript(const std::string& filename,
const Params& params) override;
#endif
}; };
} // namespace app } // namespace app

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello // Copyright (C) 2016-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -206,10 +207,19 @@ void PreviewCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
} }
} }
void PreviewCliDelegate::execScript(const std::string& filename) #ifdef ENABLE_SCRIPTING
void PreviewCliDelegate::execScript(const std::string& filename,
const Params& params)
{ {
std::cout << "- Run script: '" << filename << "'\n"; std::cout << "- Run script: '" << filename << "'\n";
if (!params.empty()) {
std::cout << " - With app.params = {\n";
for (const auto& kv : params)
std::cout << " " << kv.first << "=\"" << kv.second << "\",\n";
std::cout << " }\n";
}
} }
#endif // ENABLE_SCRIPTING
void PreviewCliDelegate::showLayersFilter(const CliOpenFile& cof) void PreviewCliDelegate::showLayersFilter(const CliOpenFile& cof)
{ {

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello // Copyright (C) 2016-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -26,7 +27,10 @@ namespace app {
const CliOpenFile& cof, const CliOpenFile& cof,
const std::string& filename) override; const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override; void exportFiles(Context* ctx, DocExporter& exporter) override;
void execScript(const std::string& filename) override; #ifdef ENABLE_SCRIPTING
void execScript(const std::string& filename,
const Params& params) override;
#endif // ENABLE_SCRIPTING
private: private:
void showLayersFilter(const CliOpenFile& cof); void showLayersFilter(const CliOpenFile& cof);

View File

@ -43,6 +43,7 @@ protected:
private: private:
std::string m_filename; std::string m_filename;
Params m_params;
}; };
RunScriptCommand::RunScriptCommand() RunScriptCommand::RunScriptCommand()
@ -59,6 +60,8 @@ void RunScriptCommand::onLoadParams(const Params& params)
if (rf.findFirst()) if (rf.findFirst())
m_filename = rf.filename(); m_filename = rf.filename();
} }
m_params = params;
} }
void RunScriptCommand::onExecute(Context* context) void RunScriptCommand::onExecute(Context* context)
@ -76,7 +79,7 @@ void RunScriptCommand::onExecute(Context* context)
App::instance() App::instance()
->scriptEngine() ->scriptEngine()
->evalFile(m_filename); ->evalFile(m_filename, m_params);
ui::Manager::getDefault()->invalidate(); ui::Manager::getDefault()->invalidate();
} }

View File

@ -10,6 +10,6 @@
// Increment this value if the scripting API is modified between two // Increment this value if the scripting API is modified between two
// released Aseprite versions. // released Aseprite versions.
#define API_VERSION 1 #define API_VERSION 2
#endif #endif

View File

@ -468,5 +468,17 @@ void register_app_object(lua_State* L)
lua_pop(L, 1); // Pop app table lua_pop(L, 1); // Pop app table
} }
void set_app_params(lua_State* L, const Params& params)
{
lua_getglobal(L, "app");
lua_newtable(L);
for (const auto& kv : params) {
lua_pushstring(L, kv.second.c_str());
lua_setfield(L, -2, kv.first.c_str());
}
lua_setfield(L, -2, "params");
lua_pop(L, 1);
}
} // namespace script } // namespace script
} // namespace app } // namespace app

View File

@ -161,6 +161,8 @@ void register_sprites_class(lua_State* L);
void register_tag_class(lua_State* L); void register_tag_class(lua_State* L);
void register_tags_class(lua_State* L); void register_tags_class(lua_State* L);
void set_app_params(lua_State* L, const Params& params);
// We use our own fopen() that supports Unicode filename on Windows // We use our own fopen() that supports Unicode filename on Windows
extern "C" FILE* lua_user_fopen(const char* fname, extern "C" FILE* lua_user_fopen(const char* fname,
const char* mode) const char* mode)
@ -351,7 +353,8 @@ bool Engine::evalCode(const std::string& code,
return ok; return ok;
} }
bool Engine::evalFile(const std::string& filename) bool Engine::evalFile(const std::string& filename,
const Params& params)
{ {
std::stringstream buf; std::stringstream buf;
{ {
@ -361,6 +364,7 @@ bool Engine::evalFile(const std::string& filename)
std::string absFilename = base::get_absolute_path(filename); std::string absFilename = base::get_absolute_path(filename);
AddScriptFilename add(absFilename); AddScriptFilename add(absFilename);
set_app_params(L, params);
return evalCode(buf.str(), "@" + absFilename); return evalCode(buf.str(), "@" + absFilename);
} }

View File

@ -14,6 +14,7 @@
#endif #endif
#include "app/color.h" #include "app/color.h"
#include "app/commands/params.h"
#include "doc/frame.h" #include "doc/frame.h"
#include "doc/object_ids.h" #include "doc/object_ids.h"
#include "gfx/fwd.h" #include "gfx/fwd.h"
@ -67,7 +68,8 @@ namespace app {
void printLastResult(); void printLastResult();
bool evalCode(const std::string& code, bool evalCode(const std::string& code,
const std::string& filename = std::string()); const std::string& filename = std::string());
bool evalFile(const std::string& filename); bool evalFile(const std::string& filename,
const Params& params = Params());
void consolePrint(const char* text) { void consolePrint(const char* text) {
onConsolePrint(text); onConsolePrint(text);