changeset 205:6b29e487da13

js: enable Molko.Music API
author David Demelier <markand@malikania.fr>
date Tue, 10 Nov 2020 10:10:56 +0100
parents c9fbb822d269
children 4e2bf083759b
files doc/api-js.rst doc/api-molko-music.rst molko-js/CMakeLists.txt molko-js/src/js-music.c molko-js/src/js-music.h molko-js/src/js.c
diffstat 6 files changed, 282 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/api-js.rst	Tue Nov 10 09:10:52 2020 +0100
+++ b/doc/api-js.rst	Tue Nov 10 10:10:56 2020 +0100
@@ -81,6 +81,7 @@
    api-molko-clock
    api-molko-event
    api-molko-font
+   api-molko-music
    api-molko-painter
    api-molko-sprite
    api-molko-texture
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/api-molko-music.rst	Tue Nov 10 10:10:56 2020 +0100
@@ -0,0 +1,80 @@
+.. toctree::
+.. highlight:: javascript
+.. _api-molko-music:
+
+Molko.Music
+===========
+
+Module for playing music. In contrast to sounds, you may play only one music at
+a time. On the other hand, a music can be looped.
+
+Constants
+---------
+
+.. js:data:: Molko.Music.<FLAG>
+
+The following values are available into the object itself:
+
+``NONE``
+  No flags to apply.
+``LOOP``
+  Loop the music.
+
+Constructors
+------------
+
+.. js:function:: Molko.Music(path)
+
+   :param string path: Path to the music file.
+   :throws Error: If unable to open the file.
+
+Open the music from the given file.
+
+Functions
+---------
+
+Since only one music can be played at a time, those following functions are
+static in the class.
+
+.. js:function:: Molko.Music.playing()
+
+   :returns: True if a music is playing.
+
+Tells if any music is currently playing.
+
+.. js:function:: Molko.Music.pause()
+
+Pause music playback immediately.
+
+.. js:function:: Molko.Music.resume()
+
+Resume music playback.
+
+.. js:function:: Molko.Music.stop(fadeout = 0)
+
+   :param uint fadeout: Optional fade out in milliseconds.
+
+Stop the music playback and apply an optional fade out effect.
+
+Methods
+-------
+
+.. js:method:: Molko.Music.play(effect = Molko.Music.NONE, fadein = 0)
+
+   :param uint effect: Optional flags (see :js:data:`Molko.Music.\<FLAG\>`).
+   :param uint fadein: Optional fade in in milliseconds.
+   :throws Error: In case of failure.
+
+Start playing this music with an optional fade in delay. If there is already a
+music playing it is stopped immediately unless it is currently fading out.
+
+Examples
+--------
+
+Play a loop music with a small 1/2 second fade in effect.
+
+::
+
+  var m = new Molko.Music("sample.ogg");
+
+  m.play(Molko.Music.LOOP, 500);
--- a/molko-js/CMakeLists.txt	Tue Nov 10 09:10:52 2020 +0100
+++ b/molko-js/CMakeLists.txt	Tue Nov 10 10:10:56 2020 +0100
@@ -28,6 +28,8 @@
 	${molko-js_SOURCE_DIR}/src/js-event.h
 	${molko-js_SOURCE_DIR}/src/js-font.c
 	${molko-js_SOURCE_DIR}/src/js-font.h
+	${molko-js_SOURCE_DIR}/src/js-music.c
+	${molko-js_SOURCE_DIR}/src/js-music.h
 	${molko-js_SOURCE_DIR}/src/js-painter.c
 	${molko-js_SOURCE_DIR}/src/js-painter.h
 	${molko-js_SOURCE_DIR}/src/js-sprite.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/molko-js/src/js-music.c	Tue Nov 10 10:10:56 2020 +0100
