Mercurial > malikania
changeset 23:ed63752a8720
Client: add JavaScript bindings for Animation, Animator, #454, #467
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 05 Apr 2016 21:06:27 +0200 |
parents | 1533fe3e3d64 |
children | 7f7c2607ace3 |
files | libclient/CMakeLists.txt libclient/malikania/animator.h libclient/malikania/js-animation.cpp libclient/malikania/js-animation.h libclient/malikania/js-animator.cpp libclient/malikania/js-animator.h tests/libclient/CMakeLists.txt tests/libclient/js-animation/CMakeLists.txt tests/libclient/js-animation/main.cpp tests/libclient/js-animation/resources/animations/margins.json tests/libclient/js-animation/resources/images/margins.png tests/libclient/js-animation/resources/sprites/margins.json |
diffstat | 12 files changed, 396 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libclient/CMakeLists.txt Mon Apr 04 22:09:06 2016 +0200 +++ b/libclient/CMakeLists.txt Tue Apr 05 21:06:27 2016 +0200 @@ -24,6 +24,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/color.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.h + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-animation.h + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-animator.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-color.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-font.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-image.h @@ -51,6 +53,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/color.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-animation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-animator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-color.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-image.cpp
--- a/libclient/malikania/animator.h Mon Apr 04 22:09:06 2016 +0200 +++ b/libclient/malikania/animator.h Tue Apr 05 21:06:27 2016 +0200 @@ -29,7 +29,7 @@ namespace malikania { class Animation; -class Position; +class Point; class Window; /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-animation.cpp Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,58 @@ +/* + * js-animation.cpp -- animation description (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-animation.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, "animation must be new-constructed"); + } + + try { + auto loader = duk::getGlobal<duk::RawPointer<ClientResourcesLoader>>(ctx, "\xff""\xff""loader"); + auto animation = loader->loadAnimation(duk::require<std::string>(ctx, 0)); + + duk::construct(ctx, duk::Pointer<Animation>{new Animation(std::move(animation))}); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +} // !namespace + +void loadMalikaniaAnimation(duk::ContextPtr ctx) +{ + duk::StackAssert sa(ctx); + + duk::getGlobal<void>(ctx, "Malikania"); + duk::push(ctx, duk::Function{constructor, 1}); + duk::putProperty(ctx, -2, "Animation"); + duk::pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-animation.h Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,49 @@ +/* + * js-animation.h -- animation description (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_ANIMATION_H +#define MALIKANIA_JS_ANIMATION_H + +#include "animation.h" +#include "js.h" + +namespace malikania { + +namespace duk { + +template <> +class TypeTraits<Animation> { +public: + static std::string name() + { + return "\xff""\xff""Animation"; + } + + static std::vector<std::string> inherits() + { + return {}; + } +}; + +} // !duk + +void loadMalikaniaAnimation(duk::ContextPtr ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_ANIMATION_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-animator.cpp Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,86 @@ +/* + * js-animator.cpp -- animation drawing 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 "js-animation.h" +#include "js-animator.h" +#include "js-point.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, "animator must be new-constructed"); + } + + duk::construct(ctx, duk::Pointer<Animator>{new Animator(*duk::get<duk::Pointer<Animation>>(ctx, 0))}); + + /* Be sure animation get not collected before */ + duk::push(ctx, duk::This()); + duk::dup(ctx, 0); + duk::putProperty(ctx, -2, "\xff""\xff""animation-ref"); + + return 0; +} + +duk::Ret draw(duk::ContextPtr ctx) +{ + try { + auto self = duk::self<duk::Pointer<Animator>>(ctx); + auto window = duk::get<duk::Pointer<Window>>(ctx, 0); + auto point = duk::get<Point>(ctx, 1); + + self->draw(*window, point); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk::Ret update(duk::ContextPtr ctx) +{ + duk::self<duk::Pointer<Animator>>(ctx)->update(); + + return 0; +} + +const duk::FunctionMap methods{ + { "draw", { draw, 2 } }, + { "update", { update, 0 } } +}; + +} // !namespace + +void loadMalikaniaAnimator(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, "Animator"); + duk::pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-animator.h Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,49 @@ +/* + * js-animator.h -- animation drawing 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_ANIMATOR_H +#define MALIKANIA_JS_ANIMATOR_H + +#include "animator.h" +#include "js.h" + +namespace malikania { + +namespace duk { + +template <> +class TypeTraits<Animator> { +public: + static std::string name() + { + return "\xff""\xff""Animator"; + } + + static std::vector<std::string> inherits() + { + return {}; + } +}; + +} // !duk + +void loadMalikaniaAnimator(duk::ContextPtr ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_ANIMATOR_H
--- a/tests/libclient/CMakeLists.txt Mon Apr 04 22:09:06 2016 +0200 +++ b/tests/libclient/CMakeLists.txt Tue Apr 05 21:06:27 2016 +0200 @@ -27,6 +27,7 @@ add_subdirectory(sprite) # JavaScript bindings +add_subdirectory(js-animation) add_subdirectory(js-color) add_subdirectory(js-font) add_subdirectory(js-image)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-animation/CMakeLists.txt Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,27 @@ +# +# 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-animation + LIBRARIES libclient + SOURCES main.cpp + RESOURCES + resources/animations/margins.json + resources/images/margins.png + resources/sprites/margins.json +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-animation/main.cpp Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,98 @@ +/* + * main.cpp -- test Animation (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/elapsed-timer.h> +#include <malikania/js-animation.h> +#include <malikania/js-animator.h> +#include <malikania/js-window.h> +#include <malikania/resources-locator.h> + +using namespace malikania; + +using namespace std::chrono_literals; + +class TestAnimation : public testing::Test { +protected: + ResourcesLocatorDirectory m_locator; + ClientResourcesLoader m_loader; + + duk::Context m_ctx; + +public: + TestAnimation() + : m_locator(SOURCE_DIRECTORY "/resources") + , m_loader(m_locator) + { + duk::putGlobal(m_ctx, "Malikania", duk::Object()); + + loadMalikaniaAnimation(m_ctx); + loadMalikaniaAnimator(m_ctx); + loadMalikaniaWindow(m_ctx); + + /* Store the loader */ + duk::putGlobal(m_ctx, "\xff""\xff""loader", duk::RawPointer<ClientResourcesLoader>{&m_loader}); + } +}; + +TEST_F(TestAnimation, basic) +{ + try { + auto ret = duk::pevalString(m_ctx, + "w = new Malikania.Window();" + "a = new Malikania.Animation('animations/margins.json');" + "d = new Malikania.Animator(a);" + ); + + if (ret != 0) { + throw duk::error(m_ctx, -1); + } + + ElapsedTimer timer; + + while (timer.elapsed() < 8000) { + auto ret = duk::pevalString(m_ctx, + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "d.draw(w, { x: 320 - 16, y: 240 - 16 });" + "d.update();" + "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(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-animation/resources/animations/margins.json Tue Apr 05 21:06:27 2016 +0200 @@ -0,0 +1,17 @@ +{ + "sprite": "sprites/margins.json", + "frames": [ + { "delay": 500 }, + { "delay": 501 }, + { "delay": 502 }, + { "delay": 503 }, + { "delay": 504 }, + { "delay": 505 }, + { "delay": 506 }, + { "delay": 507 }, + { "delay": 508 }, + { "delay": 509 }, + { "delay": 510 }, + { "delay": 511 } + ] +}