Mercurial > malikania
changeset 21:a087bc11ba04
Client: add JavaScript bindings for Sprite, #461
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 04 Apr 2016 21:35:13 +0200 |
parents | 787c2adb366c |
children | 1533fe3e3d64 |
files | libclient/CMakeLists.txt libclient/malikania/js-sprite.cpp libclient/malikania/js-sprite.h tests/libclient/CMakeLists.txt tests/libclient/js-sprite/CMakeLists.txt tests/libclient/js-sprite/main.cpp tests/libclient/js-sprite/resources/images/margins.png tests/libclient/js-sprite/resources/sprites/margins.json |
diffstat | 8 files changed, 293 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libclient/CMakeLists.txt Mon Apr 04 18:51:30 2016 +0200 +++ b/libclient/CMakeLists.txt Mon Apr 04 21:35:13 2016 +0200 @@ -29,6 +29,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-line.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-point.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-rectangle.h + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-sprite.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-window.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/label.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/line.h @@ -54,6 +55,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-line.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-point.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-rectangle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-sprite.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-size.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-window.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/label.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-sprite.cpp Mon Apr 04 21:35:13 2016 +0200 @@ -0,0 +1,86 @@ +/* + * js-sprite.cpp -- sprite 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-point.h" +#include "js-size.h" +#include "js-sprite.h" +#include "js-window.h" + +namespace malikania { + +namespace { + +duk::Ret constructor(duk::ContextPtr ctx) +{ + if (!duk_is_constructor_call(ctx)) { + duk::raise(ctx, DUK_ERR_ERROR, "sprite must be new-constructed"); + } + + try { + auto loader = duk::getGlobal<duk::RawPointer<ClientResourcesLoader>>(ctx, "\xff""\xff""loader"); + auto sprite = loader->loadSprite(duk::require<std::string>(ctx, 0)); + + duk::construct(ctx, duk::Pointer<Sprite>{new Sprite(std::move(sprite))}); + } 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<Sprite>>(ctx); + auto window = duk::get<duk::Pointer<Window>>(ctx, 0); + auto cell = duk::require<int>(ctx, 1); + auto point = duk::get<Point>(ctx, 2); + + if (cell < 0 || cell >= static_cast<int>(self->rows() * self->columns())) { + duk::raise(ctx, DUK_ERR_RANGE_ERROR, "%d is out of range", cell); + } + + self->draw(*window, static_cast<unsigned>(cell), point); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +const duk::FunctionMap methods{ + { "draw", { draw, 3 } } +}; + +} // !namespace + +void loadMalikaniaSprite(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, "Sprite"); + duk::pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-sprite.h Mon Apr 04 21:35:13 2016 +0200 @@ -0,0 +1,78 @@ +/* + * js-sprite.h -- sprite 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_SPRITE_H +#define MALIKANIA_JS_SPRITE_H + +#include "js.h" +#include "sprite.h" + +namespace malikania { + +namespace duk { + +/** + * @brief JavaScript binding for Sprite. + */ +template <> +class TypeTraits<Sprite> { +public: + /** + * Put the Sprite prototype to the top of the stack. + * + * @param ctx the context + */ + static void prototype(ContextPtr ctx) + { + duk::StackAssert sa(ctx, 1); + + duk::getGlobal<void>(ctx, "Malikania"); + duk::getGlobal<void>(ctx, "Sprite"); + duk::getProperty<void>(ctx, -1, "prototype"); + duk::remove(ctx, -2); + duk::remove(ctx, -2); + } + + /** + * Get the object signature. + * + * @return Sprite signature + */ + static inline std::string name() + { + return "\xff""\xff""Sprite"; + } + + /** + * Get inheritance list. + * + * @return empty + */ + static inline std::vector<std::string> inherits() + { + return {}; + } +}; + +} // !duk + +void loadMalikaniaSprite(duk::ContextPtr ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_SPRITE_H
--- a/tests/libclient/CMakeLists.txt Mon Apr 04 18:51:30 2016 +0200 +++ b/tests/libclient/CMakeLists.txt Mon Apr 04 21:35:13 2016 +0200 @@ -33,4 +33,5 @@ add_subdirectory(js-point) add_subdirectory(js-rectangle) add_subdirectory(js-size) +add_subdirectory(js-sprite) add_subdirectory(js-window)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-sprite/CMakeLists.txt Mon Apr 04 21:35:13 2016 +0200 @@ -0,0 +1,26 @@ +# +# 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-sprite + LIBRARIES libclient + SOURCES main.cpp + RESOURCES + resources/images/margins.png + resources/sprites/margins.json +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-sprite/main.cpp Mon Apr 04 21:35:13 2016 +0200 @@ -0,0 +1,94 @@ +/* + * main.cpp -- test Sprite (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-sprite.h> +#include <malikania/js-window.h> +#include <malikania/resources-locator.h> + +using namespace malikania; + +using namespace std::chrono_literals; + +class TestSprite : public testing::Test { +protected: + ResourcesLocatorDirectory m_locator; + ClientResourcesLoader m_loader; + + duk::Context m_ctx; + +public: + TestSprite() + : m_locator(SOURCE_DIRECTORY "/resources") + , m_loader(m_locator) + { + duk::putGlobal(m_ctx, "Malikania", duk::Object()); + + loadMalikaniaImage(m_ctx); + loadMalikaniaSprite(m_ctx); + loadMalikaniaWindow(m_ctx); + + /* Store the loader */ + duk::putGlobal(m_ctx, "\xff""\xff""loader", duk::RawPointer<ClientResourcesLoader>{&m_loader}); + } +}; + +TEST_F(TestSprite, basic) +{ + try { + auto ret = duk::pevalString(m_ctx, + "w = new Malikania.Window();" + "s = new Malikania.Sprite('sprites/margins.json');" + "c = 0;" + ); + + if (ret != 0) { + throw duk::error(m_ctx, -1); + } + + for (unsigned c = 0; c < 12; ++c) { + auto ret = duk::pevalString(m_ctx, + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "s.draw(w, c++, { x: 320 - 16, y: 240 - 16 });" + "w.present();" + ); + + if (ret != 0) { + throw duk::error(m_ctx, -1); + } + + std::this_thread::sleep_for(1s); + } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}