@@ -0,0 +1,170 @@
+/*
+ * js-music.c -- music support (Javascript bindings)
+ *
+ * Copyright (c) 2020 David Demelier <markand@malikania.fr>
+ *
+ * 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 <assert.h>
+
+#include <core/alloc.h>
+#include <core/error.h>
+#include <core/music.h>
+
+#include "js-music.h"
+
+#define SYMBOL          DUK_HIDDEN_SYMBOL("molko::music")
+
+static struct music *
+js_music_this(duk_context *ctx)
+{
+	struct music *mus;
+
+	duk_push_this(ctx);
+	duk_get_prop_string(ctx, -1, SYMBOL);
+	mus = duk_to_pointer(ctx, -1);
+	duk_pop_n(ctx, 2);
+
+	if (!mus)
+		duk_error(ctx, DUK_ERR_TYPE_ERROR, "Not a Music object");
+
+	return mus;
+}
+
+static duk_ret_t
+js_music_new(duk_context *ctx)
+{
+	struct music mus;
+	const char *path;
+
+	if (!duk_is_constructor_call(ctx))
+		return duk_error(ctx, DUK_ERR_TYPE_ERROR, "Music must be new-constructed");
+
+	path = duk_require_string(ctx, 0);
+
+	if (!music_open(&mus, path))
+		return duk_error(ctx, DUK_ERR_ERROR, "%s", error());
+
+	duk_push_this(ctx);
+	duk_push_pointer(ctx, alloc_dup(&mus, sizeof (mus)));
+	duk_put_prop_string(ctx, -2, SYMBOL);
+	duk_pop(ctx);
+
+	return 0;
+}
+
+static duk_ret_t
+js_music_playing(duk_context *ctx)
+{
+	duk_push_boolean(ctx, music_playing());
+
+	return 1;
+}
+
+static duk_ret_t
+js_music_pause(duk_context *ctx)
+{
+	(void)ctx;
+
+	music_pause();
+
+	return 0;
+}
+
+static duk_ret_t
+js_music_resume(duk_context *ctx)
+{
+	(void)ctx;
+
+	music_resume();
+
+	return 0;
+}
+
+static duk_ret_t
+js_music_stop(duk_context *ctx)
+{
+	music_stop(duk_get_uint(ctx, 0));
+
+	return 0;
+}
+
+static duk_ret_t
+js_music_play(duk_context *ctx)
+{
+	struct music *mus = js_music_this(ctx);
+	enum music_flags flags = duk_get_uint(ctx, 0);
+	unsigned int fadein = duk_get_uint(ctx, 1);
+
+	if (!music_play(mus, flags, fadein))
+		return duk_error(ctx, DUK_ERR_ERROR, "%s", error());
+
+	return 0;
+}
+
+static duk_ret_t
+js_music_finish(duk_context *ctx)
+{
+	struct music *mus;
+
+	duk_get_prop_string(ctx, 0, SYMBOL);
+
+	if ((mus = duk_to_pointer(ctx, -1))) {
+		music_finish(mus);
+		free(duk_to_pointer(ctx, -1));
+	}
+
+	duk_pop(ctx);
+	duk_del_prop_string(ctx, 0, SYMBOL);
+
+	return 0;
+}
+
+static const duk_number_list_entry flags[] = {
+	{ "NONE",       MUSIC_NONE                              },
+	{ "LOOP",       MUSIC_LOOP                              },
+	{ NULL,         0                                       }
+};
+
+static const duk_function_list_entry functions[] = {
+	{ "playing",    js_music_playing,       0               },
+	{ "pause",      js_music_pause,         0               },
+	{ "resume",     js_music_resume,        0               },
+	{ "stop",       js_music_stop,          DUK_VARARGS     },
+	{ NULL,         NULL,                   0               }
+};
+
+static const duk_function_list_entry methods[] = {
+	{ "play",       js_music_play,          DUK_VARARGS     },
+	{ NULL,         NULL,                   0               }
+};
+
+void
+js_music_load(duk_context *ctx)
+{
+	assert(ctx);
+
+	duk_push_global_object(ctx);
+	duk_get_prop_string(ctx, -1, "Molko");
+	duk_push_c_function(ctx, js_music_new, 3);
+	duk_put_function_list(ctx, -1, functions);
+	duk_put_number_list(ctx, -1, flags);
+	duk_push_object(ctx);
+	duk_put_function_list(ctx, -1, methods);
+	duk_push_c_function(ctx, js_music_finish, 1);
+	duk_set_finalizer(ctx, -2);
+	duk_put_prop_string(ctx, -2, "prototype");
+	duk_put_prop_string(ctx, -2, "Music");
+	duk_pop_n(ctx, 2);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/molko-js/src/js-music.h	Tue Nov 10 10:10:56 2020 +0100
@@ -0,0 +1,27 @@
+/*
+ * js-music.h -- music support (Javascript bindings)
+ *
+ * Copyright (c) 2020 David Demelier <markand@malikania.fr>
+ *
+ * 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 MOLKO_JS_MUSIC_H
+#define MOLKO_JS_MUSIC_H
+
+#include <duktape.h>
+
+void
+js_music_load(duk_context *ctx);
+
+#endif /* !MOLKO_JS_MUSIC_H */
--- a/molko-js/src/js.c	Tue Nov 10 09:10:52 2020 +0100
+++ b/molko-js/src/js.c	Tue Nov 10 10:10:56 2020 +0100
@@ -34,6 +34,7 @@
 #include "js-clock.h"
 #include "js-event.h"
 #include "js-font.h"
+#include "js-music.h"
 #include "js-painter.h"
 #include "js-sprite.h"
 #include "js-texture.h"
@@ -186,6 +187,7 @@
 	js_clock_load(js->handle);
 	js_event_load(js->handle);
 	js_font_load(js->handle);
+	js_music_load(js->handle);
 	js_painter_load(js->handle);
 	js_texture_load(js->handle);
 	js_sprite_load(js->handle);