mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-06 06:50:07 +00:00
Refactor scripting code
This commit is contained in:
parent
2ce09c53dd
commit
21921fdfd5
@ -82,16 +82,17 @@ And it uses the following third-party libraries:
|
|||||||
* [Google Test](https://github.com/google/googletest) - [gtest license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/gtest-LICENSE.txt)
|
* [Google Test](https://github.com/google/googletest) - [gtest license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/gtest-LICENSE.txt)
|
||||||
* [XFree86](http://www.x.org/) - [XFree86 license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/XFree86-LICENSE.txt)
|
* [XFree86](http://www.x.org/) - [XFree86 license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/XFree86-LICENSE.txt)
|
||||||
* [curl](http://curl.haxx.se/) - [curl license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/curl-LICENSE.txt)
|
* [curl](http://curl.haxx.se/) - [curl license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/curl-LICENSE.txt)
|
||||||
|
* [duktape](http://duktape.org/) - [MIT license](https://github.com/aseprite/aseprite/tree/master/third_party/duktape/LICENSE.txt)
|
||||||
* [giflib](http://sourceforge.net/projects/giflib/) - [giflib license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/giflib-LICENSE.txt)
|
* [giflib](http://sourceforge.net/projects/giflib/) - [giflib license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/giflib-LICENSE.txt)
|
||||||
* [libjpeg](http://www.ijg.org/) - [libjpeg license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/libjpeg-LICENSE.txt)
|
* [libjpeg](http://www.ijg.org/) - [libjpeg license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/libjpeg-LICENSE.txt)
|
||||||
* [libpng](http://www.libpng.org/pub/png/) - [libpng license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/libpng-LICENSE.txt)
|
* [libpng](http://www.libpng.org/pub/png/) - [libpng license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/libpng-LICENSE.txt)
|
||||||
* [libwebp](https://developers.google.com/speed/webp/) - [libwebp license](https://chromium.googlesource.com/webm/libwebp/+/master/COPYING)
|
* [libwebp](https://developers.google.com/speed/webp/) - [libwebp license](https://chromium.googlesource.com/webm/libwebp/+/master/COPYING)
|
||||||
* [loadpng](http://tjaden.strangesoft.net/loadpng/) - [zlib license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/ZLIB.txt)
|
* [loadpng](http://tjaden.strangesoft.net/loadpng/) - [zlib license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/ZLIB.txt)
|
||||||
|
* [modp_b64](https://github.com/aseprite/aseprite/tree/master/third_party/modp_b64/modp_b64.h) - [BSD license](https://github.com/aseprite/aseprite/tree/master/third_party/modp_b64/LICENSE)
|
||||||
* [pixman](http://www.pixman.org/) - [MIT license](http://cgit.freedesktop.org/pixman/plain/COPYING)
|
* [pixman](http://www.pixman.org/) - [MIT license](http://cgit.freedesktop.org/pixman/plain/COPYING)
|
||||||
* [simpleini](https://github.com/aseprite/simpleini/) - [MIT license](https://github.com/aseprite/simpleini/blob/aseprite/LICENCE.txt)
|
* [simpleini](https://github.com/aseprite/simpleini/) - [MIT license](https://github.com/aseprite/simpleini/blob/aseprite/LICENCE.txt)
|
||||||
* [tinyxml](http://www.sourceforge.net/projects/tinyxml) - [zlib license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/ZLIB.txt)
|
* [tinyxml](http://www.sourceforge.net/projects/tinyxml) - [zlib license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/ZLIB.txt)
|
||||||
* [zlib](http://www.gzip.org/zlib/) - [ZLIB license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/ZLIB.txt)
|
* [zlib](http://www.gzip.org/zlib/) - [ZLIB license](https://github.com/aseprite/aseprite/tree/master/docs/licenses/ZLIB.txt)
|
||||||
* [modp_b64](https://github.com/aseprite/aseprite/tree/master/third_party/modp_b64/modp_b64.h) - [BSD license](https://github.com/aseprite/aseprite/tree/master/third_party/modp_b64/LICENSE)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2015 by David Capello
|
// Copyright (C) 2015-2016 by David Capello
|
||||||
|
|
||||||
var spr = activeSprite
|
var col = app.pixelColor
|
||||||
|
var img = app.activeSprite
|
||||||
|
|
||||||
for (y=0; y<spr.height; ++y) {
|
for (y=0; y<img.height; ++y) {
|
||||||
for (x=0; x<spr.width; ++x) {
|
for (x=0; x<img.width; ++x) {
|
||||||
var c = spr.getPixel(x, y)
|
var c = img.getPixel(x, y)
|
||||||
var v = (rgbaR(c)+rgbaG(c)+rgbaB(c))/3
|
var v = (col.rgbaR(c)+
|
||||||
spr.putPixel(x, y, rgba(rgbaR(c),
|
col.rgbaG(c)+
|
||||||
rgbaG(c),
|
col.rgbaB(c))/3
|
||||||
rgbaB(c),
|
|
||||||
255-v))
|
img.putPixel(x, y,
|
||||||
|
col.rgba(col.rgbaR(c),
|
||||||
|
col.rgbaG(c),
|
||||||
|
col.rgbaB(c),
|
||||||
|
255-v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ add_subdirectory(gfx)
|
|||||||
add_subdirectory(net)
|
add_subdirectory(net)
|
||||||
add_subdirectory(pen)
|
add_subdirectory(pen)
|
||||||
add_subdirectory(render)
|
add_subdirectory(render)
|
||||||
add_subdirectory(scripting)
|
add_subdirectory(script)
|
||||||
add_subdirectory(she)
|
add_subdirectory(she)
|
||||||
add_subdirectory(ui)
|
add_subdirectory(ui)
|
||||||
add_subdirectory(undo)
|
add_subdirectory(undo)
|
||||||
|
@ -318,7 +318,10 @@ add_library(app-lib
|
|||||||
res/palettes_loader_delegate.cpp
|
res/palettes_loader_delegate.cpp
|
||||||
res/resources_loader.cpp
|
res/resources_loader.cpp
|
||||||
resource_finder.cpp
|
resource_finder.cpp
|
||||||
scripting/app_scripting.cpp
|
script/app_object.cpp
|
||||||
|
script/app_scripting.cpp
|
||||||
|
script/console_object.cpp
|
||||||
|
script/sprite_class.cpp
|
||||||
send_crash.cpp
|
send_crash.cpp
|
||||||
shade.cpp
|
shade.cpp
|
||||||
shell.cpp
|
shell.cpp
|
||||||
@ -441,7 +444,7 @@ target_link_libraries(app-lib
|
|||||||
net-lib
|
net-lib
|
||||||
pen-lib
|
pen-lib
|
||||||
render-lib
|
render-lib
|
||||||
scripting-lib
|
script-lib
|
||||||
she
|
she
|
||||||
ui-lib
|
ui-lib
|
||||||
undo-lib
|
undo-lib
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
#include "app/recent_files.h"
|
#include "app/recent_files.h"
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
#include "app/scripting/app_scripting.h"
|
#include "app/script/app_scripting.h"
|
||||||
#include "app/send_crash.h"
|
#include "app/send_crash.h"
|
||||||
#include "app/shell.h"
|
#include "app/shell.h"
|
||||||
#include "app/tools/tool_box.h"
|
#include "app/tools/tool_box.h"
|
||||||
@ -69,7 +69,7 @@
|
|||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
#include "pen/pen.h"
|
#include "pen/pen.h"
|
||||||
#include "render/render.h"
|
#include "render/render.h"
|
||||||
#include "scripting/engine_delegate.h"
|
#include "script/engine_delegate.h"
|
||||||
#include "she/display.h"
|
#include "she/display.h"
|
||||||
#include "she/error.h"
|
#include "she/error.h"
|
||||||
#include "she/system.h"
|
#include "she/system.h"
|
||||||
@ -138,7 +138,7 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StdoutEngineDelegate : public scripting::EngineDelegate {
|
class StdoutEngineDelegate : public script::EngineDelegate {
|
||||||
public:
|
public:
|
||||||
void onConsolePrint(const char* text) override {
|
void onConsolePrint(const char* text) override {
|
||||||
printf("%s\n", text);
|
printf("%s\n", text);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -13,16 +13,16 @@
|
|||||||
#include "app/commands/params.h"
|
#include "app/commands/params.h"
|
||||||
#include "app/console.h"
|
#include "app/console.h"
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
#include "app/scripting/app_scripting.h"
|
#include "app/script/app_scripting.h"
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
#include "scripting/engine_delegate.h"
|
#include "script/engine_delegate.h"
|
||||||
#include "ui/manager.h"
|
#include "ui/manager.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
class ConsoleEngineDelegate : public scripting::EngineDelegate {
|
class ConsoleEngineDelegate : public script::EngineDelegate {
|
||||||
public:
|
public:
|
||||||
void onConsolePrint(const char* text) override {
|
void onConsolePrint(const char* text) override {
|
||||||
m_console.printf("%s\n", text);
|
m_console.printf("%s\n", text);
|
||||||
|
73
src/app/script/app_object.cpp
Normal file
73
src/app/script/app_object.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2015-2016 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.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/script/console_object.h"
|
||||||
|
|
||||||
|
#include "app/script/sprite_class.h"
|
||||||
|
#include "app/ui_context.h"
|
||||||
|
#include "script/engine.h"
|
||||||
|
|
||||||
|
// App sub-objects
|
||||||
|
#include "app/script/pixel_color.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
script::result_t App_get_activeSprite(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
app::Document* doc = UIContext::instance()->activeDocument();
|
||||||
|
if (doc)
|
||||||
|
ctx.pushObject(wrap_sprite(doc), "Sprite");
|
||||||
|
else
|
||||||
|
ctx.pushNull();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t App_get_pixelColor(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushObject();
|
||||||
|
ctx.registerFuncs(-1, pixelColor_methods);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t App_get_version(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushString(VERSION);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const script::FunctionEntry App_methods[] = {
|
||||||
|
{ nullptr, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const script::PropertyEntry App_props[] = {
|
||||||
|
{ "activeSprite", App_get_activeSprite, nullptr },
|
||||||
|
{ "pixelColor", App_get_pixelColor, nullptr },
|
||||||
|
{ "version", App_get_version, nullptr },
|
||||||
|
{ nullptr, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
void register_app_object(script::Context& ctx)
|
||||||
|
{
|
||||||
|
ctx.pushGlobalObject();
|
||||||
|
ctx.registerObject(-1, "app", App_methods, App_props);
|
||||||
|
ctx.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
22
src/app/script/app_object.h
Normal file
22
src/app/script/app_object.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2015-2016 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.
|
||||||
|
|
||||||
|
#ifndef APP_SCRIPT_APP_OBJECT_H_INCLUDED
|
||||||
|
#define APP_SCRIPT_APP_OBJECT_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace script {
|
||||||
|
class Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
void register_app_object(script::Context& ctx);
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
32
src/app/script/app_scripting.cpp
Normal file
32
src/app/script/app_scripting.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2001-2016 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.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/script/app_scripting.h"
|
||||||
|
|
||||||
|
#include "app/script/app_object.h"
|
||||||
|
#include "app/script/console_object.h"
|
||||||
|
#include "app/script/sprite_class.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
AppScripting::AppScripting(script::EngineDelegate* delegate)
|
||||||
|
: script::Engine(delegate)
|
||||||
|
{
|
||||||
|
auto& ctx = context();
|
||||||
|
register_app_object(ctx);
|
||||||
|
register_console_object(ctx);
|
||||||
|
|
||||||
|
ctx.pushGlobalObject();
|
||||||
|
register_sprite_class(-1, ctx);
|
||||||
|
ctx.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,22 +1,21 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
// published by the Free Software Foundation.
|
// published by the Free Software Foundation.
|
||||||
|
|
||||||
#ifndef APP_SCRIPTING_H_INCLUDED
|
#ifndef APP_SCRIPT_H_INCLUDED
|
||||||
#define APP_SCRIPTING_H_INCLUDED
|
#define APP_SCRIPT_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "scripting/engine.h"
|
#include "script/engine.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
class Document;
|
|
||||||
|
|
||||||
class AppScripting : public scripting::Engine {
|
class AppScripting : public script::Engine {
|
||||||
public:
|
public:
|
||||||
AppScripting(scripting::EngineDelegate* delegate);
|
AppScripting(script::EngineDelegate* delegate);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
65
src/app/script/console_object.cpp
Normal file
65
src/app/script/console_object.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2001-2016 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.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/script/console_object.h"
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "app/console.h"
|
||||||
|
#include "script/engine.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void print(const char* str)
|
||||||
|
{
|
||||||
|
if (str) {
|
||||||
|
std::cout << str << std::endl; // New line + flush
|
||||||
|
|
||||||
|
if (App::instance()->isGui()) {
|
||||||
|
Console().printf("%s\n", str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Console_assert(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
if (!ctx.toBool(0))
|
||||||
|
print(ctx.toString(1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Console_log(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
print(ctx.toString(0));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const script::FunctionEntry Console_methods[] = {
|
||||||
|
{ "assert", Console_assert, 2 },
|
||||||
|
{ "log", Console_log, 1 },
|
||||||
|
{ nullptr, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
void register_console_object(script::Context& ctx)
|
||||||
|
{
|
||||||
|
ctx.pushGlobalObject();
|
||||||
|
ctx.registerObject(-1, "console", Console_methods, nullptr);
|
||||||
|
ctx.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
22
src/app/script/console_object.h
Normal file
22
src/app/script/console_object.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2016 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.
|
||||||
|
|
||||||
|
#ifndef APP_SCRIPT_CONSOLE_OBJECT_H_INCLUDED
|
||||||
|
#define APP_SCRIPT_CONSOLE_OBJECT_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace script {
|
||||||
|
class Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
void register_console_object(script::Context& ctx);
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
86
src/app/script/pixel_color.h
Normal file
86
src/app/script/pixel_color.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2016 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 "doc/color.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
script::result_t pixelColor_rgba(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int r = ctx.requireInt(0);
|
||||||
|
int g = ctx.requireInt(1);
|
||||||
|
int b = ctx.requireInt(2);
|
||||||
|
int a = (ctx.isUndefined(3) ? 255: ctx.requireInt(3));
|
||||||
|
ctx.pushUInt(doc::rgba(r, g, b, a));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_rgbaR(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushUInt(doc::rgba_getr(ctx.requireUInt(0)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_rgbaG(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushUInt(doc::rgba_getg(ctx.requireUInt(0)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_rgbaB(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushUInt(doc::rgba_getb(ctx.requireUInt(0)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_rgbaA(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushUInt(doc::rgba_geta(ctx.requireUInt(0)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_graya(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int v = ctx.requireInt(0);
|
||||||
|
int a = (ctx.isUndefined(1) ? 255: ctx.requireInt(1));
|
||||||
|
ctx.pushUInt(doc::graya(v, a));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_grayaV(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushUInt(doc::graya_getv(ctx.requireUInt(0)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t pixelColor_grayaA(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
ctx.pushUInt(doc::graya_geta(ctx.requireUInt(0)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const script::FunctionEntry pixelColor_methods[] = {
|
||||||
|
{ "rgba", pixelColor_rgba, 4 },
|
||||||
|
{ "rgbaR", pixelColor_rgbaR, 1 },
|
||||||
|
{ "rgbaG", pixelColor_rgbaG, 1 },
|
||||||
|
{ "rgbaB", pixelColor_rgbaB, 1 },
|
||||||
|
{ "rgbaA", pixelColor_rgbaA, 1 },
|
||||||
|
{ "graya", pixelColor_graya, 2 },
|
||||||
|
{ "grayaV", pixelColor_grayaV, 1 },
|
||||||
|
{ "grayaA", pixelColor_grayaA, 1 },
|
||||||
|
{ nullptr, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
227
src/app/script/sprite_class.cpp
Normal file
227
src/app/script/sprite_class.cpp
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2015-2016 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.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/script/sprite_class.h"
|
||||||
|
|
||||||
|
#include "app/document.h"
|
||||||
|
#include "app/document_api.h"
|
||||||
|
#include "app/transaction.h"
|
||||||
|
#include "app/ui/document_view.h"
|
||||||
|
#include "app/ui_context.h"
|
||||||
|
#include "doc/site.h"
|
||||||
|
#include "doc/sprite.h"
|
||||||
|
#include "script/engine.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class SpriteInScript {
|
||||||
|
public:
|
||||||
|
SpriteInScript(app::Document* doc)
|
||||||
|
: m_doc(doc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~SpriteInScript() {
|
||||||
|
}
|
||||||
|
|
||||||
|
app::Document* document() {
|
||||||
|
return m_doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
app::Document* m_doc;
|
||||||
|
};
|
||||||
|
|
||||||
|
script::result_t Sprite_ctor(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
if (ctx.isConstructorCall()) {
|
||||||
|
int w = ctx.requireInt(0);
|
||||||
|
int h = ctx.requireInt(1);
|
||||||
|
int colorMode = (ctx.isUndefined(2) ? IMAGE_RGB: ctx.requireInt(2));
|
||||||
|
|
||||||
|
base::UniquePtr<Sprite> sprite(
|
||||||
|
Sprite::createBasicSprite((doc::PixelFormat)colorMode, w, h, 256));
|
||||||
|
base::UniquePtr<Document> doc(new Document(sprite));
|
||||||
|
sprite.release();
|
||||||
|
|
||||||
|
doc->setContext(UIContext::instance());
|
||||||
|
ctx.pushThis(wrap_sprite(doc.release()));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_putPixel(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int x = ctx.requireInt(0);
|
||||||
|
int y = ctx.requireInt(1);
|
||||||
|
doc::color_t color = ctx.requireUInt(2);
|
||||||
|
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
DocumentView* docView = UIContext::instance()->getFirstDocumentView(doc);
|
||||||
|
if (!docView)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
doc::Site site;
|
||||||
|
docView->getSite(&site);
|
||||||
|
|
||||||
|
int celX, celY;
|
||||||
|
doc::Image* image = site.image(&celX, &celY, nullptr);
|
||||||
|
if (image)
|
||||||
|
image->putPixel(x-celX, y-celY, color);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_getPixel(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int x = ctx.requireInt(0);
|
||||||
|
int y = ctx.requireInt(1);
|
||||||
|
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
DocumentView* docView = UIContext::instance()->getFirstDocumentView(doc);
|
||||||
|
if (!docView)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
doc::Site site;
|
||||||
|
docView->getSite(&site);
|
||||||
|
|
||||||
|
int celX, celY;
|
||||||
|
doc::Image* image = site.image(&celX, &celY, nullptr);
|
||||||
|
if (image) {
|
||||||
|
doc::color_t color = image->getPixel(x-celX, y-celY);
|
||||||
|
ctx.pushUInt(color);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_resize(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int w = ctx.requireInt(0);
|
||||||
|
int h = ctx.requireInt(1);
|
||||||
|
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
{
|
||||||
|
Transaction transaction(UIContext::instance(), "Script Execution", ModifyDocument);
|
||||||
|
DocumentApi api(doc, transaction);
|
||||||
|
api.setSpriteSize(doc->sprite(), w, h);
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_crop(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int x = ctx.requireInt(0);
|
||||||
|
int y = ctx.requireInt(1);
|
||||||
|
int w = ctx.requireInt(2);
|
||||||
|
int h = ctx.requireInt(3);
|
||||||
|
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
{
|
||||||
|
Transaction transaction(UIContext::instance(), "Script Execution", ModifyDocument);
|
||||||
|
DocumentApi api(doc, transaction);
|
||||||
|
api.cropSprite(doc->sprite(), gfx::Rect(x, y, w, h));
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_get_width(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
ctx.pushInt(doc->sprite()->width());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_set_width(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int w = ctx.requireInt(0);
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
doc->sprite()->setSize(w, doc->sprite()->height());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_get_height(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
ctx.pushInt(doc->sprite()->height());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
script::result_t Sprite_set_height(script::ContextHandle handle)
|
||||||
|
{
|
||||||
|
script::Context ctx(handle);
|
||||||
|
int h = ctx.requireInt(0);
|
||||||
|
Document* doc = (Document*)unwrap_sprite(ctx.getThis());
|
||||||
|
doc->sprite()->setSize(doc->sprite()->width(), h);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const script::FunctionEntry Sprite_methods[] = {
|
||||||
|
{ "getPixel", Sprite_getPixel, 2 },
|
||||||
|
{ "putPixel", Sprite_putPixel, 3 },
|
||||||
|
{ "resize", Sprite_resize, 2 },
|
||||||
|
{ "crop", Sprite_crop, 4 },
|
||||||
|
{ nullptr, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const script::PropertyEntry Sprite_props[] = {
|
||||||
|
{ "width", Sprite_get_width, Sprite_set_width },
|
||||||
|
{ "height", Sprite_get_height, Sprite_set_height },
|
||||||
|
{ nullptr, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
static std::map<doc::ObjectId, SpriteInScript*> g_sprites;
|
||||||
|
|
||||||
|
void* wrap_sprite(app::Document* doc)
|
||||||
|
{
|
||||||
|
auto it = g_sprites.find(doc->id());
|
||||||
|
if (it != g_sprites.end())
|
||||||
|
return it->second;
|
||||||
|
else {
|
||||||
|
SpriteInScript* wrap = new SpriteInScript(doc);
|
||||||
|
g_sprites[doc->id()] = wrap;
|
||||||
|
return wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app::Document* unwrap_sprite(void* ptr)
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
return ((SpriteInScript*)ptr)->document();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_sprite_class(script::index_t idx, script::Context& ctx)
|
||||||
|
{
|
||||||
|
ctx.registerClass(idx, "Sprite", Sprite_ctor, 3, Sprite_methods, Sprite_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
24
src/app/script/sprite_class.h
Normal file
24
src/app/script/sprite_class.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2015-2016 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.
|
||||||
|
|
||||||
|
#ifndef APP_SCRIPT_SPRITE_CLASS_H_INCLUDED
|
||||||
|
#define APP_SCRIPT_SPRITE_CLASS_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "script/engine.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
class Document;
|
||||||
|
|
||||||
|
void* wrap_sprite(app::Document* doc);
|
||||||
|
app::Document* unwrap_sprite(void* ptr);
|
||||||
|
|
||||||
|
void register_sprite_class(script::index_t idx, script::Context& ctx);
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
@ -1,40 +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.
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "app/scripting/app_scripting.h"
|
|
||||||
|
|
||||||
#include "app/document.h"
|
|
||||||
#include "app/document_api.h"
|
|
||||||
#include "app/transaction.h"
|
|
||||||
#include "app/ui/document_view.h"
|
|
||||||
#include "app/ui_context.h"
|
|
||||||
#include "doc/color.h"
|
|
||||||
#include "doc/image.h"
|
|
||||||
#include "doc/site.h"
|
|
||||||
|
|
||||||
namespace app {
|
|
||||||
|
|
||||||
#include "app/scripting/raw_color.h"
|
|
||||||
#include "app/scripting/sprite.h"
|
|
||||||
|
|
||||||
AppScripting::AppScripting(scripting::EngineDelegate* delegate)
|
|
||||||
: scripting::Engine(delegate)
|
|
||||||
{
|
|
||||||
registerFunction("rgba", rgba, 4);
|
|
||||||
registerFunction("rgbaR", rgbaR, 1);
|
|
||||||
registerFunction("rgbaG", rgbaG, 1);
|
|
||||||
registerFunction("rgbaB", rgbaB, 1);
|
|
||||||
registerFunction("rgbaA", rgbaA, 1);
|
|
||||||
registerClass("Sprite", Sprite_ctor, 3, Sprite_methods, Sprite_props);
|
|
||||||
registerGlobal("activeSprite", activeSprite_getter, activeSprite_setter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,49 +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.
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
scripting::result_t rgba(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
int r = ctx.requireInt(0);
|
|
||||||
int g = ctx.requireInt(1);
|
|
||||||
int b = ctx.requireInt(2);
|
|
||||||
int a = (ctx.isUndefined(3) ? 255: ctx.requireInt(3));
|
|
||||||
ctx.pushUInt(doc::rgba(r, g, b, a));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t rgbaR(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
ctx.pushUInt(doc::rgba_getr(ctx.requireUInt(0)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t rgbaG(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
ctx.pushUInt(doc::rgba_getg(ctx.requireUInt(0)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t rgbaB(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
ctx.pushUInt(doc::rgba_getb(ctx.requireUInt(0)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t rgbaA(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
ctx.pushUInt(doc::rgba_geta(ctx.requireUInt(0)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
@ -1,143 +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.
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
scripting::result_t Sprite_ctor(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
if (ctx.isConstructorCall()) {
|
|
||||||
int w = ctx.requireInt(0);
|
|
||||||
int h = ctx.requireInt(1);
|
|
||||||
int colorMode = (ctx.isUndefined(2) ? IMAGE_RGB: ctx.requireInt(2));
|
|
||||||
|
|
||||||
base::UniquePtr<Sprite> sprite(
|
|
||||||
Sprite::createBasicSprite((doc::PixelFormat)colorMode, w, h, 256));
|
|
||||||
base::UniquePtr<Document> doc(new Document(sprite));
|
|
||||||
sprite.release();
|
|
||||||
|
|
||||||
doc->setContext(UIContext::instance());
|
|
||||||
ctx.pushThis(doc.release());
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t Sprite_putPixel(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
int x = ctx.requireInt(0);
|
|
||||||
int y = ctx.requireInt(1);
|
|
||||||
doc::color_t color = ctx.requireUInt(2);
|
|
||||||
|
|
||||||
Document* doc = (Document*)ctx.getThis();
|
|
||||||
DocumentView* docView = UIContext::instance()->getFirstDocumentView(doc);
|
|
||||||
if (!docView)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
doc::Site site;
|
|
||||||
docView->getSite(&site);
|
|
||||||
|
|
||||||
int celX, celY;
|
|
||||||
doc::Image* image = site.image(&celX, &celY, nullptr);
|
|
||||||
if (image)
|
|
||||||
image->putPixel(x-celX, y-celY, color);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t Sprite_getPixel(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
int x = ctx.requireInt(0);
|
|
||||||
int y = ctx.requireInt(1);
|
|
||||||
|
|
||||||
Document* doc = (Document*)ctx.getThis();
|
|
||||||
DocumentView* docView = UIContext::instance()->getFirstDocumentView(doc);
|
|
||||||
if (!docView)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
doc::Site site;
|
|
||||||
docView->getSite(&site);
|
|
||||||
|
|
||||||
int celX, celY;
|
|
||||||
doc::Image* image = site.image(&celX, &celY, nullptr);
|
|
||||||
if (image) {
|
|
||||||
doc::color_t color = image->getPixel(x-celX, y-celY);
|
|
||||||
ctx.pushUInt(color);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t Sprite_resize(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
int w = ctx.requireInt(0);
|
|
||||||
int h = ctx.requireInt(1);
|
|
||||||
|
|
||||||
Document* doc = (Document*)ctx.getThis();
|
|
||||||
{
|
|
||||||
Transaction transaction(UIContext::instance(), "Script Execution", ModifyDocument);
|
|
||||||
DocumentApi api(doc, transaction);
|
|
||||||
api.setSpriteSize(doc->sprite(), w, h);
|
|
||||||
transaction.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t Sprite_get_width(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
Document* doc = (Document*)ctx.getThis();
|
|
||||||
ctx.pushInt(doc->sprite()->width());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t Sprite_get_height(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
Document* doc = (Document*)ctx.getThis();
|
|
||||||
ctx.pushInt(doc->sprite()->height());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t activeSprite_getter(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
app::Document* doc = UIContext::instance()->activeDocument();
|
|
||||||
if (doc)
|
|
||||||
ctx.pushObject(doc, "Sprite");
|
|
||||||
else
|
|
||||||
ctx.pushNull();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scripting::result_t activeSprite_setter(scripting::ContextHandle handle)
|
|
||||||
{
|
|
||||||
scripting::Context ctx(handle);
|
|
||||||
Document* doc = (Document*)ctx.requireObject(0, "Sprite");
|
|
||||||
if (doc)
|
|
||||||
UIContext::instance()->setActiveDocument(doc);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scripting::FunctionEntry Sprite_methods[] = {
|
|
||||||
{ "putPixel", Sprite_putPixel, 3 },
|
|
||||||
{ "getPixel", Sprite_getPixel, 2 },
|
|
||||||
{ "resize", Sprite_resize, 2 },
|
|
||||||
{ nullptr, nullptr, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
const scripting::PropertyEntry Sprite_props[] = {
|
|
||||||
{ "width", Sprite_get_width, nullptr },
|
|
||||||
{ "height", Sprite_get_height, nullptr },
|
|
||||||
{ nullptr, nullptr, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "app/shell.h"
|
#include "app/shell.h"
|
||||||
|
|
||||||
#include "scripting/engine.h"
|
#include "script/engine.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -26,7 +26,7 @@ Shell::~Shell()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::run(scripting::Engine& engine)
|
void Shell::run(script::Engine& engine)
|
||||||
{
|
{
|
||||||
std::cout << "Welcome to " PACKAGE " v" VERSION " interactive console" << std::endl;
|
std::cout << "Welcome to " PACKAGE " v" VERSION " interactive console" << std::endl;
|
||||||
std::string line;
|
std::string line;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -9,7 +9,7 @@
|
|||||||
#define APP_SHELL_H_INCLUDED
|
#define APP_SHELL_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace scripting {
|
namespace script {
|
||||||
class Engine;
|
class Engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ namespace app {
|
|||||||
Shell();
|
Shell();
|
||||||
~Shell();
|
~Shell();
|
||||||
|
|
||||||
void run(scripting::Engine& engine);
|
void run(script::Engine& engine);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -9,10 +9,10 @@
|
|||||||
#define APP_UI_DEVCONSOLE_VIEW_H_INCLUDED
|
#define APP_UI_DEVCONSOLE_VIEW_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "app/scripting/app_scripting.h"
|
#include "app/script/app_scripting.h"
|
||||||
#include "app/ui/tabs.h"
|
#include "app/ui/tabs.h"
|
||||||
#include "app/ui/workspace_view.h"
|
#include "app/ui/workspace_view.h"
|
||||||
#include "scripting/engine_delegate.h"
|
#include "script/engine_delegate.h"
|
||||||
#include "ui/box.h"
|
#include "ui/box.h"
|
||||||
#include "ui/label.h"
|
#include "ui/label.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
@ -22,7 +22,7 @@ namespace app {
|
|||||||
class DevConsoleView : public ui::Box
|
class DevConsoleView : public ui::Box
|
||||||
, public TabView
|
, public TabView
|
||||||
, public WorkspaceView
|
, public WorkspaceView
|
||||||
, public scripting::EngineDelegate {
|
, public script::EngineDelegate {
|
||||||
public:
|
public:
|
||||||
DevConsoleView();
|
DevConsoleView();
|
||||||
~DevConsoleView();
|
~DevConsoleView();
|
||||||
|
9
src/script/CMakeLists.txt
Normal file
9
src/script/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Aseprite Scripting Library
|
||||||
|
# Copyright (C) 2015-2016 David Capello
|
||||||
|
|
||||||
|
include_directories(${DUKTAPE_DIR})
|
||||||
|
|
||||||
|
add_library(duktape ${DUKTAPE_DIR}/duktape.c)
|
||||||
|
add_library(script-lib engine.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(script-lib duktape)
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2015 David Capello
|
Copyright (c) 2015-2016 David Capello
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
@ -1,4 +1,4 @@
|
|||||||
# Aseprite Scripting Library
|
# Aseprite Scripting Library
|
||||||
*Copyright (C) 2015 David Capello*
|
*Copyright (C) 2015-2016 David Capello*
|
||||||
|
|
||||||
> Distributed under [MIT license](LICENSE.txt)
|
> Distributed under [MIT license](LICENSE.txt)
|
507
src/script/engine.cpp
Normal file
507
src/script/engine.cpp
Normal file
@ -0,0 +1,507 @@
|
|||||||
|
// Aseprite Scripting Library
|
||||||
|
// Copyright (c) 2015-2016 David Capello
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "script/engine.h"
|
||||||
|
|
||||||
|
#include "base/convert_to.h"
|
||||||
|
#include "base/exception.h"
|
||||||
|
#include "base/file_handle.h"
|
||||||
|
#include "base/memory.h"
|
||||||
|
#include "script/engine_delegate.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <duktape.h>
|
||||||
|
|
||||||
|
class ScriptEngineException : public base::Exception {
|
||||||
|
public:
|
||||||
|
ScriptEngineException(duk_errcode_t code, const char* msg)
|
||||||
|
: Exception(std::string(msg) + " (code " + base::convert_to<std::string>(code) + ")") {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// TODO classes in modules isn't supported yet
|
||||||
|
std::map<std::string, Module*> g_modules;
|
||||||
|
|
||||||
|
void* on_alloc_function(void* udata, duk_size_t size)
|
||||||
|
{
|
||||||
|
if (size)
|
||||||
|
return base_malloc(size);
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* on_realloc_function(void* udata, void* ptr, duk_size_t size)
|
||||||
|
{
|
||||||
|
if (!ptr) {
|
||||||
|
if (size)
|
||||||
|
return base_malloc(size);
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else if (!size) {
|
||||||
|
base_free(ptr);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return base_realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_free_function(void* udata, void* ptr)
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
base_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
duk_ret_t on_search_module(duk_context* ctx)
|
||||||
|
{
|
||||||
|
const char* id = duk_get_string(ctx, 0);
|
||||||
|
if (!id)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto it = g_modules.find(id);
|
||||||
|
if (it == g_modules.end()) {
|
||||||
|
// TODO error module not found
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Module* module = it->second;
|
||||||
|
Context ctxWrapper(ctx);
|
||||||
|
if (module->registerModule(ctxWrapper) > 0) {
|
||||||
|
// Overwrite the 'exports' property of the module (arg 3)
|
||||||
|
// with the object returned by registerModule()
|
||||||
|
duk_put_prop_string(ctx, 3, "exports");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 means no source code
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_fatal_handler(duk_context* ctx, duk_errcode_t code, const char* msg)
|
||||||
|
{
|
||||||
|
throw ScriptEngineException(code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::dump()
|
||||||
|
{
|
||||||
|
duk_push_context_dump(m_handle);
|
||||||
|
std::cout << duk_to_string(m_handle, -1) << std::endl;
|
||||||
|
duk_pop(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pop()
|
||||||
|
{
|
||||||
|
duk_pop(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::remove(index_t idx)
|
||||||
|
{
|
||||||
|
duk_remove(m_handle, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::duplicateTop()
|
||||||
|
{
|
||||||
|
duk_dup_top(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isConstructorCall()
|
||||||
|
{
|
||||||
|
return (duk_is_constructor_call(m_handle) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isUndefined(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_undefined(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isNull(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_null(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isNullOrUndefined(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_null_or_undefined(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isBool(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_boolean(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isNumber(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_number(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isNaN(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_nan(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::isString(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_is_string(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::getBool(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_get_boolean(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::toBool(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_to_boolean(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Context::getNumber(index_t i)
|
||||||
|
{
|
||||||
|
return duk_get_number(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Context::getInt(index_t i)
|
||||||
|
{
|
||||||
|
return duk_get_int(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Context::getUInt(index_t i)
|
||||||
|
{
|
||||||
|
return duk_get_uint(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Context::getString(index_t i)
|
||||||
|
{
|
||||||
|
return duk_get_string(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Context::toString(index_t i)
|
||||||
|
{
|
||||||
|
return duk_to_string(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::requireBool(index_t i)
|
||||||
|
{
|
||||||
|
return (duk_require_boolean(m_handle, i) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Context::requireNumber(index_t i)
|
||||||
|
{
|
||||||
|
return duk_require_number(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Context::requireInt(index_t i)
|
||||||
|
{
|
||||||
|
return duk_require_int(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Context::requireUInt(index_t i)
|
||||||
|
{
|
||||||
|
return duk_require_uint(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Context::requireString(index_t i)
|
||||||
|
{
|
||||||
|
return duk_require_string(m_handle, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Context::requireObject(index_t i, const char* className)
|
||||||
|
{
|
||||||
|
duk_get_prop_string(m_handle, i, "\xFF" "\xFF" "ptr");
|
||||||
|
void* result = (void*)duk_to_pointer(m_handle, -1);
|
||||||
|
// TODO check pointer type
|
||||||
|
duk_pop(m_handle);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushUndefined()
|
||||||
|
{
|
||||||
|
duk_push_undefined(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushNull()
|
||||||
|
{
|
||||||
|
duk_push_null(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushBool(bool val)
|
||||||
|
{
|
||||||
|
duk_push_boolean(m_handle, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushNumber(double val)
|
||||||
|
{
|
||||||
|
duk_push_number(m_handle, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushNaN()
|
||||||
|
{
|
||||||
|
duk_push_nan(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushInt(int val)
|
||||||
|
{
|
||||||
|
duk_push_int(m_handle, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushUInt(unsigned int val)
|
||||||
|
{
|
||||||
|
duk_push_uint(m_handle, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushString(const char* str)
|
||||||
|
{
|
||||||
|
duk_push_string(m_handle, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushThis()
|
||||||
|
{
|
||||||
|
duk_push_this(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushThis(void* ptr)
|
||||||
|
{
|
||||||
|
duk_push_this(m_handle);
|
||||||
|
duk_push_pointer(m_handle, ptr);
|
||||||
|
duk_put_prop_string(m_handle, -2, "\xFF" "\xFF" "ptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
index_t Context::pushObject()
|
||||||
|
{
|
||||||
|
return duk_push_object(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
index_t Context::pushObject(void* ptr, const char* className)
|
||||||
|
{
|
||||||
|
index_t obj = duk_push_object(m_handle);
|
||||||
|
duk_push_pointer(m_handle, ptr);
|
||||||
|
duk_put_prop_string(m_handle, obj, "\xFF" "\xFF" "ptr");
|
||||||
|
|
||||||
|
// TODO classes in modules isn't supported yet
|
||||||
|
duk_get_global_string(m_handle, className);
|
||||||
|
duk_get_prototype(m_handle, -1);
|
||||||
|
duk_set_prototype(m_handle, obj);
|
||||||
|
duk_pop(m_handle);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushGlobalObject()
|
||||||
|
{
|
||||||
|
duk_push_global_object(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::registerProp(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
Function getter,
|
||||||
|
Function setter)
|
||||||
|
{
|
||||||
|
duk_push_string(m_handle, id);
|
||||||
|
if (idx < 0)
|
||||||
|
--idx;
|
||||||
|
|
||||||
|
duk_uint_t flags = 0;
|
||||||
|
|
||||||
|
if (getter) {
|
||||||
|
flags |= DUK_DEFPROP_HAVE_GETTER;
|
||||||
|
duk_push_c_function(m_handle, getter, 0);
|
||||||
|
if (idx < 0)
|
||||||
|
--idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setter) {
|
||||||
|
flags |= DUK_DEFPROP_HAVE_SETTER;
|
||||||
|
duk_push_c_function(m_handle, setter, 1);
|
||||||
|
if (idx < 0)
|
||||||
|
--idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
duk_def_prop(m_handle, idx, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::registerProps(index_t idx, const PropertyEntry* props)
|
||||||
|
{
|
||||||
|
for (int i=0; props[i].id; ++i) {
|
||||||
|
registerProp(idx,
|
||||||
|
props[i].id,
|
||||||
|
props[i].getter,
|
||||||
|
props[i].setter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::registerFunc(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
const Function func,
|
||||||
|
index_t nargs)
|
||||||
|
{
|
||||||
|
duk_push_c_function(m_handle, func, nargs);
|
||||||
|
duk_put_prop_string(m_handle, idx, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::registerFuncs(index_t idx, const FunctionEntry* methods)
|
||||||
|
{
|
||||||
|
duk_put_function_list(m_handle, idx, (const duk_function_list_entry*)methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::registerObject(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
const FunctionEntry* methods,
|
||||||
|
const PropertyEntry* props)
|
||||||
|
{
|
||||||
|
duk_push_object(m_handle);
|
||||||
|
if (idx < 0)
|
||||||
|
--idx;
|
||||||
|
|
||||||
|
if (methods)
|
||||||
|
registerFuncs(-1, methods);
|
||||||
|
if (props)
|
||||||
|
registerProps(-1, props);
|
||||||
|
|
||||||
|
duk_put_prop_string(m_handle, idx, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::registerClass(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
Function ctorFunc, int ctorNargs,
|
||||||
|
const FunctionEntry* methods,
|
||||||
|
const PropertyEntry* props)
|
||||||
|
{
|
||||||
|
ASSERT(ctorFunc);
|
||||||
|
duk_push_c_function(m_handle, ctorFunc, ctorNargs);
|
||||||
|
|
||||||
|
duk_push_object(m_handle); // Prototype object
|
||||||
|
if (methods)
|
||||||
|
duk_put_function_list(m_handle, -1, (const duk_function_list_entry*)methods);
|
||||||
|
if (props)
|
||||||
|
registerProps(-1, props);
|
||||||
|
|
||||||
|
duk_set_prototype(m_handle, -2);
|
||||||
|
duk_put_prop_string(m_handle, idx-1, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Context::getThis()
|
||||||
|
{
|
||||||
|
duk_push_this(m_handle);
|
||||||
|
duk_get_prop_string(m_handle, -1, "\xFF" "\xFF" "ptr");
|
||||||
|
void* result = (void*)duk_to_pointer(m_handle, -1);
|
||||||
|
duk_pop(m_handle);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::hasProp(index_t i, const char* propName)
|
||||||
|
{
|
||||||
|
return (duk_has_prop_string(m_handle, i, propName) ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::getProp(index_t i, const char* propName)
|
||||||
|
{
|
||||||
|
duk_get_prop_string(m_handle, i, propName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::setProp(index_t i, const char* propName)
|
||||||
|
{
|
||||||
|
duk_put_prop_string(m_handle, i, propName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine::Engine(EngineDelegate* delegate)
|
||||||
|
: m_ctx(duk_create_heap(&on_alloc_function,
|
||||||
|
&on_realloc_function,
|
||||||
|
&on_free_function,
|
||||||
|
(void*)this,
|
||||||
|
&on_fatal_handler))
|
||||||
|
, m_delegate(delegate)
|
||||||
|
{
|
||||||
|
// Set 'on_search_module' as the function to search modules with
|
||||||
|
// require('modulename') on JavaScript.
|
||||||
|
duk_get_global_string(m_ctx.handle(), "Duktape");
|
||||||
|
duk_push_c_function(m_ctx.handle(), &on_search_module, 4);
|
||||||
|
duk_put_prop_string(m_ctx.handle(), -2, "modSearch");
|
||||||
|
duk_pop(m_ctx.handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine::~Engine()
|
||||||
|
{
|
||||||
|
duk_destroy_heap(m_ctx.handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::eval(const std::string& jsCode)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ContextHandle handle = m_ctx.handle();
|
||||||
|
|
||||||
|
duk_eval_string(handle, jsCode.c_str());
|
||||||
|
|
||||||
|
if (!duk_is_null_or_undefined(handle, -1))
|
||||||
|
m_delegate->onConsolePrint(duk_safe_to_string(handle, -1));
|
||||||
|
|
||||||
|
duk_pop(handle);
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex) {
|
||||||
|
std::string err = "Error: ";
|
||||||
|
err += ex.what();
|
||||||
|
m_delegate->onConsolePrint(err.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::evalFile(const std::string& file)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ContextHandle handle = m_ctx.handle();
|
||||||
|
|
||||||
|
base::FileHandle fhandle(base::open_file(file, "rb"));
|
||||||
|
FILE* f = fhandle.get();
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fseek(f, 0, SEEK_END) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sz = ftell(f);
|
||||||
|
if (sz < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fseek(f, 0, SEEK_SET) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char* buf = (char*)duk_push_fixed_buffer(handle, sz);
|
||||||
|
ASSERT(buf != nullptr);
|
||||||
|
if (fread(buf, 1, sz, f) != sz)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
f = nullptr;
|
||||||
|
|
||||||
|
duk_push_string(handle, duk_to_string(handle, -1));
|
||||||
|
duk_eval_raw(handle, nullptr, 0, DUK_COMPILE_EVAL);
|
||||||
|
|
||||||
|
if (!duk_is_null_or_undefined(handle, -1))
|
||||||
|
m_delegate->onConsolePrint(duk_safe_to_string(handle, -1));
|
||||||
|
|
||||||
|
duk_pop(handle);
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex) {
|
||||||
|
std::string err = "Error: ";
|
||||||
|
err += ex.what();
|
||||||
|
m_delegate->onConsolePrint(err.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::registerModule(Module* module)
|
||||||
|
{
|
||||||
|
g_modules[module->id()] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace script
|
@ -1,22 +1,44 @@
|
|||||||
// Aseprite Scripting Library
|
// Aseprite Scripting Library
|
||||||
// Copyright (c) 2015 David Capello
|
// Copyright (c) 2015-2016 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
#ifndef SCRIPTING_ENGINE_H_INCLUDED
|
#ifndef SCRIPT_ENGINE_H_INCLUDED
|
||||||
#define SCRIPTING_ENGINE_H_INCLUDED
|
#define SCRIPT_ENGINE_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace scripting {
|
struct duk_hthread;
|
||||||
|
|
||||||
|
namespace script {
|
||||||
|
class Context;
|
||||||
class EngineDelegate;
|
class EngineDelegate;
|
||||||
|
|
||||||
typedef int result_t;
|
typedef int result_t;
|
||||||
typedef int index_t;
|
typedef int index_t;
|
||||||
|
typedef struct duk_hthread* ContextHandle;
|
||||||
|
typedef result_t (*Function)(ContextHandle ctx);
|
||||||
|
|
||||||
typedef void* ContextHandle;
|
struct FunctionEntry {
|
||||||
|
const char* id;
|
||||||
|
Function value;
|
||||||
|
index_t nargs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PropertyEntry {
|
||||||
|
const char* id;
|
||||||
|
Function getter;
|
||||||
|
Function setter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Module {
|
||||||
|
public:
|
||||||
|
virtual ~Module() { }
|
||||||
|
virtual const char* id() const = 0;
|
||||||
|
virtual int registerModule(Context& ctx) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
public:
|
public:
|
||||||
@ -24,6 +46,11 @@ namespace scripting {
|
|||||||
|
|
||||||
ContextHandle handle() { return m_handle; }
|
ContextHandle handle() { return m_handle; }
|
||||||
|
|
||||||
|
void dump();
|
||||||
|
void pop();
|
||||||
|
void remove(index_t idx);
|
||||||
|
void duplicateTop();
|
||||||
|
|
||||||
bool isConstructorCall();
|
bool isConstructorCall();
|
||||||
|
|
||||||
bool isUndefined(index_t i);
|
bool isUndefined(index_t i);
|
||||||
@ -35,12 +62,18 @@ namespace scripting {
|
|||||||
bool isString(index_t i);
|
bool isString(index_t i);
|
||||||
|
|
||||||
bool getBool(index_t i);
|
bool getBool(index_t i);
|
||||||
|
bool toBool(index_t i);
|
||||||
double getNumber(index_t i);
|
double getNumber(index_t i);
|
||||||
int getInt(index_t i);
|
int getInt(index_t i);
|
||||||
unsigned int getUInt(index_t i);
|
unsigned int getUInt(index_t i);
|
||||||
const char* getString(index_t i);
|
const char* getString(index_t i);
|
||||||
|
const char* toString(index_t i);
|
||||||
void* getThis();
|
void* getThis();
|
||||||
|
|
||||||
|
bool hasProp(index_t i, const char* propName);
|
||||||
|
void getProp(index_t i, const char* propName);
|
||||||
|
void setProp(index_t i, const char* propName);
|
||||||
|
|
||||||
bool requireBool(index_t i);
|
bool requireBool(index_t i);
|
||||||
double requireNumber(index_t i);
|
double requireNumber(index_t i);
|
||||||
int requireInt(index_t i);
|
int requireInt(index_t i);
|
||||||
@ -56,27 +89,38 @@ namespace scripting {
|
|||||||
void pushInt(int val);
|
void pushInt(int val);
|
||||||
void pushUInt(unsigned int val);
|
void pushUInt(unsigned int val);
|
||||||
void pushString(const char* str);
|
void pushString(const char* str);
|
||||||
|
void pushThis();
|
||||||
void pushThis(void* ptr);
|
void pushThis(void* ptr);
|
||||||
void pushObject(void* ptr, const char* className);
|
index_t pushObject();
|
||||||
|
index_t pushObject(void* ptr, const char* className);
|
||||||
|
void pushGlobalObject();
|
||||||
|
|
||||||
|
void registerProp(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
Function getter,
|
||||||
|
Function setter);
|
||||||
|
void registerProps(index_t idx,
|
||||||
|
const PropertyEntry* props);
|
||||||
|
void registerFunc(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
const Function func,
|
||||||
|
index_t nargs);
|
||||||
|
void registerFuncs(index_t idx,
|
||||||
|
const FunctionEntry* methods);
|
||||||
|
void registerObject(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
const FunctionEntry* methods,
|
||||||
|
const PropertyEntry* props);
|
||||||
|
void registerClass(index_t idx,
|
||||||
|
const char* id,
|
||||||
|
Function ctorFunc, int ctorNargs,
|
||||||
|
const FunctionEntry* methods,
|
||||||
|
const PropertyEntry* props);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ContextHandle m_handle;
|
ContextHandle m_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef result_t (*Function)(ContextHandle ctx);
|
|
||||||
|
|
||||||
struct FunctionEntry {
|
|
||||||
const char* key;
|
|
||||||
Function value;
|
|
||||||
index_t nargs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PropertyEntry {
|
|
||||||
const char* key;
|
|
||||||
Function getter;
|
|
||||||
Function setter;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
public:
|
public:
|
||||||
Engine(EngineDelegate* delegate);
|
Engine(EngineDelegate* delegate);
|
||||||
@ -85,13 +129,9 @@ namespace scripting {
|
|||||||
void eval(const std::string& jsCode);
|
void eval(const std::string& jsCode);
|
||||||
void evalFile(const std::string& file);
|
void evalFile(const std::string& file);
|
||||||
|
|
||||||
void registerFunction(const char* id, Function function, int nargs);
|
Context& context() { return m_ctx; }
|
||||||
void registerClass(const char* id,
|
|
||||||
Function ctorFunc, int ctorNargs,
|
void registerModule(Module* module);
|
||||||
const FunctionEntry* methods,
|
|
||||||
const PropertyEntry* props);
|
|
||||||
void registerGlobal(const char* id,
|
|
||||||
Function getter, Function setter);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Context m_ctx;
|
Context m_ctx;
|
@ -1,14 +1,14 @@
|
|||||||
// Aseprite Scripting Library
|
// Aseprite Scripting Library
|
||||||
// Copyright (c) 2015 David Capello
|
// Copyright (c) 2015-2016 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
#ifndef SCRIPTING_ENGINE_DELEGATE_H_INCLUDED
|
#ifndef SCRIPT_ENGINE_DELEGATE_H_INCLUDED
|
||||||
#define SCRIPTING_ENGINE_DELEGATE_H_INCLUDED
|
#define SCRIPT_ENGINE_DELEGATE_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace scripting {
|
namespace script {
|
||||||
|
|
||||||
class EngineDelegate {
|
class EngineDelegate {
|
||||||
public:
|
public:
|
@ -1,7 +0,0 @@
|
|||||||
# Aseprite Scripting Library
|
|
||||||
# Copyright (C) 2015 David Capello
|
|
||||||
|
|
||||||
include_directories(${DUKTAPE_DIR})
|
|
||||||
|
|
||||||
add_library(scripting-lib
|
|
||||||
engine.cpp)
|
|
@ -1,356 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "scripting/engine.h"
|
|
||||||
|
|
||||||
#include "base/convert_to.h"
|
|
||||||
#include "base/exception.h"
|
|
||||||
#include "base/file_handle.h"
|
|
||||||
#include "base/memory.h"
|
|
||||||
#include "scripting/engine_delegate.h"
|
|
||||||
|
|
||||||
#define DUK_OPT_PANIC_HANDLER scripting_engine_panic_handler
|
|
||||||
#include <duktape.h>
|
|
||||||
|
|
||||||
class ScriptingEngineException : public base::Exception {
|
|
||||||
public:
|
|
||||||
ScriptingEngineException(duk_errcode_t code, const char* msg)
|
|
||||||
: Exception(std::string(msg) + " (code " + base::convert_to<std::string>(code) + ")") {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void scripting_engine_panic_handler(duk_errcode_t code, const char* msg)
|
|
||||||
{
|
|
||||||
throw ScriptingEngineException(code, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <duktape.c>
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace scripting {
|
|
||||||
|
|
||||||
bool Context::isConstructorCall()
|
|
||||||
{
|
|
||||||
return (duk_is_constructor_call(m_handle) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isUndefined(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_undefined(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isNull(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_null(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isNullOrUndefined(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_null_or_undefined(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isBool(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_boolean(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isNumber(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_number(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isNaN(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_nan(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::isString(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_is_string(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::getBool(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_get_boolean(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Context::getNumber(index_t i)
|
|
||||||
{
|
|
||||||
return duk_get_number(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Context::getInt(index_t i)
|
|
||||||
{
|
|
||||||
return duk_get_int(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Context::getUInt(index_t i)
|
|
||||||
{
|
|
||||||
return duk_get_uint(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Context::getString(index_t i)
|
|
||||||
{
|
|
||||||
return duk_get_string(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Context::requireBool(index_t i)
|
|
||||||
{
|
|
||||||
return (duk_require_boolean(m_handle, i) ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Context::requireNumber(index_t i)
|
|
||||||
{
|
|
||||||
return duk_require_number(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Context::requireInt(index_t i)
|
|
||||||
{
|
|
||||||
return duk_require_int(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Context::requireUInt(index_t i)
|
|
||||||
{
|
|
||||||
return duk_require_uint(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Context::requireString(index_t i)
|
|
||||||
{
|
|
||||||
return duk_require_string(m_handle, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* Context::requireObject(index_t i, const char* className)
|
|
||||||
{
|
|
||||||
duk_get_prop_string(m_handle, i, "\xFF" "\xFF" "ptr");
|
|
||||||
void* result = (void*)duk_to_pointer(m_handle, -1);
|
|
||||||
// TODO check pointer type
|
|
||||||
duk_pop(m_handle);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushUndefined()
|
|
||||||
{
|
|
||||||
duk_push_undefined(m_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushNull()
|
|
||||||
{
|
|
||||||
duk_push_null(m_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushBool(bool val)
|
|
||||||
{
|
|
||||||
duk_push_boolean(m_handle, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushNumber(double val)
|
|
||||||
{
|
|
||||||
duk_push_number(m_handle, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushNaN()
|
|
||||||
{
|
|
||||||
duk_push_nan(m_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushInt(int val)
|
|
||||||
{
|
|
||||||
duk_push_int(m_handle, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushUInt(unsigned int val)
|
|
||||||
{
|
|
||||||
duk_push_uint(m_handle, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushString(const char* str)
|
|
||||||
{
|
|
||||||
duk_push_string(m_handle, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushThis(void* ptr)
|
|
||||||
{
|
|
||||||
duk_push_this(m_handle);
|
|
||||||
duk_push_pointer(m_handle, ptr);
|
|
||||||
duk_put_prop_string(m_handle, -2, "\xFF" "\xFF" "ptr");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::pushObject(void* ptr, const char* className)
|
|
||||||
{
|
|
||||||
duk_push_object(m_handle);
|
|
||||||
duk_push_pointer(m_handle, ptr);
|
|
||||||
duk_put_prop_string(m_handle, -2, "\xFF" "\xFF" "ptr");
|
|
||||||
|
|
||||||
duk_get_global_string(m_handle, className);
|
|
||||||
duk_get_prop_string(m_handle, -1, "prototype");
|
|
||||||
duk_set_prototype(m_handle, -3);
|
|
||||||
duk_pop(m_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* Context::getThis()
|
|
||||||
{
|
|
||||||
duk_push_this(m_handle);
|
|
||||||
duk_get_prop_string(m_handle, -1, "\xFF" "\xFF" "ptr");
|
|
||||||
void* result = (void*)duk_to_pointer(m_handle, -1);
|
|
||||||
duk_pop(m_handle);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine::Engine(EngineDelegate* delegate)
|
|
||||||
: m_ctx(duk_create_heap_default())
|
|
||||||
, m_delegate(delegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine::~Engine()
|
|
||||||
{
|
|
||||||
duk_destroy_heap(m_ctx.handle());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::eval(const std::string& jsCode)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
ContextHandle handle = m_ctx.handle();
|
|
||||||
|
|
||||||
duk_eval_string(handle, jsCode.c_str());
|
|
||||||
|
|
||||||
if (!duk_is_null_or_undefined(handle, -1))
|
|
||||||
m_delegate->onConsolePrint(duk_safe_to_string(handle, -1));
|
|
||||||
|
|
||||||
duk_pop(handle);
|
|
||||||
}
|
|
||||||
catch (const std::exception& ex) {
|
|
||||||
std::string err = "Error: ";
|
|
||||||
err += ex.what();
|
|
||||||
m_delegate->onConsolePrint(err.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::evalFile(const std::string& file)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
ContextHandle handle = m_ctx.handle();
|
|
||||||
|
|
||||||
base::FileHandle fhandle(base::open_file(file, "rb"));
|
|
||||||
FILE* f = fhandle.get();
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fseek(f, 0, SEEK_END) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int sz = ftell(f);
|
|
||||||
if (sz < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fseek(f, 0, SEEK_SET) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char* buf = (char*)duk_push_fixed_buffer(handle, sz);
|
|
||||||
ASSERT(buf != nullptr);
|
|
||||||
if (fread(buf, 1, sz, f) != sz)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
f = nullptr;
|
|
||||||
|
|
||||||
duk_push_string(handle, duk_to_string(handle, -1));
|
|
||||||
duk_eval_raw(handle, nullptr, 0, DUK_COMPILE_EVAL);
|
|
||||||
|
|
||||||
if (!duk_is_null_or_undefined(handle, -1))
|
|
||||||
m_delegate->onConsolePrint(duk_safe_to_string(handle, -1));
|
|
||||||
|
|
||||||
duk_pop(handle);
|
|
||||||
}
|
|
||||||
catch (const std::exception& ex) {
|
|
||||||
std::string err = "Error: ";
|
|
||||||
err += ex.what();
|
|
||||||
m_delegate->onConsolePrint(err.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::registerFunction(const char* id, Function function, int nargs)
|
|
||||||
{
|
|
||||||
ContextHandle handle = m_ctx.handle();
|
|
||||||
|
|
||||||
duk_push_global_object(handle);
|
|
||||||
duk_push_c_function(handle, function, nargs);
|
|
||||||
duk_put_prop_string(handle, -2, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::registerClass(const char* id,
|
|
||||||
Function ctorFunc, int ctorNargs,
|
|
||||||
const FunctionEntry* methods,
|
|
||||||
const PropertyEntry* props)
|
|
||||||
{
|
|
||||||
ContextHandle handle = m_ctx.handle();
|
|
||||||
duk_push_c_function(handle, ctorFunc, ctorNargs);
|
|
||||||
|
|
||||||
duk_push_object(handle);
|
|
||||||
|
|
||||||
if (methods)
|
|
||||||
duk_put_function_list(handle, -1, (const duk_function_list_entry*)methods);
|
|
||||||
|
|
||||||
if (props) {
|
|
||||||
for (int i=0; props[i].key; ++i) {
|
|
||||||
duk_push_string(handle, props[i].key);
|
|
||||||
|
|
||||||
duk_idx_t objidx = -2;
|
|
||||||
duk_uint_t flags = 0;
|
|
||||||
|
|
||||||
if (props[i].getter) {
|
|
||||||
flags |= DUK_DEFPROP_HAVE_GETTER;
|
|
||||||
duk_push_c_function(handle, props[i].getter, 0);
|
|
||||||
--objidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props[i].setter) {
|
|
||||||
flags |= DUK_DEFPROP_HAVE_SETTER;
|
|
||||||
duk_push_c_function(handle, props[i].setter, 1);
|
|
||||||
--objidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
duk_def_prop(handle, objidx, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
duk_put_prop_string(handle, -2, "prototype");
|
|
||||||
|
|
||||||
duk_put_global_string(handle, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::registerGlobal(const char* id,
|
|
||||||
Function getter, Function setter)
|
|
||||||
{
|
|
||||||
ContextHandle handle = m_ctx.handle();
|
|
||||||
|
|
||||||
duk_push_global_object(handle);
|
|
||||||
duk_push_string(handle, id);
|
|
||||||
|
|
||||||
duk_idx_t objidx = -2;
|
|
||||||
duk_uint_t flags = 0;
|
|
||||||
|
|
||||||
if (getter) {
|
|
||||||
flags |= DUK_DEFPROP_HAVE_GETTER;
|
|
||||||
duk_push_c_function(handle, getter, 0);
|
|
||||||
--objidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setter) {
|
|
||||||
flags |= DUK_DEFPROP_HAVE_SETTER;
|
|
||||||
duk_push_c_function(handle, setter, 1);
|
|
||||||
--objidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
duk_def_prop(handle, objidx, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace scripting
|
|
2
third_party/duktape
vendored
2
third_party/duktape
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 90090c7f9277e192af58e1878aee24e5d9f48eaa
|
Subproject commit 0de771cd55df729ec8a881b601ca3d4389e4a69a
|
Loading…
Reference in New Issue
Block a user