diff --git a/data/scripts/white_to_alpha.js b/data/scripts/white_to_alpha.js index 81eace42a..b8ab13d9f 100644 --- a/data/scripts/white_to_alpha.js +++ b/data/scripts/white_to_alpha.js @@ -2,7 +2,7 @@ // Copyright (C) 2015-2016 by David Capello var col = app.pixelColor -var img = app.activeSprite +var img = app.activeImage for (y=0; yactiveDocument(); if (doc) - ctx.pushObject(wrap_sprite(doc), "Sprite"); + ctx.pushObject(unwrap_engine(ctx)->wrapSprite(doc), "Sprite"); + else + ctx.pushNull(); + return 1; +} + +script::result_t App_get_activeImage(script::ContextHandle handle) +{ + script::Context ctx(handle); + app::Document* doc = UIContext::instance()->activeDocument(); + if (doc) { + SpriteWrap* wrap = unwrap_engine(ctx)->wrapSprite(doc); + ctx.pushObject(wrap->activeImage(), "Image"); + } else ctx.pushNull(); return 1; @@ -55,6 +70,7 @@ const script::FunctionEntry App_methods[] = { }; const script::PropertyEntry App_props[] = { + { "activeImage", App_get_activeImage, nullptr }, { "activeSprite", App_get_activeSprite, nullptr }, { "pixelColor", App_get_pixelColor, nullptr }, { "version", App_get_version, nullptr }, diff --git a/src/app/script/app_scripting.cpp b/src/app/script/app_scripting.cpp index db8c48b6d..637fb1962 100644 --- a/src/app/script/app_scripting.cpp +++ b/src/app/script/app_scripting.cpp @@ -11,9 +11,13 @@ #include "app/script/app_scripting.h" +#include "app/document.h" #include "app/script/app_object.h" #include "app/script/console_object.h" +#include "app/script/image_class.h" +#include "app/script/image_wrap.h" #include "app/script/sprite_class.h" +#include "app/script/sprite_wrap.h" namespace app { @@ -25,8 +29,51 @@ AppScripting::AppScripting(script::EngineDelegate* delegate) register_console_object(ctx); ctx.pushGlobalObject(); + register_image_class(-1, ctx); register_sprite_class(-1, ctx); + + ctx.pushPointer(this); + ctx.setProp(-2, script::kPtrId); + ctx.pop(); } +SpriteWrap* AppScripting::wrapSprite(app::Document* doc) +{ + auto it = m_sprites.find(doc->id()); + if (it != m_sprites.end()) + return it->second; + else { + auto wrap = new SpriteWrap(doc); + m_sprites[doc->id()] = wrap; + return wrap; + } +} + +void AppScripting::onAfterEval(bool err) +{ + // Commit all transactions + if (!err) { + for (auto& it : m_sprites) + it.second->commit(); + } + destroyWrappers(); +} + +void AppScripting::destroyWrappers() +{ + for (auto& it : m_sprites) + delete it.second; + m_sprites.clear(); +} + +AppScripting* unwrap_engine(script::Context& ctx) +{ + ctx.pushGlobalObject(); + ctx.getProp(-1, script::kPtrId); + void* ptr = ctx.getPointer(-1); + ctx.pop(2); + return (AppScripting*)ptr; +} + } diff --git a/src/app/script/app_scripting.h b/src/app/script/app_scripting.h index ac89a43d4..b44399209 100644 --- a/src/app/script/app_scripting.h +++ b/src/app/script/app_scripting.h @@ -5,19 +5,43 @@ // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. -#ifndef APP_SCRIPT_H_INCLUDED -#define APP_SCRIPT_H_INCLUDED +#ifndef APP_SCRIPTING_H_INCLUDED +#define APP_SCRIPTING_H_INCLUDED #pragma once +#include "doc/object_id.h" #include "script/engine.h" +#include + +namespace doc { + class Image; +} + namespace app { + class Document; + class ImageWrap; + class SpriteWrap; class AppScripting : public script::Engine { + typedef std::map Sprites; + public: AppScripting(script::EngineDelegate* delegate); + + SpriteWrap* wrapSprite(app::Document* doc); + + protected: + void onAfterEval(bool err) override; + + private: + void destroyWrappers(); + + Sprites m_sprites; }; + AppScripting* unwrap_engine(script::Context& ctx); + } // namespace app #endif diff --git a/src/app/script/image_class.cpp b/src/app/script/image_class.cpp new file mode 100644 index 000000000..8401d4e58 --- /dev/null +++ b/src/app/script/image_class.cpp @@ -0,0 +1,101 @@ +// 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/image_class.h" + +#include "app/script/image_wrap.h" +#include "doc/image.h" + +namespace app { + +namespace { + +script::result_t Image_ctor(script::ContextHandle handle) +{ + return 0; +} + +script::result_t Image_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); + + auto wrap = (ImageWrap*)ctx.getThis(); + if (wrap) { + wrap->modifyRegion(gfx::Region(gfx::Rect(x, y, 1, 1))); + wrap->image()->putPixel(x, y, color); + } + + return 0; +} + +script::result_t Image_getPixel(script::ContextHandle handle) +{ + script::Context ctx(handle); + int x = ctx.requireInt(0); + int y = ctx.requireInt(1); + + auto wrap = (ImageWrap*)ctx.getThis(); + if (wrap) { + doc::color_t color = wrap->image()->getPixel(x, y); + ctx.pushUInt(color); + return 1; + } + else + return 0; +} + +script::result_t Image_get_width(script::ContextHandle handle) +{ + script::Context ctx(handle); + auto wrap = (ImageWrap*)ctx.getThis(); + if (wrap) { + ctx.pushInt(wrap->image()->width()); + return 1; + } + else + return 0; +} + +script::result_t Image_get_height(script::ContextHandle handle) +{ + script::Context ctx(handle); + auto wrap = (ImageWrap*)ctx.getThis(); + if (wrap) { + ctx.pushInt(wrap->image()->height()); + return 1; + } + else + return 0; +} + +const script::FunctionEntry Image_methods[] = { + { "getPixel", Image_getPixel, 2 }, + { "putPixel", Image_putPixel, 3 }, + { nullptr, nullptr, 0 } +}; + +const script::PropertyEntry Image_props[] = { + { "width", Image_get_width, nullptr }, + { "height", Image_get_height, nullptr }, + { nullptr, nullptr, 0 } +}; + +} // anonymous namespace + +void register_image_class(script::index_t idx, script::Context& ctx) +{ + ctx.registerClass(idx, "Image", Image_ctor, 0, Image_methods, Image_props); +} + +} // namespace app diff --git a/src/app/script/image_class.h b/src/app/script/image_class.h new file mode 100644 index 000000000..4630c7c45 --- /dev/null +++ b/src/app/script/image_class.h @@ -0,0 +1,20 @@ +// 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_IMAGE_CLASS_H_INCLUDED +#define APP_SCRIPT_IMAGE_CLASS_H_INCLUDED +#pragma once + +#include "script/engine.h" + +namespace app { + + void register_image_class(script::index_t idx, script::Context& ctx); + +} // namespace app + +#endif diff --git a/src/app/script/image_wrap.cpp b/src/app/script/image_wrap.cpp new file mode 100644 index 000000000..9b6828afc --- /dev/null +++ b/src/app/script/image_wrap.cpp @@ -0,0 +1,52 @@ +// 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. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "app/script/image_wrap.h" + +#include "app/cmd/copy_region.h" +#include "app/script/sprite_wrap.h" +#include "app/transaction.h" +#include "doc/image.h" + +namespace app { + +ImageWrap::ImageWrap(SpriteWrap* sprite, doc::Image* img) + : m_sprite(sprite) + , m_image(img) + , m_backup(nullptr) +{ +} + +ImageWrap::~ImageWrap() +{ +} + +void ImageWrap::commit() +{ + if (m_modifiedRegion.isEmpty()) + return; + + sprite()->transaction().execute( + new cmd::CopyRegion(m_image, + m_backup.get(), + m_modifiedRegion, 0, 0, + true)); +} + +void ImageWrap::modifyRegion(const gfx::Region& rgn) +{ + if (!m_backup) + m_backup.reset(doc::Image::createCopy(m_image)); + + m_modifiedRegion |= rgn; +} + +} // namespace app diff --git a/src/app/script/image_wrap.h b/src/app/script/image_wrap.h new file mode 100644 index 000000000..50bc03078 --- /dev/null +++ b/src/app/script/image_wrap.h @@ -0,0 +1,39 @@ +// 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_IMAGE_WRAP_H_INCLUDED +#define APP_SCRIPT_IMAGE_WRAP_H_INCLUDED +#pragma once + +#include "doc/image.h" +#include "doc/image_ref.h" +#include "gfx/region.h" + +namespace app { + class SpriteWrap; + + class ImageWrap { + public: + ImageWrap(SpriteWrap* sprite, doc::Image* img); + ~ImageWrap(); + + void commit(); + + SpriteWrap* sprite() const { return m_sprite; } + doc::Image* image() const { return m_image; } + + void modifyRegion(const gfx::Region& rgn); + private: + SpriteWrap* m_sprite; + doc::Image* m_image; + doc::ImageRef m_backup; + gfx::Region m_modifiedRegion; + }; + +} // namespace app + +#endif diff --git a/src/app/script/sprite_class.cpp b/src/app/script/sprite_class.cpp index 83958616e..786aa1381 100644 --- a/src/app/script/sprite_class.cpp +++ b/src/app/script/sprite_class.cpp @@ -11,8 +11,11 @@ #include "app/script/sprite_class.h" +#include "app/cmd/set_sprite_size.h" #include "app/document.h" #include "app/document_api.h" +#include "app/script/app_scripting.h" +#include "app/script/sprite_wrap.h" #include "app/transaction.h" #include "app/ui/document_view.h" #include "app/ui_context.h" @@ -20,30 +23,10 @@ #include "doc/sprite.h" #include "script/engine.h" -#include -#include - 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); @@ -58,71 +41,22 @@ script::result_t Sprite_ctor(script::ContextHandle handle) sprite.release(); doc->setContext(UIContext::instance()); - ctx.pushThis(wrap_sprite(doc.release())); + ctx.pushThis(unwrap_engine(ctx)->wrapSprite(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); + auto wrap = (SpriteWrap*)ctx.getThis(); + if (wrap) { + Document* doc = wrap->document(); + DocumentApi api(doc, wrap->transaction()); api.setSpriteSize(doc->sprite(), w, h); - transaction.commit(); } return 0; @@ -136,12 +70,11 @@ script::result_t Sprite_crop(script::ContextHandle handle) 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); + auto wrap = (SpriteWrap*)ctx.getThis(); + if (wrap) { + Document* doc = wrap->document(); + DocumentApi api(doc, wrap->transaction()); api.cropSprite(doc->sprite(), gfx::Rect(x, y, w, h)); - transaction.commit(); } return 0; @@ -150,8 +83,8 @@ script::result_t Sprite_crop(script::ContextHandle handle) 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()); + auto wrap = (SpriteWrap*)ctx.getThis(); + ctx.pushInt(wrap->sprite()->width()); return 1; } @@ -159,16 +92,21 @@ 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()); + auto wrap = (SpriteWrap*)ctx.getThis(); + + wrap->transaction().execute( + new cmd::SetSpriteSize(wrap->sprite(), + w, + wrap->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()); + auto wrap = (SpriteWrap*)ctx.getThis(); + ctx.pushInt(wrap->sprite()->height()); return 1; } @@ -176,14 +114,17 @@ 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); + auto wrap = (SpriteWrap*)ctx.getThis(); + + wrap->transaction().execute( + new cmd::SetSpriteSize(wrap->sprite(), + wrap->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 } @@ -197,28 +138,6 @@ const script::PropertyEntry Sprite_props[] = { } // anonymous namespace -static std::map 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); diff --git a/src/app/script/sprite_class.h b/src/app/script/sprite_class.h index 98ab6e2d5..5c1ffe038 100644 --- a/src/app/script/sprite_class.h +++ b/src/app/script/sprite_class.h @@ -12,10 +12,6 @@ #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); diff --git a/src/app/script/sprite_wrap.cpp b/src/app/script/sprite_wrap.cpp new file mode 100644 index 000000000..cfdbbef02 --- /dev/null +++ b/src/app/script/sprite_wrap.cpp @@ -0,0 +1,96 @@ +// 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. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "app/script/sprite_wrap.h" + +#include "app/cmd/set_sprite_size.h" +#include "app/document.h" +#include "app/document_api.h" +#include "app/script/image_wrap.h" +#include "app/transaction.h" +#include "app/ui/document_view.h" +#include "app/ui_context.h" +#include "doc/site.h" +#include "doc/sprite.h" + +namespace app { + +SpriteWrap::SpriteWrap(app::Document* doc) + : m_doc(doc) + , m_view(UIContext::instance()->getFirstDocumentView(m_doc)) + , m_transaction(nullptr) +{ +} + +SpriteWrap::~SpriteWrap() +{ + for (auto it : m_images) + delete it.second; + + if (m_transaction) + delete m_transaction; +} + +Transaction& SpriteWrap::transaction() +{ + if (!m_transaction) { + m_transaction = new Transaction(UIContext::instance(), + "Script Execution", + ModifyDocument); + } + return *m_transaction; +} + +void SpriteWrap::commit() +{ + for (auto it : m_images) + it.second->commit(); + + if (m_transaction) { + m_transaction->commit(); + delete m_transaction; + m_transaction = nullptr; + } +} + +app::Document* SpriteWrap::document() +{ + return m_doc; +} + +doc::Sprite* SpriteWrap::sprite() +{ + return m_doc->sprite(); +} + +ImageWrap* SpriteWrap::activeImage() +{ + if (!m_view) + return nullptr; + + doc::Site site; + m_view->getSite(&site); + return wrapImage(site.image()); +} + +ImageWrap* SpriteWrap::wrapImage(doc::Image* img) +{ + auto it = m_images.find(img->id()); + if (it != m_images.end()) + return it->second; + else { + auto wrap = new ImageWrap(this, img); + m_images[img->id()] = wrap; + return wrap; + } +} + +} // namespace app diff --git a/src/app/script/sprite_wrap.h b/src/app/script/sprite_wrap.h new file mode 100644 index 000000000..5b4f05c37 --- /dev/null +++ b/src/app/script/sprite_wrap.h @@ -0,0 +1,53 @@ +// 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_SPRITE_WRAP_H_INCLUDED +#define APP_SCRIPT_SPRITE_WRAP_H_INCLUDED +#pragma once + +#include "doc/object_id.h" + +#include + +namespace doc { + class Image; + class Sprite; +} + +namespace app { + class Document; + class DocumentView; + class ImageWrap; + class Transaction; + + class SpriteWrap { + typedef std::map Images; + + public: + SpriteWrap(app::Document* doc); + ~SpriteWrap(); + + void commit(); + Transaction& transaction(); + + app::Document* document(); + doc::Sprite* sprite(); + ImageWrap* activeImage(); + + ImageWrap* wrapImage(doc::Image* img); + + private: + app::Document* m_doc; + app::DocumentView* m_view; + app::Transaction* m_transaction; + + Images m_images; + }; + +} // namespace app + +#endif diff --git a/src/script/engine.cpp b/src/script/engine.cpp index bc54660d0..eea3c587c 100644 --- a/src/script/engine.cpp +++ b/src/script/engine.cpp @@ -30,6 +30,8 @@ public: namespace script { +const char* kPtrId = "\xFF" "\xFF" "ptr"; + namespace { // TODO classes in modules isn't supported yet @@ -108,6 +110,11 @@ void Context::pop() duk_pop(m_handle); } +void Context::pop(index_t count) +{ + duk_pop_n(m_handle, count); +} + void Context::remove(index_t idx) { duk_remove(m_handle, idx); @@ -193,6 +200,11 @@ const char* Context::toString(index_t i) return duk_to_string(m_handle, i); } +void* Context::getPointer(index_t i) +{ + return duk_get_pointer(m_handle, i); +} + bool Context::requireBool(index_t i) { return (duk_require_boolean(m_handle, i) ? true: false); @@ -220,7 +232,7 @@ const char* Context::requireString(index_t i) void* Context::requireObject(index_t i, const char* className) { - duk_get_prop_string(m_handle, i, "\xFF" "\xFF" "ptr"); + duk_get_prop_string(m_handle, i, kPtrId); void* result = (void*)duk_to_pointer(m_handle, -1); // TODO check pointer type duk_pop(m_handle); @@ -276,7 +288,12 @@ 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"); + duk_put_prop_string(m_handle, -2, kPtrId); +} + +void Context::pushPointer(void* ptr) +{ + duk_push_pointer(m_handle, ptr); } index_t Context::pushObject() @@ -288,7 +305,7 @@ 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"); + duk_put_prop_string(m_handle, obj, kPtrId); // TODO classes in modules isn't supported yet duk_get_global_string(m_handle, className); @@ -395,7 +412,7 @@ void Context::registerClass(index_t idx, void* Context::getThis() { duk_push_this(m_handle); - duk_get_prop_string(m_handle, -1, "\xFF" "\xFF" "ptr"); + duk_get_prop_string(m_handle, -1, kPtrId); void* result = (void*)duk_to_pointer(m_handle, -1); duk_pop_2(m_handle); return result; @@ -445,6 +462,8 @@ void Engine::printLastResult() void Engine::eval(const std::string& jsCode) { + bool errFlag = true; + onBeforeEval(); try { ContextHandle handle = m_ctx.handle(); @@ -453,18 +472,23 @@ void Engine::eval(const std::string& jsCode) if (m_printLastResult && !duk_is_null_or_undefined(handle, -1)) { m_delegate->onConsolePrint(duk_safe_to_string(handle, -1)); + } duk_pop(handle); + errFlag = false; } catch (const std::exception& ex) { std::string err = "Error: "; err += ex.what(); m_delegate->onConsolePrint(err.c_str()); } + onAfterEval(errFlag); } void Engine::evalFile(const std::string& file) { + bool errFlag = true; + onBeforeEval(); try { ContextHandle handle = m_ctx.handle(); @@ -497,14 +521,17 @@ void Engine::evalFile(const std::string& file) if (m_printLastResult && !duk_is_null_or_undefined(handle, -1)) { m_delegate->onConsolePrint(duk_safe_to_string(handle, -1)); + } duk_pop(handle); + errFlag = false; } catch (const std::exception& ex) { std::string err = "Error: "; err += ex.what(); m_delegate->onConsolePrint(err.c_str()); } + onAfterEval(errFlag); } void Engine::registerModule(Module* module) diff --git a/src/script/engine.h b/src/script/engine.h index ec9534a14..fc6e2a515 100644 --- a/src/script/engine.h +++ b/src/script/engine.h @@ -21,6 +21,8 @@ namespace script { typedef struct duk_hthread* ContextHandle; typedef result_t (*Function)(ContextHandle ctx); + extern const char* kPtrId; + struct FunctionEntry { const char* id; Function value; @@ -48,6 +50,7 @@ namespace script { void dump(); void pop(); + void pop(index_t count); void remove(index_t idx); void duplicateTop(); @@ -68,6 +71,7 @@ namespace script { unsigned int getUInt(index_t i); const char* getString(index_t i); const char* toString(index_t i); + void* getPointer(index_t i); void* getThis(); bool hasProp(index_t i, const char* propName); @@ -91,6 +95,7 @@ namespace script { void pushString(const char* str); void pushThis(); void pushThis(void* ptr); + void pushPointer(void* ptr); index_t pushObject(); index_t pushObject(void* ptr, const char* className); void pushGlobalObject(); @@ -134,6 +139,10 @@ namespace script { void registerModule(Module* module); + protected: + virtual void onBeforeEval() { } + virtual void onAfterEval(bool err) { } + private: Context m_ctx; EngineDelegate* m_delegate;