From b2cafe41082900e760e70121859868a7df778b71 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 10 Dec 2018 16:44:49 -0300 Subject: [PATCH] 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 sections. --- src/app/cli/app_options.cpp | 2 ++ src/app/cli/app_options.h | 3 +++ src/app/cli/cli_delegate.h | 7 ++++++- src/app/cli/cli_processor.cpp | 16 +++++++++++++++- src/app/cli/cli_tests.cpp | 6 +++++- src/app/cli/default_cli_delegate.cpp | 10 ++++++---- src/app/cli/default_cli_delegate.h | 6 +++++- src/app/cli/preview_cli_delegate.cpp | 12 +++++++++++- src/app/cli/preview_cli_delegate.h | 6 +++++- src/app/commands/cmd_run_script.cpp | 5 ++++- src/app/script/api_version.h | 2 +- src/app/script/app_object.cpp | 12 ++++++++++++ src/app/script/engine.cpp | 6 +++++- src/app/script/engine.h | 4 +++- 14 files changed, 83 insertions(+), 14 deletions(-) diff --git a/src/app/cli/app_options.cpp b/src/app/cli/app_options.cpp index be31aa993..e0bd1005e 100644 --- a/src/app/cli/app_options.cpp +++ b/src/app/cli/app_options.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // 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("").description("Special format to generate filenames")) #ifdef ENABLE_SCRIPTING , m_script(m_po.add("script").requiresValue("").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 , 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")) diff --git a/src/app/cli/app_options.h b/src/app/cli/app_options.h index e926e4394..ecace8aab 100644 --- a/src/app/cli/app_options.h +++ b/src/app/cli/app_options.h @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of @@ -77,6 +78,7 @@ public: const Option& filenameFormat() const { return m_filenameFormat; } #ifdef ENABLE_SCRIPTING const Option& script() const { return m_script; } + const Option& scriptParam() const { return m_scriptParam; } #endif const Option& listLayers() const { return m_listLayers; } const Option& listTags() const { return m_listTags; } @@ -135,6 +137,7 @@ private: Option& m_filenameFormat; #ifdef ENABLE_SCRIPTING Option& m_script; + Option& m_scriptParam; #endif Option& m_listLayers; Option& m_listTags; diff --git a/src/app/cli/cli_delegate.h b/src/app/cli/cli_delegate.h index 7d2ad24d9..3bf752a1a 100644 --- a/src/app/cli/cli_delegate.h +++ b/src/app/cli/cli_delegate.h @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This program is distributed under the terms of @@ -15,6 +16,7 @@ namespace app { class AppOptions; class Context; class DocExporter; + class Params; struct CliOpenFile; class CliDelegate { @@ -30,7 +32,10 @@ namespace app { virtual void saveFile(Context* ctx, const CliOpenFile& cof) { } virtual void loadPalette(Context* ctx, const CliOpenFile& cof, const std::string& filename) { } 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 diff --git a/src/app/cli/cli_processor.cpp b/src/app/cli/cli_processor.cpp index e2117d96b..c468ef9e6 100644 --- a/src/app/cli/cli_processor.cpp +++ b/src/app/cli/cli_processor.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -134,6 +135,9 @@ void CliProcessor::process(Context* ctx) } // Process other options and file names else if (!m_options.values().empty()) { +#ifdef ENABLE_SCRIPTING + Params scriptParams; +#endif Console console; CliOpenFile cof; SpriteSheetType sheetType = SpriteSheetType::None; @@ -431,7 +435,17 @@ void CliProcessor::process(Context* ctx) // --script else if (opt == &m_options.script()) { std::string filename = value.value(); - m_delegate->execScript(filename); + m_delegate->execScript(filename, scriptParams); + } + // --script-param + 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 // --list-layers diff --git a/src/app/cli/cli_tests.cpp b/src/app/cli/cli_tests.cpp index fa0701f71..3b30cbfd5 100644 --- a/src/app/cli/cli_tests.cpp +++ b/src/app/cli/cli_tests.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This program is distributed under the terms of @@ -33,7 +34,10 @@ public: void afterOpenFile(const CliOpenFile& cof) override { } void saveFile(Context* ctx, const CliOpenFile& cof) 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 versionWasShown() const { return m_versionWasShown; } diff --git a/src/app/cli/default_cli_delegate.cpp b/src/app/cli/default_cli_delegate.cpp index 7f4e6dfe4..3c94c4814 100644 --- a/src/app/cli/default_cli_delegate.cpp +++ b/src/app/cli/default_cli_delegate.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // 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"); } -void DefaultCliDelegate::execScript(const std::string& filename) -{ #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"); -#endif } +#endif // ENABLE_SCRIPTING } // namespace app diff --git a/src/app/cli/default_cli_delegate.h b/src/app/cli/default_cli_delegate.h index 9c1efb375..e71b52f04 100644 --- a/src/app/cli/default_cli_delegate.h +++ b/src/app/cli/default_cli_delegate.h @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This program is distributed under the terms of @@ -20,7 +21,10 @@ namespace app { void saveFile(Context* ctx, const CliOpenFile& cof) override; void loadPalette(Context* ctx, const CliOpenFile& cof, const std::string& filename) 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 diff --git a/src/app/cli/preview_cli_delegate.cpp b/src/app/cli/preview_cli_delegate.cpp index 84fa3dfad..fe5a500b7 100644 --- a/src/app/cli/preview_cli_delegate.cpp +++ b/src/app/cli/preview_cli_delegate.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // 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"; + 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) { diff --git a/src/app/cli/preview_cli_delegate.h b/src/app/cli/preview_cli_delegate.h index b4f2643cd..ee44d0293 100644 --- a/src/app/cli/preview_cli_delegate.h +++ b/src/app/cli/preview_cli_delegate.h @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2016-2018 David Capello // // This program is distributed under the terms of @@ -26,7 +27,10 @@ namespace app { const CliOpenFile& cof, const std::string& filename) 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: void showLayersFilter(const CliOpenFile& cof); diff --git a/src/app/commands/cmd_run_script.cpp b/src/app/commands/cmd_run_script.cpp index 7b378c9c1..cdf0b43d1 100644 --- a/src/app/commands/cmd_run_script.cpp +++ b/src/app/commands/cmd_run_script.cpp @@ -43,6 +43,7 @@ protected: private: std::string m_filename; + Params m_params; }; RunScriptCommand::RunScriptCommand() @@ -59,6 +60,8 @@ void RunScriptCommand::onLoadParams(const Params& params) if (rf.findFirst()) m_filename = rf.filename(); } + + m_params = params; } void RunScriptCommand::onExecute(Context* context) @@ -76,7 +79,7 @@ void RunScriptCommand::onExecute(Context* context) App::instance() ->scriptEngine() - ->evalFile(m_filename); + ->evalFile(m_filename, m_params); ui::Manager::getDefault()->invalidate(); } diff --git a/src/app/script/api_version.h b/src/app/script/api_version.h index 3dfc97491..528b761bb 100644 --- a/src/app/script/api_version.h +++ b/src/app/script/api_version.h @@ -10,6 +10,6 @@ // Increment this value if the scripting API is modified between two // released Aseprite versions. -#define API_VERSION 1 +#define API_VERSION 2 #endif diff --git a/src/app/script/app_object.cpp b/src/app/script/app_object.cpp index beb0f5fdd..b156966b7 100644 --- a/src/app/script/app_object.cpp +++ b/src/app/script/app_object.cpp @@ -468,5 +468,17 @@ void register_app_object(lua_State* L) 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 app diff --git a/src/app/script/engine.cpp b/src/app/script/engine.cpp index 3bcc14f01..157e061d5 100644 --- a/src/app/script/engine.cpp +++ b/src/app/script/engine.cpp @@ -161,6 +161,8 @@ void register_sprites_class(lua_State* L); void register_tag_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 extern "C" FILE* lua_user_fopen(const char* fname, const char* mode) @@ -351,7 +353,8 @@ bool Engine::evalCode(const std::string& code, return ok; } -bool Engine::evalFile(const std::string& filename) +bool Engine::evalFile(const std::string& filename, + const Params& params) { std::stringstream buf; { @@ -361,6 +364,7 @@ bool Engine::evalFile(const std::string& filename) std::string absFilename = base::get_absolute_path(filename); AddScriptFilename add(absFilename); + set_app_params(L, params); return evalCode(buf.str(), "@" + absFilename); } diff --git a/src/app/script/engine.h b/src/app/script/engine.h index 0c9ea106b..4c798d8e6 100644 --- a/src/app/script/engine.h +++ b/src/app/script/engine.h @@ -14,6 +14,7 @@ #endif #include "app/color.h" +#include "app/commands/params.h" #include "doc/frame.h" #include "doc/object_ids.h" #include "gfx/fwd.h" @@ -67,7 +68,8 @@ namespace app { void printLastResult(); bool evalCode(const std::string& code, 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) { onConsolePrint(text);