Add basic scripting support to eval expression in --shell and DevConsole

This commit is contained in:
David Capello 2015-06-19 20:01:30 -03:00
parent 699d60b03f
commit 5b17f44526
13 changed files with 138 additions and 75 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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<SkinTheme*>(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

View File

@ -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

View File

@ -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)

20
src/scripting/LICENSE.txt Normal file
View File

@ -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.

4
src/scripting/README.md Normal file
View File

@ -0,0 +1,4 @@
# Aseprite Scripting Library
*Copyright (C) 2015 David Capello*
> Distributed under [MIT license](LICENSE.txt)

View File

@ -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);
}

View File

@ -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 <string>
namespace scripting {
class EngineDelegate;
class Engine {
public:
Engine();
Engine(EngineDelegate* delegate);
~Engine();
bool supportEval() const;
void eval(const std::string& script);
private:

View File

@ -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

View File

@ -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 <duktape.h>
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<std::string>(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 <duktape.c>
}
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;
};

View File

@ -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) {
}
};

View File

@ -55,6 +55,3 @@ if(NOT USE_SHARED_PIXMAN)
endif()
add_subdirectory(simpleini)
# Duktape
add_library(duktape duktape/duktape.c)