Mercurial > malikania
changeset 19:6400830bb36b
Client: add some JavaScript bindings for Image, #457
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 04 Apr 2016 13:20:06 +0200 |
parents | cc13926bed59 |
children | 787c2adb366c |
files | libclient/CMakeLists.txt libclient/malikania/js-image.cpp libclient/malikania/js-image.h tests/libclient/CMakeLists.txt tests/libclient/js-image/CMakeLists.txt tests/libclient/js-image/main.cpp tests/libclient/js-image/resources/images/smiley.png |
diffstat | 7 files changed, 269 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libclient/CMakeLists.txt Sun Apr 03 20:10:37 2016 +0200 +++ b/libclient/CMakeLists.txt Mon Apr 04 13:20:06 2016 +0200 @@ -25,6 +25,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-color.h + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-image.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-line.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-point.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-rectangle.h @@ -49,6 +50,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-color.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-image.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-line.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-point.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-rectangle.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-image.cpp Mon Apr 04 13:20:06 2016 +0200 @@ -0,0 +1,88 @@ +/* + * js-image.cpp -- image object (JavaScript binding) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "client-resources-loader.h" +#include "js-image.h" +#include "js-point.h" +#include "js-rectangle.h" +#include "js-window.h" + +namespace malikania { + +namespace { + +duk::Ret constructor(duk::ContextPtr ctx) +{ + duk::StackAssert sa(ctx); + + if (!duk_is_constructor_call(ctx)) { + duk::raise(ctx, DUK_ERR_ERROR, "image must be new-constructed"); + } + + try { + auto loader = duk::getGlobal<duk::RawPointer<ClientResourcesLoader>>(ctx, "\xff""\xff""loader"); + auto image = loader->loadImage(duk::require<std::string>(ctx, 0)); + + duk::construct(ctx, duk::Pointer<Image>{new Image(std::move(image))}); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk::Ret draw(duk::ContextPtr ctx) +{ + try { + auto self = duk::self<duk::Pointer<Image>>(ctx); + auto window = duk::get<duk::Pointer<Window>>(ctx, 0); + + if (duk::top(ctx) == 2) { + self->draw(*window, duk::get<Point>(ctx, 1)); + } else if (duk::top(ctx) == 3) { + self->draw(*window, duk::get<Rectangle>(ctx, 1), duk::get<Rectangle>(ctx, 2)); + } else { + duk::raise(ctx, DUK_ERR_TYPE_ERROR, "invalid number of arguments: #%d", duk::top(ctx)); + } + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +const duk::FunctionMap methods{ + { "draw", { draw, DUK_VARARGS } } +}; + +} // !namespace + +void loadMalikaniaImage(duk::ContextPtr ctx) +{ + duk::StackAssert sa(ctx); + + duk::getGlobal<void>(ctx, "Malikania"); + duk::push(ctx, duk::Function{constructor, 1}); + duk::push(ctx, duk::Object()); + duk::push(ctx, methods); + duk::putProperty(ctx, -2, "prototype"); + duk::putProperty(ctx, -2, "Image"); + duk::pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-image.h Mon Apr 04 13:20:06 2016 +0200 @@ -0,0 +1,49 @@ +/* + * js-image.h -- image object (JavaScript binding) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_JS_IMAGE_H +#define MALIKANIA_JS_IMAGE_H + +#include "image.h" +#include "js.h" + +namespace malikania { + +namespace duk { + +template <> +class TypeTraits<Image> { +public: + static inline std::string name() + { + return "\xff""\xff""Image"; + } + + static inline std::vector<std::string> inherits() + { + return {}; + } +}; + +} // !duk + +void loadMalikaniaImage(duk::ContextPtr ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_IMAGE_H
--- a/tests/libclient/CMakeLists.txt Sun Apr 03 20:10:37 2016 +0200 +++ b/tests/libclient/CMakeLists.txt Mon Apr 04 13:20:06 2016 +0200 @@ -28,6 +28,7 @@ # JavaScript bindings add_subdirectory(js-color) +add_subdirectory(js-image) add_subdirectory(js-line) add_subdirectory(js-point) add_subdirectory(js-rectangle)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-image/CMakeLists.txt Mon Apr 04 13:20:06 2016 +0200 @@ -0,0 +1,25 @@ +# +# CMakeLists.txt -- CMake build system for malikania +# +# Copyright (c) 2013-2016 Malikania Authors +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +malikania_create_test( + NAME js-image + LIBRARIES libclient + SOURCES main.cpp + RESOURCES + resources/images/smiley.png +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-image/main.cpp Mon Apr 04 13:20:06 2016 +0200 @@ -0,0 +1,104 @@ +/* + * main.cpp -- test Image (JavaScript binding) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <chrono> +#include <thread> + +#include <gtest/gtest.h> + +#include <malikania/client-resources-loader.h> +#include <malikania/js-image.h> +#include <malikania/js-window.h> +#include <malikania/resources-locator.h> + +using namespace malikania; + +using namespace std::chrono_literals; + +class TestImage : public testing::Test { +protected: + ResourcesLocatorDirectory m_locator; + ClientResourcesLoader m_loader; + + duk::Context m_ctx; + +public: + TestImage() + : m_locator(SOURCE_DIRECTORY "/resources") + , m_loader(m_locator) + { + duk::putGlobal(m_ctx, "Malikania", duk::Object()); + + loadMalikaniaImage(m_ctx); + loadMalikaniaWindow(m_ctx); + + /* Store the loader */ + duk::putGlobal(m_ctx, "\xff""\xff""loader", duk::RawPointer<ClientResourcesLoader>{&m_loader}); + } +}; + +TEST_F(TestImage, basic) +{ + try { + auto ret = duk::pevalString(m_ctx, + "w = new Malikania.Window();" + "i = new Malikania.Image('images/smiley.png');" + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "i.draw(w, { x: 320 - 16, y: 240 - 16 });" + "w.present();" + ); + + if (ret != 0) { + throw duk::error(m_ctx, -1); + } + + std::this_thread::sleep_for(3s); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +TEST_F(TestImage, stretch) +{ + try { + auto ret = duk::pevalString(m_ctx, + "w = new Malikania.Window();" + "i = new Malikania.Image('images/smiley.png');" + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "i.draw(w, null, { x: 10, y: 10, width: 620, height: 460 });" + "w.present();" + ); + + if (ret != 0) { + throw duk::error(m_ctx, -1); + } + + std::this_thread::sleep_for(3s); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}