diff --git a/CMakeLists.txt b/CMakeLists.txt index eb205a7a1..f71b7bb34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,9 +158,6 @@ else() include_directories(${LIBPNG_DIR}) endif() -# Include duktape directory -include_directories(${DUKTAPE_DIR}) - # Do not use MMX optimizations in PNG code add_definitions(-DPNG_NO_MMX_CODE) diff --git a/src/app/app.cpp b/src/app/app.cpp index 795c74118..11aa3f8b9 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -67,6 +67,7 @@ #include "doc/sprite.h" #include "render/render.h" #include "scripting/engine.h" +#include "scripting/engine_delegate.h" #include "she/display.h" #include "she/error.h" #include "she/system.h" @@ -102,7 +103,6 @@ public: InputChain m_inputChain; // This is a raw pointer because we want to delete this explicitly. app::crash::DataRecovery* m_recovery; - scripting::Engine m_scriptingEngine; Modules(bool verbose) : m_loggerModule(verbose) @@ -131,6 +131,13 @@ public: }; +class StdoutEngineDelegate : public scripting::EngineDelegate { +public: + void onConsolePrint(const char* text) override { + printf("%s\n", text); + } +}; + App* App::m_instance = NULL; App::App() @@ -559,13 +566,10 @@ void App::run() // Start shell to execute scripts. if (m_isShell) { - if (m_modules->m_scriptingEngine.supportEval()) { - Shell shell; - shell.run(m_modules->m_scriptingEngine); - } - else { - std::cerr << "Your version of " PACKAGE " wasn't compiled with shell support.\n"; - } + StdoutEngineDelegate delegate; + scripting::Engine engine(&delegate); + Shell shell; + shell.run(engine); } // Destroy all documents in the UIContext. diff --git a/src/app/ui/devconsole_view.cpp b/src/app/ui/devconsole_view.cpp index 6ac599063..be21790af 100644 --- a/src/app/ui/devconsole_view.cpp +++ b/src/app/ui/devconsole_view.cpp @@ -61,9 +61,10 @@ protected: DevConsoleView::DevConsoleView() : Box(JI_VERTICAL) - , m_textBox("Welcome Aseprite Console\n(experimental)", JI_LEFT) + , m_textBox("Welcome to Aseprite JavaScript Console\n(Experimental)", JI_LEFT) , m_label(">") , m_entry(new CommmandEntry) + , m_engine(this) { SkinTheme* theme = static_cast(getTheme()); @@ -130,7 +131,13 @@ bool DevConsoleView::onProcessMessage(Message* msg) void DevConsoleView::onExecuteCommand(const std::string& cmd) { - m_textBox.setText(m_textBox.getText() + "\n" + cmd); + m_engine.eval(cmd); +} + +void DevConsoleView::onConsolePrint(const char* text) +{ + if (text) + m_textBox.setText(m_textBox.getText() + "\n" + text); } } // namespace app diff --git a/src/app/ui/devconsole_view.h b/src/app/ui/devconsole_view.h index 0f9572812..06f4c0c6f 100644 --- a/src/app/ui/devconsole_view.h +++ b/src/app/ui/devconsole_view.h @@ -11,6 +11,8 @@ #include "app/ui/tabs.h" #include "app/ui/workspace_view.h" +#include "scripting/engine.h" +#include "scripting/engine_delegate.h" #include "ui/box.h" #include "ui/label.h" #include "ui/textbox.h" @@ -19,7 +21,8 @@ namespace app { class DevConsoleView : public ui::Box , public TabView - , public WorkspaceView { + , public WorkspaceView + , public scripting::EngineDelegate { public: DevConsoleView(); ~DevConsoleView(); @@ -36,6 +39,9 @@ namespace app { bool onCloseView(Workspace* workspace) override; void onTabPopup(Workspace* workspace) override; + // EngineDelegate impl + virtual void onConsolePrint(const char* text) override; + protected: bool onProcessMessage(ui::Message* msg) override; void onExecuteCommand(const std::string& cmd); @@ -48,6 +54,7 @@ namespace app { ui::HBox m_bottomBox; ui::Label m_label; CommmandEntry* m_entry; + scripting::Engine m_engine; }; } // namespace app diff --git a/src/scripting/CMakeLists.txt b/src/scripting/CMakeLists.txt index eea3a6cb0..e91415d36 100644 --- a/src/scripting/CMakeLists.txt +++ b/src/scripting/CMakeLists.txt @@ -1,7 +1,7 @@ -# ASEPRITE -# Copyright (C) 2001-2013, 2015 David Capello +# Aseprite Scripting Library +# Copyright (C) 2015 David Capello + +include_directories(${DUKTAPE_DIR}) add_library(scripting-lib engine.cpp) - -target_link_libraries(scripting-lib duktape) diff --git a/src/scripting/LICENSE.txt b/src/scripting/LICENSE.txt new file mode 100644 index 000000000..11f1e5e40 --- /dev/null +++ b/src/scripting/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2015 David Capello + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/scripting/README.md b/src/scripting/README.md new file mode 100644 index 000000000..3862e85a7 --- /dev/null +++ b/src/scripting/README.md @@ -0,0 +1,4 @@ +# Aseprite Scripting Library +*Copyright (C) 2015 David Capello* + +> Distributed under [MIT license](LICENSE.txt) diff --git a/src/scripting/engine.cpp b/src/scripting/engine.cpp index 7c04330b3..7fc100342 100644 --- a/src/scripting/engine.cpp +++ b/src/scripting/engine.cpp @@ -1,9 +1,8 @@ -// Aseprite -// Copyright (C) 2001-2015 David Capello +// Aseprite Scripting Library +// Copyright (c) 2015 David Capello // -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. #include "scripting/engine.h" @@ -11,17 +10,14 @@ namespace scripting { - Engine::Engine() : m_impl(new EngineImpl) { + Engine::Engine(EngineDelegate* delegate) + : m_impl(new EngineImpl(delegate)) { } Engine::~Engine() { delete m_impl; } - bool Engine::supportEval() const { - return m_impl->supportEval(); - } - void Engine::eval(const std::string& script) { m_impl->eval(script); } diff --git a/src/scripting/engine.h b/src/scripting/engine.h index 6c8da5ed6..46aeb7e80 100644 --- a/src/scripting/engine.h +++ b/src/scripting/engine.h @@ -1,9 +1,8 @@ -// Aseprite -// Copyright (C) 2001-2015 David Capello +// Aseprite Scripting Library +// Copyright (c) 2015 David Capello // -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. #ifndef SCRIPTING_ENGINE_H_INCLUDED #define SCRIPTING_ENGINE_H_INCLUDED @@ -12,13 +11,13 @@ #include namespace scripting { + class EngineDelegate; class Engine { public: - Engine(); + Engine(EngineDelegate* delegate); ~Engine(); - bool supportEval() const; void eval(const std::string& script); private: diff --git a/src/scripting/engine_delegate.h b/src/scripting/engine_delegate.h new file mode 100644 index 000000000..b4e64b79e --- /dev/null +++ b/src/scripting/engine_delegate.h @@ -0,0 +1,21 @@ +// Aseprite Scripting Library +// Copyright (c) 2015 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SCRIPTING_ENGINE_DELEGATE_H_INCLUDED +#define SCRIPTING_ENGINE_DELEGATE_H_INCLUDED +#pragma once + +namespace scripting { + + class EngineDelegate { + public: + virtual ~EngineDelegate() { } + virtual void onConsolePrint(const char* text) = 0; + }; + +} + +#endif diff --git a/src/scripting/engine_duktape.h b/src/scripting/engine_duktape.h index 2f8fe14d9..7d8d33459 100644 --- a/src/scripting/engine_duktape.h +++ b/src/scripting/engine_duktape.h @@ -1,29 +1,62 @@ -// Aseprite -// Copyright (C) 2001-2015 David Capello +// Aseprite Scripting Library +// Copyright (c) 2015 David Capello // -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. #include "scripting/engine.h" +#include "base/convert_to.h" +#include "base/exception.h" +#include "base/memory.h" +#include "scripting/engine_delegate.h" + +#define DUK_OPT_PANIC_HANDLER scripting_engine_panic_handler #include -class scripting::Engine::EngineImpl -{ +class ScriptingEngineException : public base::Exception { public: - EngineImpl() { } + ScriptingEngineException(duk_errcode_t code, const char* msg) + : Exception(std::string(msg) + " (code " + base::convert_to(code) + ")") { + } +}; - bool supportEval() const { - return true; +static void scripting_engine_panic_handler(duk_errcode_t code, const char* msg) +{ + throw ScriptingEngineException(code, msg); +} + +extern "C" { + #include +} + +class scripting::Engine::EngineImpl { +private: + +public: + EngineImpl(EngineDelegate* delegate) + : m_delegate(delegate) { + m_ctx = duk_create_heap_default(); + } + + ~EngineImpl() { + duk_destroy_heap(m_ctx); } void eval(const std::string& scriptString) { - duk_context *ctx = duk_create_heap_default(); - duk_eval_string(ctx, scriptString.c_str()); - duk_pop(ctx); - printf("%s\n", duk_get_string(ctx, -1)); - duk_destroy_heap(ctx); + try { + duk_eval_string(m_ctx, scriptString.c_str()); + m_delegate->onConsolePrint(duk_safe_to_string(m_ctx, -1)); + duk_pop(m_ctx); + } + catch (const std::exception& ex) { + std::string err = "Error: "; + err += ex.what(); + m_delegate->onConsolePrint(err.c_str()); + } } +private: + duk_context* m_ctx; + EngineDelegate* m_delegate; }; diff --git a/src/scripting/engine_none.h b/src/scripting/engine_none.h deleted file mode 100644 index 48d2aaba3..000000000 --- a/src/scripting/engine_none.h +++ /dev/null @@ -1,22 +0,0 @@ -// Aseprite -// Copyright (C) 2001-2015 David Capello -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. - -#include "scripting/engine.h" - -class scripting::Engine::EngineImpl -{ -public: - EngineImpl() { } - - bool supportEval() const { - return false; - } - - void eval(const std::string& scriptString) { - } - -}; diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 49a9b76d5..59cd5aa7a 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -55,6 +55,3 @@ if(NOT USE_SHARED_PIXMAN) endif() add_subdirectory(simpleini) - -# Duktape -add_library(duktape duktape/duktape.c)