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 }
+  ]
+}
Binary file tests/libclient/js-animation/resources/images/margins.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/libclient/js-animation/resources/sprites/margins.json	Tue Apr 05 21:06:27 2016 +0200
@@ -0,0 +1,6 @@
+{
+  "image": "images/margins.png",
+  "cell": [ 32, 32 ],
+  "margin": [ 4, 6 ],
+  "space": [ 2, 3 ]
+}