Mercurial > malikania
changeset 42:a47a4477f347
Misc: new style, closes #578
line wrap: on
line diff
--- a/client/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/client/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -16,202 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <chrono> -#include <iostream> -#include <thread> - -#include <malikania/client-resources-loader.hpp> -#include <malikania/resources-locator.hpp> - -#include <malikania/js-animation.hpp> -#include <malikania/js-animator.hpp> -#include <malikania/js-client.hpp> -#include <malikania/js-client-target.hpp> -#include <malikania/js-color.hpp> -#include <malikania/js-font.hpp> -#include <malikania/js-image.hpp> -#include <malikania/js-line.hpp> -#include <malikania/js-point.hpp> -#include <malikania/js-rectangle.hpp> -#include <malikania/js-size.hpp> -#include <malikania/js-sprite.hpp> -#include <malikania/js-window.hpp> - -#if 0 - -using namespace malikania; - -namespace { - -int usage() -{ - std::cerr << "usage: mlk-client directory\n"; - - return 1; -} - -duk::Context init() +int main() { - duk::Context ctx; - - /* TODO: Put Malikania global somewhere else */ - duk::putGlobal(ctx, "Malikania", duk::Object()); - - loadMalikaniaAnimation(ctx); - loadMalikaniaAnimator(ctx); - loadMalikaniaColor(ctx); - loadMalikaniaFont(ctx); - loadMalikaniaImage(ctx); - loadMalikaniaLine(ctx); - loadMalikaniaPoint(ctx); - loadMalikaniaRectangle(ctx); - loadMalikaniaSize(ctx); - loadMalikaniaSprite(ctx); - loadMalikaniaWindow(ctx); - loadMalikaniaClient(ctx); - loadMalikaniaClientTarget(ctx); - - return ctx; -} - -void start(duk::Context &ctx, std::shared_ptr<Client> client) -{ - duk::getGlobal<void>(ctx, "start"); - - if (duk::is<duk::Function>(ctx, -1)) { - duk::push(ctx, std::move(client)); - duk::pcall(ctx, 1); - duk::pop(ctx); - } else { - duk::pop(ctx); - } -} - -void update(duk::Context &ctx, std::shared_ptr<Client> client) -{ - duk::getGlobal<void>(ctx, "update"); - - if (duk::is<duk::Function>(ctx, -1)) { - duk::push(ctx, std::move(client)); - duk::pcall(ctx, 1); - duk::pop(ctx); - } else { - duk::pop(ctx); - client->update(); - } -} - -void draw(duk::Context &ctx, std::shared_ptr<Client> client) -{ - duk::getGlobal<void>(ctx, "draw"); - - if (duk::is<duk::Function>(ctx, -1)) { - duk::push(ctx, std::move(client)); - duk::pcall(ctx, 1); - duk::pop(ctx); - } else { - duk::pop(ctx); - client->draw(); - } } -int run(duk::Context &ctx) -{ - auto running = true; - auto client = std::make_shared<Client>(); - - client->setOnQuit([&] () { - running = false; - }); - client->setOnKeyDown([&] (unsigned key) { - duk::getGlobal<void>(ctx, "keyDown"); - - if (duk::is<duk::Function>(ctx, -1)) { - duk::push(ctx, static_cast<int>(key)); - duk::pcall(ctx, 1); - duk::pop(ctx); - } else { - duk::pop(ctx); - } - }); - client->setOnKeyDown([&] (unsigned key) { - duk::getGlobal<void>(ctx, "keyUp"); - - if (duk::is<duk::Function>(ctx, -1)) { - duk::push(ctx, static_cast<int>(key)); - duk::pcall(ctx, 1); - duk::pop(ctx); - } else { - duk::pop(ctx); - } - }); - - start(ctx, client); - - while (running) { - client->poll(); - - update(ctx, client); - draw(ctx, client); - - // TODO: remove this with an appropriate FPS calculation. - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - - return 0; -} - -int boot(const std::string &directory) -{ - std::string path = directory + "/client.js"; - duk::Context ctx = init(); - - /* Store the loader */ - ResourcesLocatorDirectory locator(directory); - ClientResourcesLoader loader(locator); - - duk::putGlobal(ctx, "\xff""\xff""loader", &loader); - - if (duk::pevalFile(ctx, path) != 0) { - duk::Exception info = duk::exception(ctx, -1); - - std::cerr << info.fileName << ":" << info.lineNumber << ": " << info.stack << std::endl; - - return 1; - } - - return run(ctx); -} - -} // !namespace - -int main(int argc, char **argv) -{ -#if 0 - -- argc; - ++ argv; - - if (argc < 1) { - return usage(); - } - - return boot(argv[0]); -#endif - Client client; - ElapsedTimer timer; - - while (timer.elapsed() < 5000) { - client.poll(); - client.update(); - client.draw(); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - - return 0; -} - -#endif - -int main() {} -
--- a/database/sqlite/src/account.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/database/sqlite/src/account.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -67,16 +67,16 @@ "select count(*) from mk_account" ); -Account to_account(sqlite::statement& stmt) +account to_account(sqlite::statement& stmt) { - Account ac; + account ac; - ac.setId(sqlite3_column_int64(stmt.get(), 0)); - ac.setName(reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 1))); - ac.setEmail(reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 2))); - ac.setFirstName(reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 3))); - ac.setLastName(reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 4))); - ac.setPassword(reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 5))); + ac.id = sqlite3_column_int64(stmt.get(), 0); + ac.name = reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 1)); + ac.email = reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 2)); + ac.first_name = reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 3)); + ac.last_name = reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 4)); + ac.password = reinterpret_cast<const char *>(sqlite3_column_text(stmt.get(), 5)); return ac; } @@ -87,51 +87,51 @@ extern "C" { -BOOST_SYMBOL_EXPORT void malikania_account_create(Account& account) +BOOST_SYMBOL_EXPORT void malikania_account_create(account& account) { auto stmt = sqlite::prepare(create_query); - sqlite3_bind_text(stmt.get(), 1, account.name().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 2, account.email().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 3, account.firstName().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 4, account.lastName().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 5, account.password().c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 1, account.name.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 2, account.email.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 3, account.first_name.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 4, account.last_name.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 5, account.password.c_str(), -1, nullptr); if (sqlite3_step(stmt.get()) != SQLITE_DONE) { throw std::runtime_error(sqlite3_errmsg(sqlite::database.get())); } - account.setId(sqlite3_last_insert_rowid(sqlite::database.get())); + account.id = sqlite3_last_insert_rowid(sqlite::database.get()); } -BOOST_SYMBOL_EXPORT void malikania_account_update(Account& account) +BOOST_SYMBOL_EXPORT void malikania_account_update(account& account) { auto stmt = sqlite::prepare(update_query); - sqlite3_bind_text(stmt.get(), 1, account.name().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 2, account.email().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 3, account.firstName().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 4, account.lastName().c_str(), -1, nullptr); - sqlite3_bind_text(stmt.get(), 5, account.password().c_str(), -1, nullptr); - sqlite3_bind_int64(stmt.get(), 6, account.id()); + sqlite3_bind_text(stmt.get(), 1, account.name.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 2, account.email.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 3, account.first_name.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 4, account.last_name.c_str(), -1, nullptr); + sqlite3_bind_text(stmt.get(), 5, account.password.c_str(), -1, nullptr); + sqlite3_bind_int64(stmt.get(), 6, account.id); if (sqlite3_step(stmt.get()) != SQLITE_DONE) { throw std::runtime_error(sqlite3_errmsg(sqlite::database.get())); } } -BOOST_SYMBOL_EXPORT void malikania_account_remove(const Account& account) +BOOST_SYMBOL_EXPORT void malikania_account_remove(const account& account) { auto stmt = sqlite::prepare(delete_query); - sqlite3_bind_int64(stmt.get(), 1, account.id()); + sqlite3_bind_int64(stmt.get(), 1, account.id); if (sqlite3_step(stmt.get()) != SQLITE_OK) { throw std::runtime_error(sqlite3_errmsg(sqlite::database.get())); } } -BOOST_SYMBOL_EXPORT Account malikania_account_get(std::uint64_t id) +BOOST_SYMBOL_EXPORT account malikania_account_get(std::uint64_t id) { auto stmt = sqlite::prepare(get_query); @@ -144,11 +144,11 @@ return to_account(stmt); } -BOOST_SYMBOL_EXPORT std::vector<Account> malikania_account_list() +BOOST_SYMBOL_EXPORT std::vector<account> malikania_account_list() { auto stmt = sqlite::prepare(list_query); - std::vector<Account> list; + std::vector<account> list; while (sqlite3_step(stmt.get()) == SQLITE_ROW) { list.push_back(to_account(stmt));
--- a/libclient-js/CMakeLists.txt Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient-js/CMakeLists.txt Tue Nov 29 21:21:36 2016 +0100 @@ -20,37 +20,37 @@ set( HEADERS - ${libclient-js_SOURCE_DIR}/malikania/js-animation.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-animator.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-client.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-client-resources-loader.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-client-target.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-color.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-font.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-image.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-line.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-point.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-rectangle.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-sprite.hpp - ${libclient-js_SOURCE_DIR}/malikania/js-window.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_animation.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_animator.hpp +# ${libclient-js_SOURCE_DIR}/malikania/js_client.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_client_resources_loader.hpp +# ${libclient-js_SOURCE_DIR}/malikania/js_client_target.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_color.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_font.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_image.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_line.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_point.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_rectangle.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_sprite.hpp + ${libclient-js_SOURCE_DIR}/malikania/js_window.hpp ) set( SOURCES - ${libclient-js_SOURCE_DIR}/malikania/js-animation.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-animator.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-client.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-client-resources-loader.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-client-target.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-color.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-font.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-image.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-line.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-point.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-rectangle.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-sprite.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-size.cpp - ${libclient-js_SOURCE_DIR}/malikania/js-window.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_animation.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_animator.cpp +# ${libclient-js_SOURCE_DIR}/malikania/js_client.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_client_resources_loader.cpp +# ${libclient-js_SOURCE_DIR}/malikania/js_client_target.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_color.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_font.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_image.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_line.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_point.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_rectangle.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_sprite.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_size.cpp + ${libclient-js_SOURCE_DIR}/malikania/js_window.cpp ) malikania_create_library(
--- a/libclient-js/malikania/js-animation.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * 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 <cassert> - -#include "js-client-resources-loader.hpp" -#include "js-animation.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff""\xff""malikania-animation-ptr"); - -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - duk_error(ctx, DUK_ERR_ERROR, "animation must be new-constructed"); - - try { - auto loader = dukx_get_client_loader(ctx); - auto animation = loader->loadAnimation(duk_require_string(ctx, 0)); - - dukx_new_animation(ctx, new Animation(std::move(animation))); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, Signature.c_str()); - delete static_cast<Animation *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, Signature.c_str()); - - return 0; -} - -} // !namespace - -void dukx_new_animation(duk_context *ctx, Animation *animation) -{ - assert(ctx); - assert(animation); - - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_push_pointer(ctx, animation); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); -} - -Animation *dukx_require_animation(duk_context *ctx, duk_idx_t index) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_prop_string(ctx, index, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Animation object"); - - return static_cast<Animation *>(ptr); -} - -void dukx_load_animation(duk_context *ctx) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 1); - duk_push_object(ctx); - duk_push_c_function(ctx, destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "Animation"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-animation.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * js-animation.hpp -- 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_HPP -#define MALIKANIA_JS_ANIMATION_HPP - -#include <malikania/duktape.hpp> - -#include "animation.hpp" - -namespace malikania { - -/** - * Construct an Animation object as this. - * - * \pre ctx != nullptr - * \pre animation != nullptr - * \param ctx the context - * \param animation the animation - */ -void dukx_new_animation(duk_context *ctx, Animation *animation); - -/** - * Get an Animation object at the given index or raise a JavaScript error. - * - * \pre ctx != nullptr - * \param ctx the context - * \param index the value index - * \return the Animation object - */ -Animation *dukx_require_animation(duk_context *ctx, duk_idx_t index); - -/** - * Load the Animation module into the context. - * - * \pre ctx != nullptr - * \param ctx the context - */ -void dukx_load_animation(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_ANIMATION_HPP
--- a/libclient-js/malikania/js-animator.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* - * 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 <cassert> -#include <string> - -#include "js-animation.hpp" -#include "js-animator.hpp" -#include "js-point.hpp" -#include "js-window.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff""\xff""malikania-animator-ptr"); - -Animator *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Animator object"); - - return static_cast<Animator *>(ptr); -} - -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - duk_error(ctx, DUK_ERR_ERROR, "animator must be new-constructed"); - - // Be sure animation get not collected before. - dukx_new_animator(ctx, new Animator(*dukx_require_animation(ctx, 0))); - duk_push_this(ctx); - duk_dup(ctx, 0); - duk_put_prop_string(ctx, -2, "\xff""\xff""animation-ref"); - - return 0; -} - -duk_ret_t destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, Signature.c_str()); - delete static_cast<Animator *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, Signature.c_str()); - - return 0; -} - -duk_ret_t draw(duk_context *ctx) -{ - try { - self(ctx)->draw(*dukx_require_window(ctx, 0), dukx_get_point(ctx, 1)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t update(duk_context *ctx) -{ - self(ctx)->update(); - - return 0; -} - -const duk_function_list_entry methods[] = { - { "draw", draw, 2 }, - { "update", update, 0 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_new_animator(duk_context *ctx, Animator *animator) -{ - assert(ctx); - assert(animator); - - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_push_pointer(ctx, animator); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); -} - -Animator *dukx_require_animator(duk_context *ctx, duk_idx_t index) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_prop_string(ctx, index, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Animator object"); - - return static_cast<Animator *>(ptr); -} - -void dukx_load_animator(duk_context *ctx) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 1); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "Animator"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-animator.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * js-animator.hpp -- 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_HPP -#define MALIKANIA_JS_ANIMATOR_HPP - -#include "animator.hpp" -#include "duktape.hpp" - -namespace malikania { - -/** - * Construct an Animator object as this. - * - * \pre ctx != nullptr - * \pre animator != nullptr - * \param ctx the context - * \param animator the animator - */ -void dukx_new_animator(duk_context *ctx, Animator *animator); - -/** - * Get the animator at the given index. - * - * \pre ctx != nullptr - * \param ctx the context - * \param index the value index - * \return the animator - */ -Animator *dukx_require_animator(duk_context *ctx, duk_idx_t index); - -void dukx_load_animator(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_ANIMATOR_HPP
--- a/libclient-js/malikania/js-client-resources-loader.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * js-client-resources-loader.cpp -- client resources loader (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 <cassert> - -#include "js-client-resources-loader.hpp" -#include "js-resources-loader.hpp" - -namespace malikania { - -namespace { - -const std::string Variable("\xff""\xff""malikania-client-resources-loader"); - -} // !namespace - -void dukx_put_client_loader(duk_context *ctx, ClientResourcesLoader *loader) -{ - assert(ctx); - assert(loader); - - // Also store as parent. - dukx_put_loader(ctx, loader); - - StackAssert sa(ctx); - - duk_push_pointer(ctx, loader); - duk_put_global_string(ctx, Variable.c_str()); -} - -ClientResourcesLoader *dukx_get_client_loader(duk_context *ctx) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_global_string(ctx, Variable.c_str()); - auto ptr = static_cast<ClientResourcesLoader *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - - return static_cast<ClientResourcesLoader *>(ptr); -} - -} // !malikania
--- a/libclient-js/malikania/js-client-resources-loader.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * js-client-resources-loader.hpp -- client resources loader (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_CLIENT_RESOURCES_LOADER_H -#define MALIKANIA_JS_CLIENT_RESOURCES_LOADER_H - -#include "client-resources-loader.hpp" -#include "duktape.hpp" - -namespace malikania { - -void dukx_put_client_loader(duk_context *ctx, ClientResourcesLoader *); - -ClientResourcesLoader *dukx_get_client_loader(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_CLIENT_RESOURCES_LOADER_H
--- a/libclient-js/malikania/js-client-target.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * js-client-target.cpp -- client resources loader (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-client-target.hpp" - -namespace malikania { - -class JsTarget : public Client::Target { -public: - -}; - -namespace { - -duk_ret_t constructor(duk_context *ctx) -{ - return 0; -} - -duk_ret_t draw(duk_context *ctx) -{ - return 0; -} - -} // !namespace - -void dukx_load_client_target(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_get_prop_string(ctx, -1, "Client"); - duk_push_c_function(ctx, constructor, 1); - duk_push_object(ctx); - duk_put_prop_string(ctx, -1, "prototype"); - duk_put_prop_string(ctx, -2, "Target"); - duk_pop_2(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-client-target.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * js-client-target.hpp -- client resources loader (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_CLIENT_TARGET_HPP -#define MALIKANIA_JS_CLIENT_TARGET_HPP - -#include "client-target.hpp" -#include "duktape.hpp" - -namespace malikania { - -void dukx_load_client_target(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_CLIENT_TARGET_HPP
--- a/libclient-js/malikania/js-client.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * js-client.cpp -- client resources loader (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 <cassert> - -#include "js-client.hpp" -#include "js-client-target.hpp" -#include "js-window.hpp" - -namespace malikania { - -namespace { - -duk_ret_t draw(duk_context *) -{ -#if 0 - try { - duk::self<std::shared_ptr<Client>>(ctx)->draw(); - } catch (const std::exception &ex) { - duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } -#endif - - return 0; -} - -duk_ret_t setTarget(duk_context *) -{ -#if 0 - auto self = duk::self<Client *>(ctx); - auto target = duk::get<std::shared_ptr<Client::Target>>(ctx, 0); - - self->setTarget(std::move(target)); -#endif - - return 0; -} - -duk_ret_t update(duk_context *) -{ -#if 0 - try { - duk::self<std::shared_ptr<Client>>(ctx)->update(); - } catch (const std::exception &ex) { - duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } -#endif - - return 0; -} - -const duk_function_list_entry methods[] = { - { "draw", draw, 0 }, - { "setTarget", setTarget, 1 }, - { "update", update, 0 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_load_client(duk_context *ctx) -{ -#if 0 - duk::StackAssert sa(ctx); - - duk::getGlobal<void>(ctx, "Malikania"); - duk::push(ctx, duk::Object()); - duk::push(ctx, duk::Object()); - duk::TypeTraits<Window>::prototype(ctx); - duk::setPrototype(ctx, -2); - duk::put(ctx, methods); - duk::putProperty(ctx, -2, "prototype"); - duk::putProperty(ctx, -2, "Client"); - duk::pop(ctx); -#endif -} - -} // !malikania
--- a/libclient-js/malikania/js-client.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * js-client.hpp -- client resources loader (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_CLIENT_HPP -#define MALIKANIA_JS_CLIENT_HPP - -#include "client.hpp" -#include "duktape.hpp" - -namespace malikania { - -void dukx_load_client(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_CLIENT_HPP
--- a/libclient-js/malikania/js-color.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/* - * js-color.cpp -- color 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 <cassert> - -#include "js-color.hpp" -#include "util.hpp" - -namespace malikania { - -namespace { - -std::uint8_t clampComponent(duk_context *ctx, int value, bool required) -{ - if (value < 0 || value > 255) { - if (required) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d is out of range (0, 255)", value); - else - value = util::clamp(value, 0, 255); - } - - return static_cast<std::uint8_t>(value); -} - -Color parseString(duk_context *ctx, duk_idx_t index, bool required) -{ - assert(duk_is_string(ctx, index)); - - Color color; - - try { - color = Color(duk_get_string(ctx, index)); - } catch (const std::exception &ex) { - if (required) - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return color; -} - -Color parseObject(duk_context *ctx, duk_idx_t index, bool required) -{ - assert(duk_is_object(ctx, index)); - - auto require = [&] (const auto prop) -> std::uint8_t { - if (required && !duk_has_prop_string(ctx, index, prop)) - duk_error(ctx, DUK_ERR_ERROR, "missing %s property in color description", prop); - - duk_get_prop_string(ctx, index, prop); - auto comp = duk_get_int(ctx, -1); - duk_pop(ctx); - - return clampComponent(ctx, comp, required); - }; - - // Alpha is optional. - duk_get_prop_string(ctx, index, "alpha"); - auto alpha = duk_is_number(ctx, -1) ? duk_to_int(ctx, -1) : 255; - duk_pop(ctx); - - return Color( - require("red"), - require("green"), - require("blue"), - clampComponent(ctx, alpha, required) - ); -} - -Color parse(duk_context *ctx, duk_idx_t index, bool required, Color color = {}) -{ - switch (duk_get_type(ctx, index)) { - case DUK_TYPE_STRING: - color = parseString(ctx, index, required); - break; - case DUK_TYPE_OBJECT: - color = parseObject(ctx, index, required); - break; - default: - if (required) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "color (string, object) expected"); - - break; - } - - return color; -} - -duk_ret_t constructor(duk_context *ctx) -{ - Color color; - - /* - * The constructor allows an additional signature that takes 4 number - * arguments, otherwise use the literal parsing functions. - */ - if (duk_get_top(ctx) >= 3) { - // Alpha is optional. - auto alpha = duk_is_number(ctx, 3) ? duk_to_int(ctx, 3) : 255; - - color = Color( - clampComponent(ctx, duk_require_int(ctx, 0), true), - clampComponent(ctx, duk_require_int(ctx, 1), true), - clampComponent(ctx, duk_require_int(ctx, 2), true), - clampComponent(ctx, alpha, true) - ); - } else if (duk_get_top(ctx) == 1) - color = parse(ctx, 0, true); - - duk_ret_t ret; - - // Allow both constructor and non constructor calls. - if (duk_is_constructor_call(ctx)) { - duk_push_this(ctx); - dukx_put_color(ctx, color); - duk_pop(ctx); - ret = 0; - } else { - dukx_push_color(ctx, color); - ret = 1; - } - - return ret; -} - -} //! namespace - -Color dukx_get_color(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, false); -} - -Color dukx_require_color(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, true); -} - -Color dukx_optional_color(duk_context *ctx, duk_idx_t index, Color def) -{ - return parse(ctx, index, false, std::move(def)); -} - -void dukx_push_color(duk_context *ctx, const Color &color) -{ - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - dukx_put_color(ctx, color); -} - -void dukx_put_color(duk_context *ctx, const Color &color) -{ - assert(duk_is_object(ctx, -1)); - - StackAssert sa(ctx, 0); - - duk_push_uint(ctx, color.red()); - duk_put_prop_string(ctx, -2, "red"); - duk_push_uint(ctx, color.green()); - duk_put_prop_string(ctx, -2, "green"); - duk_push_uint(ctx, color.blue()); - duk_put_prop_string(ctx, -2, "blue"); - duk_push_uint(ctx, color.alpha()); - duk_put_prop_string(ctx, -2, "alpha"); -} - -void dukx_load_color(duk_context *ctx) -{ - StackAssert sa(ctx, 0); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, DUK_VARARGS); - duk_put_prop_string(ctx, -2, "Color"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-color.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * js-color.hpp -- color 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_COLOR_HPP -#define MALIKANIA_JS_COLOR_HPP - -/** - * \file js-color.h - * \brief JavaScript binding for Color. - * - * Colors can be created from plain JavaScript object. - * - * ```` - * { - * red: 0, - * green: 255, - * blue: 255, - * alpha: 255 - * } - * ```` - * - * It can also takes strings like "#rrggbbaa" and SVG names. - */ - -#include "color.hpp" -#include "duktape.hpp" - -namespace malikania { - -/** - * Get a color. - * - * May return a default value or a color with adjusted components. - * - * @param ctx the context - * @param index the index - */ -Color dukx_get_color(duk_context *ctx, duk_idx_t index); - -/** - * Require a color. - * - * If the color has any invalid component, raise a JavaScript error. - * - * @param ctx the context - * @param index the index - */ -Color dukx_require_color(duk_context *ctx, duk_idx_t index); - -/** - * Like get, but return the default value only if the value at the given - * index is not an object or not a string, otherwise, adjust invalid values. - * - * @param ctx the context - * @param index the index - * @param def the default value - */ -Color dukx_optional_color(duk_context *ctx, duk_idx_t index, Color def); - -/** - * Push the color as object. - * - * @param ctx the context - * @param color the color - */ -void dukx_push_color(duk_context *ctx, const Color &color); - -/** - * Put the color properties into the object at the top of the stack. - * - * @pre the top value must be an object - * @param ctx the context - * @param color the color - */ -void dukx_put_color(duk_context *ctx, const Color &color); - -void dukx_load_color(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_COLOR_HPP
--- a/libclient-js/malikania/js-font.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * js-font.cpp -- font 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 <cassert> - -#include "js-client-resources-loader.hpp" -#include "js-font.hpp" -#include "js-size.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff""\xff""malikania-font-ptr"); - -Font *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Font object"); - - return static_cast<Font *>(ptr); -} - -duk_ret_t constructor(duk_context *ctx) -{ - StackAssert sa(ctx); - - if (!duk_is_constructor_call(ctx)) - duk_error(ctx, DUK_ERR_ERROR, "font must be new-constructed"); - - try { - auto loader = dukx_get_client_loader(ctx); - auto id = duk_require_string(ctx, 0); - auto size = duk_require_int(ctx, 1); - - if (size < 0) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d must not be negative", size); - - dukx_new_font(ctx, new Font(loader->loadFont(id, static_cast<unsigned>(size)))); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t clip(duk_context *ctx) -{ - try { - dukx_push_size(ctx, self(ctx)->clip(duk_require_string(ctx, 0))); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 1; -} - -const duk_function_list_entry methods[] = { - { "clip", clip, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_new_font(duk_context *ctx, Font *font) -{ - assert(ctx); - assert(font); - - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_push_pointer(ctx, font); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); -} - -Font *dukx_require_font(duk_context *ctx, duk_idx_t index) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_prop_string(ctx, index, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Font object"); - - return static_cast<Font *>(ptr); -} - -void dukx_load_font(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 2); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "Font"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-font.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * js-font.hpp -- font 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_FONT_HPP -#define MALIKANIA_JS_FONT_HPP - -#include "duktape.hpp" -#include "font.hpp" - -namespace malikania { - -void dukx_new_font(duk_context *ctx, Font *font); - -Font *dukx_require_font(duk_context *ctx, duk_idx_t index); - -void dukx_load_font(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_FONT_HPP
--- a/libclient-js/malikania/js-image.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * 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 "js-client-resources-loader.hpp" -#include "js-image.hpp" -#include "js-point.hpp" -#include "js-rectangle.hpp" -#include "js-size.hpp" -#include "js-window.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff""\xff""malikania-image-ptr"); - -Image *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Animator object"); - - return static_cast<Image *>(ptr); -} - -duk_ret_t size(duk_context *ctx) -{ - try { - dukx_push_size(ctx, self(ctx)->size()); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 1; -} - -duk_ret_t draw(duk_context *ctx) -{ - try { - auto image = self(ctx); - auto window = dukx_require_window(ctx, 0); - - if (duk_get_top(ctx) == 2) - image->draw(*window, dukx_get_point(ctx, 1)); - else if (duk_get_top(ctx) == 3) - image->draw(*window, dukx_get_rect(ctx, 1), dukx_get_rect(ctx, 2)); - else - duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid number of arguments: #%d", duk_get_top(ctx)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - duk_error(ctx, DUK_ERR_ERROR, "image must be new-constructed"); - - try { - auto loader = dukx_get_client_loader(ctx); - auto image = new Image(loader->loadImage(duk_require_string(ctx, 0))); - - dukx_new_image(ctx, image); - duk_push_this(ctx); - duk_push_string(ctx, "size"); - duk_push_c_function(ctx, size, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - duk_pop(ctx); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -const duk_function_list_entry methods[] = { - { "draw", draw, DUK_VARARGS }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_new_image(duk_context *ctx, Image *image) -{ - assert(ctx); - assert(image); - - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_push_pointer(ctx, image); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); -} - -void dukx_load_image(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 1); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "Image"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-image.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * js-image.hpp -- 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_HPP -#define MALIKANIA_JS_IMAGE_HPP - -#include "duktape.hpp" -#include "image.hpp" - -namespace malikania { - -void dukx_new_image(duk_context *ctx, Image *image); - -void dukx_load_image(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_IMAGE_HPP
--- a/libclient-js/malikania/js-line.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* - * js-line.cpp -- line 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 <cassert> - -#include "js-line.hpp" - -namespace malikania { - -namespace { - -duk_ret_t constructor(duk_context *ctx) -{ - Line line; - - if (duk_get_top(ctx) == 4) { - line = Line( - duk_get_int(ctx, 0), - duk_get_int(ctx, 1), - duk_get_int(ctx, 2), - duk_get_int(ctx, 3) - ); - } else if (duk_get_top(ctx) == 1) - line = dukx_require_line(ctx, 0); - - duk_ret_t ret; - - /* Allow both constructor and non constructor calls */ - if (duk_is_constructor_call(ctx)) { - duk_push_this(ctx); - dukx_put_line(ctx, line); - ret = 0; - } else { - dukx_push_line(ctx, line); - ret = 1; - } - - return ret; -} - -} // !namespace - -Line dukx_get_line(duk_context *ctx, duk_idx_t index) -{ - auto get = [&] (auto name) { - StackAssert sa(ctx); - - duk_get_prop_string(ctx, index, name); - auto v = duk_get_int(ctx, -1); - duk_pop(ctx); - - return v; - }; - - return Line(get("x1"), get("y1"), get("x2"), get("y2")); -} - -Line dukx_require_line(duk_context *ctx, duk_idx_t index) -{ - auto get = [&] (auto prop) { - if (!duk_has_prop_string(ctx, index, prop)) - duk_error(ctx, DUK_ERR_ERROR, "missing %s property in line description", prop); - - duk_get_prop_string(ctx, index, prop); - - if (!duk_is_number(ctx, -1)) { - duk_pop(ctx); - duk_error(ctx, DUK_ERR_TYPE_ERROR, "property %s is not an int", prop); - } - - auto value = duk_to_int(ctx, -1); - - duk_pop(ctx); - - return value; - }; - - return Line(get("x1"), get("y1"), get("x2"), get("y2")); -} - -Line dukx_optional_line(duk_context *ctx, duk_idx_t index, Line def) -{ - return duk_is_object(ctx, index) ? dukx_get_line(ctx, index) : def; -} - -void dukx_push_line(duk_context *ctx, const Line &line) -{ - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - dukx_put_line(ctx, line); -} - -void dukx_put_line(duk_context *ctx, const Line &line) -{ - assert(duk_is_object(ctx, -1)); - - StackAssert sa(ctx); - - duk_push_int(ctx, line.x1()); - duk_put_prop_string(ctx, -2, "x1"); - duk_push_int(ctx, line.y1()); - duk_put_prop_string(ctx, -2, "y1"); - duk_push_int(ctx, line.x2()); - duk_put_prop_string(ctx, -2, "x2"); - duk_push_int(ctx, line.y2()); - duk_put_prop_string(ctx, -2, "y2"); -} - -void dukx_load_line(duk_context *ctx) -{ - StackAssert sa(ctx, 0); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, DUK_VARARGS); - duk_put_prop_string(ctx, -2, "Line"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-line.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * js-line.hpp -- line 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_LINE_HPP -#define MALIKANIA_JS_LINE_HPP - -/** - * \file js-line.h - * \brief JavaScript binding for Line. - * - * Lines are plain objects. - * - * ```` - * { - * x1: 10, - * y1: 10, - * x2: 50, - * y2: 50 - * } - * ```` - */ - -#include "duktape.hpp" -#include "line.hpp" - -namespace malikania { - -/** - * Get a line. - * - * @param ctx the context - * @param index the index - * @return the line - */ -Line dukx_get_line(duk_context *ctx, duk_idx_t index); - -/** - * Require a line. - * - * If value is not an object or any property is invalid, raise a JavaScript error. - * - * @param ctx the context - * @param index the index - * @return the line - */ -Line dukx_require_line(duk_context *ctx, duk_idx_t index); - -/** - * Like get but return def if the value at the given index is not an object. - * - * @param ctx the context - * @param index the index - * @param def the default value - * @return the line - */ -Line dukx_optional_line(duk_context *ctx, duk_idx_t index, Line def); - -/** - * Push the line as object. - * - * @param ctx the context - * @param line the line - */ -void dukx_push_line(duk_context *ctx, const Line &line); - -/** - * Put the line properties into the object at the top of the stack. - * - * @param ctx the context - * @param line the line - */ -void dukx_put_line(duk_context *ctx, const Line &line); - -void dukx_load_line(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_LINE_HPP
--- a/libclient-js/malikania/js-point.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * js-point.cpp -- point 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 <cassert> - -#include "js-point.hpp" - -namespace malikania { - -namespace { - -Point parse(duk_context *ctx, duk_idx_t index, bool required, Point point = {}) -{ - StackAssert sa(ctx); - - if (duk_is_object(ctx, index)) { - if (required && !duk_has_prop_string(ctx, index, "x")) - duk_error(ctx, DUK_ERR_ERROR, "missing x property in point description"); - else if (required && !duk_has_prop_string(ctx, index, "y")) - duk_error(ctx, DUK_ERR_ERROR, "missing y property in point description"); - - //point = Point(duk::getProperty<int>(ctx, index, "x"), duk::getProperty<int>(ctx, index, "y")); - int x; - int y; - - duk_get_prop_string(ctx, index, "x"); - x = duk_to_int(ctx, -1); - duk_pop(ctx); - duk_get_prop_string(ctx, index, "y"); - y = duk_to_int(ctx, -1); - duk_pop(ctx); - - point = Point(x, y); - } else if (required) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "point object expected"); - - return point; -} - -duk_ret_t constructor(duk_context *ctx) -{ - Point point; - - if (duk_get_top(ctx) == 2) - point = Point(duk_require_int(ctx, 0), duk_require_int(ctx, 1)); - else if (duk_get_top(ctx) == 1) - point = parse(ctx, 0, true); - - duk_ret_t ret; - - // Allow both constructor and non constructor calls. - if (duk_is_constructor_call(ctx)) { - duk_push_this(ctx); - dukx_put_point(ctx, point); - duk_pop(ctx); - ret = 0; - } else { - dukx_push_point(ctx, point); - ret = 1; - } - - return ret; -} - -} // !namespace - -Point dukx_get_point(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, false); -} - -Point dukx_require_point(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, true); -} - -Point dukx_optional_point(duk_context *ctx, duk_idx_t index, Point def) -{ - return parse(ctx, index, false, std::move(def)); -} - -void dukx_push_point(duk_context *ctx, const Point &point) -{ - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - dukx_put_point(ctx, point); -} - -void dukx_put_point(duk_context *ctx, const Point &point) -{ - assert(duk_is_object(ctx, -1)); - - StackAssert sa(ctx); - - duk_push_int(ctx, point.x()); - duk_put_prop_string(ctx, -2, "x"); - duk_push_int(ctx, point.y()); - duk_put_prop_string(ctx, -2, "y"); -} - -void dukx_load_point(duk_context *ctx) -{ - StackAssert sa(ctx, 0); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, DUK_VARARGS); - duk_put_prop_string(ctx, -2, "Point"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-point.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * js-point.hpp -- point 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_POINT_HPP -#define MALIKANIA_JS_POINT_HPP - -#include "duktape.hpp" -#include "point.hpp" - -namespace malikania { - -Point dukx_require_point(duk_context *ctx, duk_idx_t index); - -Point dukx_get_point(duk_context *ctx, duk_idx_t index); - -void dukx_push_point(duk_context *ctx, const Point &point); - -void dukx_put_point(duk_context *ctx, const Point &point); - -void dukx_load_point(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_POINT_HPP
--- a/libclient-js/malikania/js-rectangle.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * js-rectangle.cpp -- rectangle 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 <cassert> - -#include "js-rectangle.hpp" - -namespace malikania { - -namespace { - -unsigned clamp(duk_context *ctx, int value, bool required) -{ - if (value < 0) { - if (required) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d can not be negative", value); - else - value = 0; - } - - return static_cast<unsigned>(value); -} - -Rectangle parse(duk_context *ctx, duk_idx_t index, bool required, Rectangle rect = {}) -{ - StackAssert sa(ctx); - - if (duk_is_object(ctx, index)) { - auto get = [&] (auto prop) { - if (required && !duk_has_prop_string(ctx, index, prop)) - duk_error(ctx, DUK_ERR_ERROR, "missing '%s' property", prop); - - duk_get_prop_string(ctx, index, prop); - - if (required && !duk_is_number(ctx, -1)) { - duk_pop(ctx); - duk_error(ctx, DUK_ERR_ERROR, "invalid '%s' property (number expected)", prop); - } - - auto value = duk_to_int(ctx, -1); - - duk_pop(ctx); - - return value; - }; - - rect = Rectangle(get("x"), get("y"), - clamp(ctx, get("width"), required), clamp(ctx, get("height"), required)); - } else if (required) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "rectangle object expected"); - - return rect; -} - -duk_ret_t constructor(duk_context *ctx) -{ - Rectangle rect; - - if (duk_get_top(ctx) == 4) { - rect = Rectangle( - duk_require_int(ctx, 0), - duk_require_int(ctx, 1), - clamp(ctx, duk_require_int(ctx, 2), true), - clamp(ctx, duk_require_int(ctx, 3), true) - ); - } else if (duk_get_top(ctx) == 1) - rect = parse(ctx, 0, true); - - duk_ret_t ret; - - // Allow both constructor and non constructor calls. - if (duk_is_constructor_call(ctx)) { - duk_push_this(ctx); - dukx_put_rect(ctx, rect); - duk_pop(ctx); - ret = 0; - } else { - dukx_push_rect(ctx, rect); - ret = 1; - } - - return ret; -} - -} // !namespace - -Rectangle dukx_get_rect(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, false); -} - -Rectangle dukx_require_rect(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, true); -} - -Rectangle dukx_optional_rect(duk_context *ctx, duk_idx_t index, Rectangle def) -{ - return parse(ctx, index, false, std::move(def)); -} - -void dukx_push_rect(duk_context *ctx, const Rectangle &rect) -{ - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - dukx_put_rect(ctx, rect); -} - -void dukx_put_rect(duk_context *ctx, const Rectangle &rect) -{ - assert(duk_is_object(ctx, -1)); - - StackAssert sa(ctx); - - duk_push_int(ctx, rect.x()); - duk_put_prop_string(ctx, -2, "x"); - duk_push_int(ctx, rect.y()); - duk_put_prop_string(ctx, -2, "y"); - duk_push_uint(ctx, rect.width()); - duk_put_prop_string(ctx, -2, "width"); - duk_push_uint(ctx, rect.height()); - duk_put_prop_string(ctx, -2, "height"); -} - -void dukx_load_rect(duk_context *ctx) -{ - StackAssert sa(ctx, 0); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, DUK_VARARGS); - duk_put_prop_string(ctx, -2, "Rectangle"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-rectangle.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * js-rectangle.hpp -- rectangle 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_RECTANGLE_HPP -#define MALIKANIA_JS_RECTANGLE_HPP - -/** - * \file js-rectangle.hpp - * \brief JavaScript binding for Rectangle. - * - * Rectangles are plain objects. - * - * ```` - * { - * x: 10, - * y: 20, - * width: 100, - * height: 200 - * } - * ```` - */ - -#include "duktape.hpp" -#include "rectangle.hpp" - -namespace malikania { - -/** - * Get a rectangle. - * - * The rectangle may be adjusted if any values are incorrect. - * - * @param ctx the context - * @param index the value index - * @return the rectangle - */ -Rectangle dukx_get_rect(duk_context *ctx, duk_idx_t index); - -/** - * Require a rectangle. - * - * If the object is not a rectangle or if width, height are invalid, raise a JavaScript error. - * - * @param ctx the context - * @param index the index - * @return the rectangle - */ -Rectangle dukx_require_rect(duk_context *ctx, duk_idx_t index); - -/** - * Like get but return the default value if the value at the given index is not an object or invalid - * - * @param ctx the context - * @param index the idnex - * @param def the default value - * @return the rectangle - */ -Rectangle dukx_optional_rect(duk_context *ctx, duk_idx_t index, Rectangle def); - -/** - * Push the rectangle as object. - * - * @param ctx the context - * @param rect the rectangle - */ -void dukx_push_rect(duk_context *ctx, const Rectangle &rect); - -/** - * Put the rectangle properties into the object at the top of the stack. - * - * @param ctx the context - * @param rect the rectangle - */ -void dukx_put_rect(duk_context *ctx, const Rectangle &rect); - -void dukx_load_rect(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_RECTANGLE_HPP
--- a/libclient-js/malikania/js-size.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -/* - * js-size.cpp -- size 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 <cassert> - -#include "js-size.hpp" - -namespace malikania { - -namespace { - -Size parse(duk_context *ctx, duk_idx_t index, bool required, Size size = {}) -{ - StackAssert sa(ctx); - - if (duk_is_object(ctx, index)) { - if (required && !duk_has_prop_string(ctx, index, "width")) - duk_error(ctx, DUK_ERR_ERROR, "missing width property in size description"); - else if (required && !duk_has_prop_string(ctx, index, "height")) - duk_error(ctx, DUK_ERR_ERROR, "missing height property in size description"); - - int width; - int height; - - duk_get_prop_string(ctx, index, "width"); - width = duk_to_int(ctx, -1); - duk_pop(ctx); - duk_get_prop_string(ctx, index, "height"); - height = duk_to_int(ctx, -1); - duk_pop(ctx); - - if (width < 0) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "width can not be negative"); - if (height < 0) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "height can not be negative"); - - size = Size(width, height); - } else if (required) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "size object expected"); - - return size; -} - -duk_ret_t constructor(duk_context *ctx) -{ - Size size; - - if (duk_get_top(ctx) == 2) { - int width; - int height; - - if ((width = duk_require_int(ctx, 0)) < 0) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument #0 can not be negative"); - if ((height = duk_require_int(ctx, 1)) < 0) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument #1 can not be negative"); - - size = Size(static_cast<unsigned>(width), static_cast<unsigned>(height)); - } else if (duk_get_top(ctx) == 1) - size = parse(ctx, 0, true); - - duk_ret_t ret; - - // Allow both constructor and non constructor calls. - if (duk_is_constructor_call(ctx)) { - duk_push_this(ctx); - dukx_put_size(ctx, size); - duk_pop(ctx); - ret = 0; - } else { - dukx_push_size(ctx, size); - ret = 1; - } - - return ret; -} - -} // !namespace - -Size dukx_get_size(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, false); -} - -Size dukx_require_size(duk_context *ctx, duk_idx_t index) -{ - return parse(ctx, index, true); -} - -Size dukx_optional_size(duk_context *ctx, duk_idx_t index, Size def) -{ - return parse(ctx, index, false, std::move(def)); -} - -void dukx_push_size(duk_context *ctx, const Size &size) -{ - StackAssert sa(ctx, 1); - - duk_push_object(ctx); - dukx_put_size(ctx, size); -} - -void dukx_put_size(duk_context *ctx, const Size &size) -{ - assert(duk_is_object(ctx, -1)); - - StackAssert sa(ctx, 0); - - duk_push_uint(ctx, size.width()); - duk_put_prop_string(ctx, -2, "width"); - duk_push_uint(ctx, size.height()); - duk_put_prop_string(ctx, -2, "height"); -} - -void dukx_load_size(duk_context *ctx) -{ - StackAssert sa(ctx, 0); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, DUK_VARARGS); - duk_put_prop_string(ctx, -2, "Size"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-size.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * js-size.hpp -- size 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_SIZE_HPP -#define MALIKANIA_JS_SIZE_HPP - -/** - * \file js-size.h - * \brief JavaScript binding for Size. - * - * Size are plain objects. - * - * ```` - * { - * width: 1000, - * height: 2000 - * } - * ```` - */ - -#include "duktape.hpp" -#include "size.hpp" - -namespace malikania { - -/** - * Get a size. - * - * The size may be adjusted if any values are incorrect. - * - * @param ctx the context - * @param index the value index - * @return the size - */ -Size dukx_get_size(duk_context *ctx, duk_idx_t index); - -/** - * Require a size - * - * If the object is not a size, raise a JavaScript error. - * - * @param ctx the context - * @param index the index - * @return the size - */ -Size dukx_require_size(duk_context *ctx, duk_idx_t index); - -/** - * Like get but return the default value if the value at the given index is not an object. - * - * @param ctx the context - * @param index the idnex - * @param def the default value - * @return the size - */ -Size dukx_optional_size(duk_context *ctx, duk_idx_t index, Size def); - -/** - * Push the size as object. - * - * @param ctx the context - * @param size the size - */ -void dukx_push_size(duk_context *ctx, const Size &size); - -/** - * Put the size properties into the object at the top of the stack. - * - * @param ctx the context - * @param size the size - */ -void dukx_put_size(duk_context *ctx, const Size &size); - -void dukx_load_size(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_SIZE_HPP
--- a/libclient-js/malikania/js-sprite.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/* - * 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 "js-client-resources-loader.hpp" -#include "js-point.hpp" -#include "js-size.hpp" -#include "js-sprite.hpp" -#include "js-window.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff""\xff""malikania-sprite-ptr"); - -Sprite *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Sprite object"); - - return static_cast<Sprite *>(ptr); -} - -duk_ret_t cell(duk_context *ctx) -{ - dukx_push_size(ctx, self(ctx)->cell()); - - return 1; -} - -duk_ret_t columns(duk_context *ctx) -{ - duk_push_uint(ctx, self(ctx)->columns()); - - return 1; -} - -duk_ret_t margins(duk_context *ctx) -{ - dukx_push_size(ctx, self(ctx)->margin()); - - return 1; -} - -duk_ret_t rows(duk_context *ctx) -{ - duk_push_uint(ctx, self(ctx)->rows()); - - return 1; -} - -duk_ret_t space(duk_context *ctx) -{ - dukx_push_size(ctx, self(ctx)->space()); - - return 1; -} - -duk_ret_t constructor(duk_context *ctx) -{ - if (!duk_is_constructor_call(ctx)) - duk_error(ctx, DUK_ERR_ERROR, "sprite must be new-constructed"); - - try { - auto loader = dukx_get_client_loader(ctx); - auto sprite = loader->loadSprite(duk_require_string(ctx, 0)); - - duk_push_this(ctx); - duk_push_pointer(ctx, new Sprite(std::move(sprite))); - duk_put_prop_string(ctx, -2, Signature.c_str()); - - // Cell. - duk_push_string(ctx, "cell"); - duk_push_c_function(ctx, cell, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - - // Columns. - duk_push_string(ctx, "columns"); - duk_push_c_function(ctx, columns, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - - // Margins. - duk_push_string(ctx, "margins"); - duk_push_c_function(ctx, margins, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - - // Rows. - duk_push_string(ctx, "rows"); - duk_push_c_function(ctx, rows, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - - // Space. - duk_push_string(ctx, "space"); - duk_push_c_function(ctx, space, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - - duk_pop(ctx); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t draw(duk_context *ctx) -{ - try { - auto sprite = self(ctx); - auto window = dukx_require_window(ctx, 0); - auto cell = duk_require_uint(ctx, 1); - auto point = dukx_get_point(ctx, 2); - - if (cell >= (sprite->rows() * sprite->columns())) - duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d is out of range", cell); - - sprite->draw(*window, cell, point); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -const duk_function_list_entry methods[] = { - { "draw", draw, 3 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_load_sprite(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 1); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "Sprite"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-sprite.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * js-sprite.hpp -- 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_HPP -#define MALIKANIA_JS_SPRITE_HPP - -#include "duktape.hpp" -#include "sprite.hpp" - -namespace malikania { - -void dukx_load_sprite(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_SPRITE_HPP
--- a/libclient-js/malikania/js-window.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,284 +0,0 @@ -/* - * js-window.cpp -- window management (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 <cassert> - -#include "js-color.hpp" -#include "js-font.hpp" -#include "js-line.hpp" -#include "js-point.hpp" -#include "js-rectangle.hpp" -#include "js-window.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff""\xff""malikania-window-ptr"); -const std::string Prototype("\xff""\xff""malikania-window-prototype"); - -Window *self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Window object"); - - return static_cast<Window *>(ptr); -} - -duk_ret_t constructor(duk_context *ctx) -{ - StackAssert sa(ctx); - - if (!duk_is_constructor_call(ctx)) - duk_error(ctx, DUK_ERR_ERROR, "window must be new-constructed"); - - // TODO: add parameters. - try { - auto win = new Window; - - duk_push_this(ctx); - duk_push_pointer(ctx, win); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t clear(duk_context *ctx) -{ - try { - self(ctx)->clear(); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t present(duk_context *ctx) -{ - try { - self(ctx)->present(); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawingColor(duk_context *ctx) -{ - try { - dukx_push_color(ctx, self(ctx)->drawingColor()); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 1; -} - -duk_ret_t drawLine(duk_context *ctx) -{ - try { - self(ctx)->drawLine(dukx_require_line(ctx, 0)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawLines(duk_context *ctx) -{ - try { - self(ctx)->drawLines(dukx_get_array(ctx, 0, dukx_get_point)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawPoint(duk_context *ctx) -{ - try { - self(ctx)->drawPoint(dukx_require_point(ctx, 0)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawPoints(duk_context *ctx) -{ - try { - self(ctx)->drawPoints(dukx_get_array(ctx, 0, dukx_get_point)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawRectangle(duk_context *ctx) -{ - try { - self(ctx)->drawRectangle(dukx_require_rect(ctx, 0)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawRectangles(duk_context *ctx) -{ - try { - self(ctx)->drawRectangles(dukx_get_array(ctx, 0, dukx_get_rect)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t drawText(duk_context *ctx) -{ - try { - auto win = self(ctx); - auto text = duk_require_string(ctx, 0); - auto font = dukx_require_font(ctx, 1); - auto rect = dukx_get_rect(ctx, 2); - - if (!rect.isNull()) - win->drawText(text, *font, rect); - else - win->drawText(text, *font, Point(rect.x(), rect.y())); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t fillRectangle(duk_context *ctx) -{ - try { - self(ctx)->fillRectangle(dukx_require_rect(ctx, 0)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t fillRectangles(duk_context *ctx) -{ - try { - self(ctx)->fillRectangles(dukx_get_array(ctx, 0, dukx_get_rect)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -duk_ret_t setDrawingColor(duk_context *ctx) -{ - try { - self(ctx)->setDrawingColor(dukx_require_color(ctx, 0)); - } catch (const std::exception &ex) { - duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); - } - - return 0; -} - -const duk_function_list_entry methods[] = { - { "clear", clear, 0 }, - { "drawingColor", drawingColor, 0 }, - { "drawLine", drawLine, 1 }, - { "drawLines", drawLines, 1 }, - { "drawPoint", drawPoint, 1 }, - { "drawPoints", drawPoints, 1 }, - { "drawRectangle", drawRectangle, 1 }, - { "drawRectangles", drawRectangles, 1 }, - { "drawText", drawText, 3 }, - { "fillRectangle", fillRectangle, 1 }, - { "fillRectangles", fillRectangles, 1 }, - { "present", present, 0 }, - { "setDrawingColor", setDrawingColor, 1 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_new_window(duk_context *ctx, Window *window) -{ - assert(ctx); - assert(window); - - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_push_pointer(ctx, window); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); -} - -Window *dukx_require_window(duk_context *ctx, duk_idx_t index) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_prop_string(ctx, index, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Window object"); - - return static_cast<Window *>(ptr); -} - -void dukx_load_window(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 0); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "Window"); - duk_pop(ctx); -} - -} // !malikania
--- a/libclient-js/malikania/js-window.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * js-window.hpp -- window management (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_WINDOW_HPP -#define MALIKANIA_JS_WINDOW_HPP - -#include "duktape.hpp" -#include "window.hpp" - -namespace malikania { - -Window *dukx_require_window(duk_context *ctx, duk_idx_t index); - -void dukx_load_window(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_WINDOW_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_animation.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,108 @@ +/* + * 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 <cassert> + +#include "js_client_resources_loader.hpp" +#include "js_animation.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff""\xff""malikania-animation-ptr"); + +duk_ret_t constructor(duk_context* ctx) +{ + if (!duk_is_constructor_call(ctx)) { + duk_error(ctx, DUK_ERR_ERROR, "animation must be new-constructed"); + } + + try { + auto& loader = dukx_get_client_loader(ctx); + auto anim = loader.load_animation(duk_require_string(ctx, 0)); + + duk_push_this(ctx); + duk_push_pointer(ctx, new animation(std::move(anim))); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t destructor(duk_context* ctx) +{ + duk_get_prop_string(ctx, 0, signature.c_str()); + delete static_cast<animation *>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, signature.c_str()); + + return 0; +} + +} // !namespace + +void dukx_new_animation(duk_context* ctx, animation& anim) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, new animation(std::move(anim))); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); +} + +animation& dukx_require_animation(duk_context* ctx, duk_idx_t index) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_prop_string(ctx, index, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an animation object"); + } + + return *static_cast<animation*>(ptr); +} + +void dukx_load_animation(duk_context* ctx) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 1); + duk_push_object(ctx); + duk_push_c_function(ctx, destructor, 1); + duk_set_finalizer(ctx, -2); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "Animation"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_animation.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,60 @@ +/* + * js_animation.hpp -- 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_HPP +#define MALIKANIA_JS_ANIMATION_HPP + +#include <malikania/duktape.hpp> + +#include "animation.hpp" + +namespace malikania { + +#if 0 +/** + * Construct an animation object as this. + * + * \pre ctx != nullptr + * \pre animation != nullptr + * \param ctx the context + * \param animation the animation + */ +void dukx_new_animation(duk_context* ctx, animation* animation); +#endif + +/** + * Get an animation object at the given index or raise a Javascript error. + * + * \pre ctx != nullptr + * \param ctx the context + * \param index the value index + * \return the Animation object + */ +animation& dukx_require_animation(duk_context* ctx, duk_idx_t index); + +/** + * Load the animation module into the context. + * + * \pre ctx != nullptr + * \param ctx the context + */ +void dukx_load_animation(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_ANIMATION_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_animator.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,153 @@ +/* + * 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 <cassert> +#include <string> + +#include "js_animation.hpp" +#include "js_animator.hpp" +#include "js_point.hpp" +#include "js_window.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff""\xff""malikania-animator-ptr"); + +animator& self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an animator object"); + } + + return *static_cast<animator*>(ptr); +} + +duk_ret_t constructor(duk_context *ctx) +{ + if (!duk_is_constructor_call(ctx)) { + duk_error(ctx, DUK_ERR_ERROR, "animator must be new-constructed"); + } + + duk_push_this(ctx); + duk_push_pointer(ctx, new animator(dukx_require_animation(ctx, 0))); + duk_put_prop_string(ctx, -2, signature.c_str()); + + // Be sure animation get not collected before. + duk_dup(ctx, 0); + duk_put_prop_string(ctx, -2, "\xff""\xff""animation-ref"); + duk_pop(ctx); + + return 0; +} + +duk_ret_t destructor(duk_context *ctx) +{ + duk_get_prop_string(ctx, 0, signature.c_str()); + delete static_cast<animator *>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, signature.c_str()); + + return 0; +} + +duk_ret_t draw(duk_context *ctx) +{ + try { + self(ctx).draw(dukx_require_window(ctx, 0), dukx_get_point(ctx, 1)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t update(duk_context *ctx) +{ + self(ctx).update(); + + return 0; +} + +const duk_function_list_entry methods[] = { + { "draw", draw, 2 }, + { "update", update, 0 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +#if 0 + +void dukx_new_animator(duk_context* ctx, animator& ator) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, new animator); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); +} + +#endif + +animator& dukx_require_animator(duk_context* ctx, duk_idx_t index) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_prop_string(ctx, index, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an animator object"); + } + + return *static_cast<animator*>(ptr); +} + +void dukx_load_animator(duk_context* ctx) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 1); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_push_c_function(ctx, destructor, 1); + duk_set_finalizer(ctx, -2); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "Animator"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_animator.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,55 @@ +/* + * js_animator.hpp -- 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_HPP +#define MALIKANIA_JS_ANIMATOR_HPP + +#include "animator.hpp" +#include "duktape.hpp" + +namespace malikania { + +#if 0 + +/** + * Construct an animator object as this. + * + * \pre ctx != nullptr + * \pre animator != nullptr + * \param ctx the context + * \param animator the animator + */ +void dukx_new_animator(duk_context* ctx, animator ator); + +#endif + +/** + * Get the animator at the given index. + * + * \pre ctx != nullptr + * \param ctx the context + * \param index the value index + * \return the animator + */ +animator& dukx_require_animator(duk_context* ctx, duk_idx_t index); + +void dukx_load_animator(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_ANIMATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_client.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,93 @@ +/* +* js-client.cpp -- client resources loader (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 <cassert> + +#include "js_client.hpp" +#include "js_client-target.hpp" +#include "js_window.hpp" + +namespace malikania { + +namespace { + +duk_ret_t draw(duk_context*) +{ +#if 0 + try { + duk::self<std::shared_ptr<Client>>(ctx)->draw(); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } +#endif + + return 0; +} + +duk_ret_t setTarget(duk_context*) +{ +#if 0 + auto self = duk::self<Client*>(ctx); + auto target = duk::get<std::shared_ptr<Client::Target>>(ctx, 0); + + self->setTarget(std::move(target)); +#endif + + return 0; +} + +duk_ret_t update(duk_context*) +{ +#if 0 + try { + duk::self<std::shared_ptr<Client>>(ctx)->update(); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } +#endif + + return 0; +} + +const duk_function_list_entry methods[] = { + { "draw", draw, 0 }, + { "setTarget", setTarget, 1 }, + { "update", update, 0 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +void dukx_load_client(duk_context* ctx) +{ +#if 0 + duk::StackAssert sa(ctx); + + duk::getGlobal<void>(ctx, "Malikania"); + duk::push(ctx, duk::Object()); + duk::push(ctx, duk::Object()); + duk::TypeTraits<Window>::prototype(ctx); + duk::setPrototype(ctx, -2); + duk::put(ctx, methods); + duk::putProperty(ctx, -2, "prototype"); + duk::putProperty(ctx, -2, "Client"); + duk::pop(ctx); +#endif +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_client.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,31 @@ +/* + * js-client.hpp -- client resources loader (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_CLIENT_HPP +#define MALIKANIA_JS_CLIENT_HPP + +#include "client.hpp" +#include "duktape.hpp" + +namespace malikania { + +void dukx_load_client(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_CLIENT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_client_resources_loader.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,58 @@ +/* + * js_client_resources_loader.cpp -- client resources loader (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 <cassert> + +#include "js_client_resources_loader.hpp" +#include "js_resources_loader.hpp" + +namespace malikania { + +namespace { + +const std::string variable("\xff""\xff""malikania-client-resources-loader"); + +} // !namespace + +void dukx_put_client_loader(duk_context* ctx, client_resources_loader& loader) +{ + assert(ctx); + + // Also store as parent. + dukx_put_loader(ctx, loader); + + StackAssert sa(ctx); + + duk_push_pointer(ctx, &loader); + duk_put_global_string(ctx, variable.c_str()); +} + +client_resources_loader& dukx_get_client_loader(duk_context* ctx) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_global_string(ctx, variable.c_str()); + auto ptr = static_cast<client_resources_loader*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + + return *static_cast<client_resources_loader*>(ptr); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_client_resources_loader.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,33 @@ +/* + * js_client_resources_loader.hpp -- client resources loader (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_CLIENT_RESOURCES_LOADER_H +#define MALIKANIA_JS_CLIENT_RESOURCES_LOADER_H + +#include "client_resources_loader.hpp" +#include "duktape.hpp" + +namespace malikania { + +void dukx_put_client_loader(duk_context* ctx, client_resources_loader&); + +client_resources_loader& dukx_get_client_loader(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_CLIENT_RESOURCES_LOADER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_client_target.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,55 @@ +/* + * js-client-target.cpp -- client resources loader (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-client-target.hpp" + +namespace malikania { + +class JsTarget : public Client::Target { +public: + +}; + +namespace { + +duk_ret_t constructor(duk_context *ctx) +{ + return 0; +} + +duk_ret_t draw(duk_context *ctx) +{ + return 0; +} + +} // !namespace + +void dukx_load_client_target(duk_context *ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_get_prop_string(ctx, -1, "Client"); + duk_push_c_function(ctx, constructor, 1); + duk_push_object(ctx); + duk_put_prop_string(ctx, -1, "prototype"); + duk_put_prop_string(ctx, -2, "Target"); + duk_pop_2(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_client_target.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,31 @@ +/* + * js-client-target.hpp -- client resources loader (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_CLIENT_TARGET_HPP +#define MALIKANIA_JS_CLIENT_TARGET_HPP + +#include "client-target.hpp" +#include "duktape.hpp" + +namespace malikania { + +void dukx_load_client_target(duk_context *ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_CLIENT_TARGET_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_color.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,196 @@ +/* + * js_color.cpp -- color 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 <cassert> + +#include "js_color.hpp" +#include "util.hpp" + +namespace malikania { + +namespace { + +std::uint8_t clamp_component(duk_context* ctx, int value, bool required) +{ + if (value < 0 || value > 255) { + if (required) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d is out of range (0, 255)", value); + } else { + value = util::clamp(value, 0, 255); + } + } + + return static_cast<std::uint8_t>(value); +} + +color parse_string(duk_context* ctx, duk_idx_t index, bool required) +{ + assert(duk_is_string(ctx, index)); + + color ret; + + try { + ret = color(duk_get_string(ctx, index)); + } catch (const std::exception &ex) { + if (required) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + } + + return ret; +} + +color parse_object(duk_context* ctx, duk_idx_t index, bool required) +{ + assert(duk_is_object(ctx, index)); + + auto require = [&] (const auto prop) -> std::uint8_t { + if (required && !duk_has_prop_string(ctx, index, prop)) { + duk_error(ctx, DUK_ERR_ERROR, "missing %s property in color description", prop); + } + + duk_get_prop_string(ctx, index, prop); + auto comp = duk_get_int(ctx, -1); + duk_pop(ctx); + + return clamp_component(ctx, comp, required); + }; + + // Alpha is optional. + duk_get_prop_string(ctx, index, "alpha"); + auto alpha = duk_is_number(ctx, -1) ? duk_to_int(ctx, -1) : 255; + duk_pop(ctx); + + return color( + require("red"), + require("green"), + require("blue"), + clamp_component(ctx, alpha, required) + ); +} + +color parse(duk_context* ctx, duk_idx_t index, bool required, color ret = {}) +{ + switch (duk_get_type(ctx, index)) { + case DUK_TYPE_STRING: + ret = parse_string(ctx, index, required); + break; + case DUK_TYPE_OBJECT: + ret = parse_object(ctx, index, required); + break; + default: + if (required) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "color (string, object) expected"); + } + + break; + } + + return ret; +} + +duk_ret_t constructor(duk_context* ctx) +{ + color obj; + + /* + * The constructor allows an additional signature that takes 4 number + * arguments, otherwise use the literal parsing functions. + */ + if (duk_get_top(ctx) >= 3) { + // Alpha is optional. + auto alpha = duk_is_number(ctx, 3) ? duk_to_int(ctx, 3) : 255; + + obj = color( + clamp_component(ctx, duk_require_int(ctx, 0), true), + clamp_component(ctx, duk_require_int(ctx, 1), true), + clamp_component(ctx, duk_require_int(ctx, 2), true), + clamp_component(ctx, alpha, true) + ); + } else if (duk_get_top(ctx) == 1) { + obj = parse(ctx, 0, true); + } + + duk_ret_t ret; + + // Allow both constructor and non constructor calls. + if (duk_is_constructor_call(ctx)) { + duk_push_this(ctx); + dukx_put_color(ctx, obj); + duk_pop(ctx); + ret = 0; + } else { + dukx_push_color(ctx, obj); + ret = 1; + } + + return ret; +} + +} //! namespace + +color dukx_get_color(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, false); +} + +color dukx_require_color(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, true); +} + +color dukx_optional_color(duk_context* ctx, duk_idx_t index, color def) +{ + return parse(ctx, index, false, std::move(def)); +} + +void dukx_push_color(duk_context* ctx, const color& color) +{ + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + dukx_put_color(ctx, color); +} + +void dukx_put_color(duk_context* ctx, const color &color) +{ + assert(duk_is_object(ctx, -1)); + + StackAssert sa(ctx, 0); + + duk_push_uint(ctx, color.red()); + duk_put_prop_string(ctx, -2, "red"); + duk_push_uint(ctx, color.green()); + duk_put_prop_string(ctx, -2, "green"); + duk_push_uint(ctx, color.blue()); + duk_put_prop_string(ctx, -2, "blue"); + duk_push_uint(ctx, color.alpha()); + duk_put_prop_string(ctx, -2, "alpha"); +} + +void dukx_load_color(duk_context* ctx) +{ + StackAssert sa(ctx, 0); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, DUK_VARARGS); + duk_put_prop_string(ctx, -2, "Color"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_color.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,96 @@ +/* + * js_color.hpp -- color 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_COLOR_HPP +#define MALIKANIA_JS_COLOR_HPP + +/** + * \file js_color.hpp + * \brief JavaScript binding for color. + * + * colors can be created from plain JavaScript object. + * + * ```` + * { + * red: 0, + * green: 255, + * blue: 255, + * alpha: 255 + * } + * ```` + * + * It can also takes strings like "#rrggbbaa" and SVG names. + */ + +#include "color.hpp" +#include "duktape.hpp" + +namespace malikania { + +/** + * Get a color. + * + * May return a default value or a color with adjusted components. + * + * \param ctx the context + * \param index the index + */ +color dukx_get_color(duk_context* ctx, duk_idx_t index); + +/** + * Require a color. + * + * If the color has any invalid component, raise a JavaScript error. + * + * \param ctx the context + * \param index the index + */ +color dukx_require_color(duk_context* ctx, duk_idx_t index); + +/** + * Like get, but return the default value only if the value at the given + * index is not an object or not a string, otherwise, adjust invalid values. + * + * \param ctx the context + * \param index the index + * \param def the default value + */ +color dukx_optional_color(duk_context* ctx, duk_idx_t index, color def); + +/** + * Push the color as object. + * + * \param ctx the context + * \param color the color + */ +void dukx_push_color(duk_context* ctx, const color& color); + +/** + * Put the color properties into the object at the top of the stack. + * + * \pre the top value must be an object + * \param ctx the context + * \param color the color + */ +void dukx_put_color(duk_context* ctx, const color& color); + +void dukx_load_color(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_COLOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_font.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,140 @@ +/* + * js_font.cpp -- font 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 SOTWARE 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 <cassert> + +#include "js_client_resources_loader.hpp" +#include "js_font.hpp" +#include "js_size.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff""\xff""malikania-font-ptr"); + +font& self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a font object"); + } + + return *static_cast<font*>(ptr); +} + +duk_ret_t constructor(duk_context* ctx) +{ + StackAssert sa(ctx); + + if (!duk_is_constructor_call(ctx)) { + duk_error(ctx, DUK_ERR_ERROR, "font must be new-constructed"); + } + + try { + auto& loader = dukx_get_client_loader(ctx); + auto id = duk_require_string(ctx, 0); + auto size = duk_require_int(ctx, 1); + + if (size < 0) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d must not be negative", size); + } + + duk_push_this(ctx); + duk_push_pointer(ctx, new font(loader.load_font(id, static_cast<unsigned>(size)))); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t clip(duk_context* ctx) +{ + try { + dukx_push_size(ctx, self(ctx).clip(duk_require_string(ctx, 0))); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 1; +} + +const duk_function_list_entry methods[] = { + { "clip", clip, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +#if 0 + +void dukx_new_font(duk_context* ctx, font *font) +{ + assert(ctx); + assert(font); + + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, font); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); +} + +#endif + +font& dukx_require_font(duk_context* ctx, duk_idx_t index) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_prop_string(ctx, index, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a font object"); + } + + return *static_cast<font*>(ptr); +} + +void dukx_load_font(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 2); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "Font"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_font.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,37 @@ +/* + * js_font.hpp -- font 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_FONT_HPP +#define MALIKANIA_JS_FONT_HPP + +#include "duktape.hpp" +#include "font.hpp" + +namespace malikania { + +#if 0 +void dukx_new_font(duk_context *ctx, Font *font); +#endif + +font& dukx_require_font(duk_context* ctx, duk_idx_t index); + +void dukx_load_font(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_FONT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_image.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,135 @@ +/* + * 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 "js_client_resources_loader.hpp" +#include "js_image.hpp" +#include "js_point.hpp" +#include "js_rectangle.hpp" +#include "js_size.hpp" +#include "js_window.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff""\xff""malikania-image-ptr"); + +image& self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Animator object"); + } + + return *static_cast<image *>(ptr); +} + +duk_ret_t size(duk_context* ctx) +{ + try { + dukx_push_size(ctx, self(ctx).size()); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 1; +} + +duk_ret_t draw(duk_context* ctx) +{ + try { + auto& image = self(ctx); + auto& window = dukx_require_window(ctx, 0); + + if (duk_get_top(ctx) == 2) { + image.draw(window, dukx_get_point(ctx, 1)); + } else if (duk_get_top(ctx) == 3) { + image.draw(window, dukx_get_rect(ctx, 1), dukx_get_rect(ctx, 2)); + } else { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid number of arguments: #%d", duk_get_top(ctx)); + } + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t constructor(duk_context* ctx) +{ + if (!duk_is_constructor_call(ctx)) { + duk_error(ctx, DUK_ERR_ERROR, "image must be new-constructed"); + } + + try { + auto& loader = dukx_get_client_loader(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, new image(loader.load_image(duk_require_string(ctx, 0)))); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_push_string(ctx, "size"); + duk_push_c_function(ctx, size, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + duk_pop(ctx); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +const duk_function_list_entry methods[] = { + { "draw", draw, DUK_VARARGS }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +void dukx_new_image(duk_context* ctx, image *image) +{ + assert(ctx); + assert(image); + + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, image); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); +} + +void dukx_load_image(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 1); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "Image"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_image.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,35 @@ +/* + * js_image.hpp -- 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_HPP +#define MALIKANIA_JS_IMAGE_HPP + +#include "duktape.hpp" +#include "image.hpp" + +namespace malikania { + +#if 0 +void dukx_new_image(duk_context* ctx, image& image); +#endif + +void dukx_load_image(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_IMAGE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_line.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,136 @@ +/* + * js_line.cpp -- line 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 <cassert> + +#include "js_line.hpp" + +namespace malikania { + +namespace { + +duk_ret_t constructor(duk_context* ctx) +{ + line obj; + + if (duk_get_top(ctx) == 4) { + obj = line( + duk_get_int(ctx, 0), + duk_get_int(ctx, 1), + duk_get_int(ctx, 2), + duk_get_int(ctx, 3) + ); + } else if (duk_get_top(ctx) == 1) { + obj = dukx_require_line(ctx, 0); + } + + duk_ret_t ret; + + // Allow both constructor and non constructor calls. + if (duk_is_constructor_call(ctx)) { + duk_push_this(ctx); + dukx_put_line(ctx, obj); + ret = 0; + } else { + dukx_push_line(ctx, obj); + ret = 1; + } + + return ret; +} + +} // !namespace + +line dukx_get_line(duk_context* ctx, duk_idx_t index) +{ + auto get = [&] (auto name) { + StackAssert sa(ctx); + + duk_get_prop_string(ctx, index, name); + auto v = duk_get_int(ctx, -1); + duk_pop(ctx); + + return v; + }; + + return line(get("x1"), get("y1"), get("x2"), get("y2")); +} + +line dukx_require_line(duk_context* ctx, duk_idx_t index) +{ + auto get = [&] (auto prop) { + if (!duk_has_prop_string(ctx, index, prop)) + duk_error(ctx, DUK_ERR_ERROR, "missing %s property in line description", prop); + + duk_get_prop_string(ctx, index, prop); + + if (!duk_is_number(ctx, -1)) { + duk_pop(ctx); + duk_error(ctx, DUK_ERR_TYPE_ERROR, "property %s is not an int", prop); + } + + auto value = duk_to_int(ctx, -1); + + duk_pop(ctx); + + return value; + }; + + return line(get("x1"), get("y1"), get("x2"), get("y2")); +} + +line dukx_optional_line(duk_context* ctx, duk_idx_t index, line def) +{ + return duk_is_object(ctx, index) ? dukx_get_line(ctx, index) : def; +} + +void dukx_push_line(duk_context* ctx, const line& line) +{ + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + dukx_put_line(ctx, line); +} + +void dukx_put_line(duk_context* ctx, const line& line) +{ + assert(duk_is_object(ctx, -1)); + + StackAssert sa(ctx); + + duk_push_int(ctx, line.x1()); + duk_put_prop_string(ctx, -2, "x1"); + duk_push_int(ctx, line.y1()); + duk_put_prop_string(ctx, -2, "y1"); + duk_push_int(ctx, line.x2()); + duk_put_prop_string(ctx, -2, "x2"); + duk_push_int(ctx, line.y2()); + duk_put_prop_string(ctx, -2, "y2"); +} + +void dukx_load_line(duk_context* ctx) +{ + StackAssert sa(ctx, 0); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, DUK_VARARGS); + duk_put_prop_string(ctx, -2, "Line"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_line.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,93 @@ +/* + * js_line.hpp -- line 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_LINE_HPP +#define MALIKANIA_JS_LINE_HPP + +/** + * \file js_line.hpp + * \brief JavaScript binding for line. + * + * lines are plain objects. + * + * ```` + * { + * x1: 10, + * y1: 10, + * x2: 50, + * y2: 50 + * } + * ```` + */ + +#include "duktape.hpp" +#include "line.hpp" + +namespace malikania { + +/** + * Get a line. + * + * \param ctx the context + * \param index the index + * \return the line + */ +line dukx_get_line(duk_context* ctx, duk_idx_t index); + +/** + * Require a line. + * + * If value is not an object or any property is invalid, raise a JavaScript error. + * + * \param ctx the context + * \param index the index + * \return the line + */ +line dukx_require_line(duk_context* ctx, duk_idx_t index); + +/** + * Like get but return def if the value at the given index is not an object. + * + * \param ctx the context + * \param index the index + * \param def the default value + * \return the line + */ +line dukx_optional_line(duk_context* ctx, duk_idx_t index, line def); + +/** + * Push the line as object. + * + * \param ctx the context + * \param line the line + */ +void dukx_push_line(duk_context* ctx, const line &line); + +/** + * Put the line properties into the object at the top of the stack. + * + * \param ctx the context + * \param line the line + */ +void dukx_put_line(duk_context* ctx, const line &line); + +void dukx_load_line(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_LINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_point.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,130 @@ +/* + * js_point.cpp -- point 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 <cassert> + +#include "js_point.hpp" + +namespace malikania { + +namespace { + +point parse(duk_context* ctx, duk_idx_t index, bool required, point ret = {}) +{ + StackAssert sa(ctx); + + if (duk_is_object(ctx, index)) { + if (required && !duk_has_prop_string(ctx, index, "x")) { + duk_error(ctx, DUK_ERR_ERROR, "missing x property in point description"); + } + else if (required && !duk_has_prop_string(ctx, index, "y")) { + duk_error(ctx, DUK_ERR_ERROR, "missing y property in point description"); + } + + int x; + int y; + + duk_get_prop_string(ctx, index, "x"); + x = duk_to_int(ctx, -1); + duk_pop(ctx); + duk_get_prop_string(ctx, index, "y"); + y = duk_to_int(ctx, -1); + duk_pop(ctx); + + ret = point(x, y); + } else if (required) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "point object expected"); + } + + return ret; +} + +duk_ret_t constructor(duk_context* ctx) +{ + point obj; + + if (duk_get_top(ctx) == 2) { + obj = point(duk_require_int(ctx, 0), duk_require_int(ctx, 1)); + } else if (duk_get_top(ctx) == 1) { + obj = parse(ctx, 0, true); + } + + duk_ret_t ret; + + // Allow both constructor and non constructor calls. + if (duk_is_constructor_call(ctx)) { + duk_push_this(ctx); + dukx_put_point(ctx, obj); + duk_pop(ctx); + ret = 0; + } else { + dukx_push_point(ctx, obj); + ret = 1; + } + + return ret; +} + +} // !namespace + +point dukx_get_point(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, false); +} + +point dukx_require_point(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, true); +} + +point dukx_optional_point(duk_context* ctx, duk_idx_t index, point def) +{ + return parse(ctx, index, false, std::move(def)); +} + +void dukx_push_point(duk_context* ctx, const point &point) +{ + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + dukx_put_point(ctx, point); +} + +void dukx_put_point(duk_context* ctx, const point& point) +{ + assert(duk_is_object(ctx, -1)); + + StackAssert sa(ctx); + + duk_push_int(ctx, point.x()); + duk_put_prop_string(ctx, -2, "x"); + duk_push_int(ctx, point.y()); + duk_put_prop_string(ctx, -2, "y"); +} + +void dukx_load_point(duk_context* ctx) +{ + StackAssert sa(ctx, 0); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, DUK_VARARGS); + duk_put_prop_string(ctx, -2, "Point"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_point.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,39 @@ +/* + * js_point.hpp -- point 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_POINT_HPP +#define MALIKANIA_JS_POINT_HPP + +#include "duktape.hpp" +#include "point.hpp" + +namespace malikania { + +point dukx_require_point(duk_context* ctx, duk_idx_t index); + +point dukx_get_point(duk_context* ctx, duk_idx_t index); + +void dukx_push_point(duk_context* ctx, const point& point); + +void dukx_put_point(duk_context* ctx, const point& point); + +void dukx_load_point(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_POINT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_rectangle.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,151 @@ +/* + * js_rectangle.cpp -- rectangle 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 <cassert> + +#include "js_rectangle.hpp" + +namespace malikania { + +namespace { + +unsigned clamp(duk_context* ctx, int value, bool required) +{ + if (value < 0) { + if (required) + duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d can not be negative", value); + else + value = 0; + } + + return static_cast<unsigned>(value); +} + +rectangle parse(duk_context* ctx, duk_idx_t index, bool required, rectangle rect = {}) +{ + StackAssert sa(ctx); + + if (duk_is_object(ctx, index)) { + auto get = [&] (auto prop) { + if (required && !duk_has_prop_string(ctx, index, prop)) + duk_error(ctx, DUK_ERR_ERROR, "missing '%s' property", prop); + + duk_get_prop_string(ctx, index, prop); + + if (required && !duk_is_number(ctx, -1)) { + duk_pop(ctx); + duk_error(ctx, DUK_ERR_ERROR, "invalid '%s' property (number expected)", prop); + } + + auto value = duk_to_int(ctx, -1); + + duk_pop(ctx); + + return value; + }; + + rect = rectangle(get("x"), get("y"), + clamp(ctx, get("width"), required), clamp(ctx, get("height"), required)); + } else if (required) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "rectangle object expected"); + + return rect; +} + +duk_ret_t constructor(duk_context* ctx) +{ + rectangle rect; + + if (duk_get_top(ctx) == 4) { + rect = rectangle( + duk_require_int(ctx, 0), + duk_require_int(ctx, 1), + clamp(ctx, duk_require_int(ctx, 2), true), + clamp(ctx, duk_require_int(ctx, 3), true) + ); + } else if (duk_get_top(ctx) == 1) + rect = parse(ctx, 0, true); + + duk_ret_t ret; + + // Allow both constructor and non constructor calls. + if (duk_is_constructor_call(ctx)) { + duk_push_this(ctx); + dukx_put_rect(ctx, rect); + duk_pop(ctx); + ret = 0; + } else { + dukx_push_rect(ctx, rect); + ret = 1; + } + + return ret; +} + +} // !namespace + +rectangle dukx_get_rect(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, false); +} + +rectangle dukx_require_rect(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, true); +} + +rectangle dukx_optional_rect(duk_context* ctx, duk_idx_t index, rectangle def) +{ + return parse(ctx, index, false, std::move(def)); +} + +void dukx_push_rect(duk_context* ctx, const rectangle& rect) +{ + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + dukx_put_rect(ctx, rect); +} + +void dukx_put_rect(duk_context* ctx, const rectangle& rect) +{ + assert(duk_is_object(ctx, -1)); + + StackAssert sa(ctx); + + duk_push_int(ctx, rect.x()); + duk_put_prop_string(ctx, -2, "x"); + duk_push_int(ctx, rect.y()); + duk_put_prop_string(ctx, -2, "y"); + duk_push_uint(ctx, rect.width()); + duk_put_prop_string(ctx, -2, "width"); + duk_push_uint(ctx, rect.height()); + duk_put_prop_string(ctx, -2, "height"); +} + +void dukx_load_rect(duk_context* ctx) +{ + StackAssert sa(ctx, 0); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, DUK_VARARGS); + duk_put_prop_string(ctx, -2, "Rectangle"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_rectangle.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,95 @@ +/* + * js_rectangle.hpp -- rectangle 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_RECTANGLE_HPP +#define MALIKANIA_JS_RECTANGLE_HPP + +/** + * \file js_rectangle.hpp + * \brief JavaScript binding for rectangle. + * + * rectangles are plain objects. + * + * ```` + * { + * x: 10, + * y: 20, + * width: 100, + * height: 200 + * } + * ```` + */ + +#include "duktape.hpp" +#include "rectangle.hpp" + +namespace malikania { + +/** + * Get a rectangle. + * + * The rectangle may be adjusted if any values are incorrect. + * + * \param ctx the context + * \param index the value index + * \return the rectangle + */ +rectangle dukx_get_rect(duk_context* ctx, duk_idx_t index); + +/** + * Require a rectangle. + * + * If the object is not a rectangle or if width, height are invalid, raise a JavaScript error. + * + * \param ctx the context + * \param index the index + * \return the rectangle + */ +rectangle dukx_require_rect(duk_context* ctx, duk_idx_t index); + +/** + * Like get but return the default value if the value at the given index is not an object or invalid + * + * \param ctx the context + * \param index the idnex + * \param def the default value + * \return the rectangle + */ +rectangle dukx_optional_rect(duk_context* ctx, duk_idx_t index, rectangle def); + +/** + * Push the rectangle as object. + * + * \param ctx the context + * \param rect the rectangle + */ +void dukx_push_rect(duk_context* ctx, const rectangle &rect); + +/** + * Put the rectangle properties into the object at the top of the stack. + * + * \param ctx the context + * \param rect the rectangle + */ +void dukx_put_rect(duk_context* ctx, const rectangle& rect); + +void dukx_load_rect(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_RECTANGLE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_size.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,146 @@ +/* + * js_size.cpp -- size 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 <cassert> + +#include "js_size.hpp" + +namespace malikania { + +namespace { + +size parse(duk_context* ctx, duk_idx_t index, bool required, size ret = {}) +{ + StackAssert sa(ctx); + + if (duk_is_object(ctx, index)) { + if (required && !duk_has_prop_string(ctx, index, "width")) { + duk_error(ctx, DUK_ERR_ERROR, "missing width property in size description"); + } else if (required && !duk_has_prop_string(ctx, index, "height")) { + duk_error(ctx, DUK_ERR_ERROR, "missing height property in size description"); + } + + int width; + int height; + + duk_get_prop_string(ctx, index, "width"); + width = duk_to_int(ctx, -1); + duk_pop(ctx); + duk_get_prop_string(ctx, index, "height"); + height = duk_to_int(ctx, -1); + duk_pop(ctx); + + if (width < 0) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "width can not be negative"); + } + if (height < 0) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "height can not be negative"); + } + + ret = size(width, height); + } else if (required) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "size object expected"); + } + + return ret; +} + +duk_ret_t constructor(duk_context* ctx) +{ + size obj; + + if (duk_get_top(ctx) == 2) { + int width; + int height; + + if ((width = duk_require_int(ctx, 0)) < 0) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument #0 can not be negative"); + } + if ((height = duk_require_int(ctx, 1)) < 0) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument #1 can not be negative"); + } + + obj = size(static_cast<unsigned>(width), static_cast<unsigned>(height)); + } else if (duk_get_top(ctx) == 1) { + obj = parse(ctx, 0, true); + } + + duk_ret_t ret; + + // Allow both constructor and non constructor calls. + if (duk_is_constructor_call(ctx)) { + duk_push_this(ctx); + dukx_put_size(ctx, obj); + duk_pop(ctx); + ret = 0; + } else { + dukx_push_size(ctx, obj); + ret = 1; + } + + return ret; +} + +} // !namespace + +size dukx_get_size(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, false); +} + +size dukx_require_size(duk_context* ctx, duk_idx_t index) +{ + return parse(ctx, index, true); +} + +size dukx_optional_size(duk_context* ctx, duk_idx_t index, size def) +{ + return parse(ctx, index, false, std::move(def)); +} + +void dukx_push_size(duk_context* ctx, const size& size) +{ + StackAssert sa(ctx, 1); + + duk_push_object(ctx); + dukx_put_size(ctx, size); +} + +void dukx_put_size(duk_context* ctx, const size& size) +{ + assert(duk_is_object(ctx, -1)); + + StackAssert sa(ctx, 0); + + duk_push_uint(ctx, size.width()); + duk_put_prop_string(ctx, -2, "width"); + duk_push_uint(ctx, size.height()); + duk_put_prop_string(ctx, -2, "height"); +} + +void dukx_load_size(duk_context* ctx) +{ + StackAssert sa(ctx, 0); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, DUK_VARARGS); + duk_put_prop_string(ctx, -2, "Size"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_size.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,93 @@ +/* + * js_size.hpp -- size 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_SIZE_HPP +#define MALIKANIA_JS_SIZE_HPP + +/** + * \file js_size.hpp + * \brief JavaScript binding for size. + * + * size are plain objects. + * + * ```` + * { + * width: 1000, + * height: 2000 + * } + * ```` + */ + +#include "duktape.hpp" +#include "size.hpp" + +namespace malikania { + +/** + * Get a size. + * + * The size may be adjusted if any values are incorrect. + * + * \param ctx the context + * \param index the value index + * \return the size + */ +size dukx_get_size(duk_context* ctx, duk_idx_t index); + +/** + * Require a size + * + * If the object is not a size, raise a JavaScript error. + * + * \param ctx the context + * \param index the index + * \return the size + */ +size dukx_require_size(duk_context* ctx, duk_idx_t index); + +/** + * Like get but return the default value if the value at the given index is not an object. + * + * \param ctx the context + * \param index the idnex + * \param def the default value + * \return the size + */ +size dukx_optional_size(duk_context* ctx, duk_idx_t index, size def); + +/** + * Push the size as object. + * + * \param ctx the context + * \param size the size + */ +void dukx_push_size(duk_context* ctx, const size& size); + +/** + * Put the size properties into the object at the top of the stack. + * + * \param ctx the context + * \param size the size + */ +void dukx_put_size(duk_context* ctx, const size& size); + +void dukx_load_size(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_SIZE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_sprite.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,169 @@ +/* + * 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 "js_client_resources_loader.hpp" +#include "js_point.hpp" +#include "js_size.hpp" +#include "js_sprite.hpp" +#include "js_window.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff""\xff""malikania-sprite-ptr"); + +sprite& self(duk_context *ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a sprite object"); + } + + return *static_cast<sprite*>(ptr); +} + +duk_ret_t cell(duk_context* ctx) +{ + dukx_push_size(ctx, self(ctx).cell()); + + return 1; +} + +duk_ret_t columns(duk_context* ctx) +{ + duk_push_uint(ctx, self(ctx).columns()); + + return 1; +} + +duk_ret_t margins(duk_context *ctx) +{ + dukx_push_size(ctx, self(ctx).margin()); + + return 1; +} + +duk_ret_t rows(duk_context *ctx) +{ + duk_push_uint(ctx, self(ctx).rows()); + + return 1; +} + +duk_ret_t space(duk_context *ctx) +{ + dukx_push_size(ctx, self(ctx).space()); + + return 1; +} + +duk_ret_t constructor(duk_context *ctx) +{ + if (!duk_is_constructor_call(ctx)) { + duk_error(ctx, DUK_ERR_ERROR, "sprite must be new-constructed"); + } + + try { + auto& loader = dukx_get_client_loader(ctx); + auto sp = loader.load_sprite(duk_require_string(ctx, 0)); + + duk_push_this(ctx); + duk_push_pointer(ctx, new sprite(std::move(sp))); + duk_put_prop_string(ctx, -2, signature.c_str()); + + // Cell. + duk_push_string(ctx, "cell"); + duk_push_c_function(ctx, cell, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + + // Columns. + duk_push_string(ctx, "columns"); + duk_push_c_function(ctx, columns, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + + // Margins. + duk_push_string(ctx, "margins"); + duk_push_c_function(ctx, margins, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + + // Rows. + duk_push_string(ctx, "rows"); + duk_push_c_function(ctx, rows, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + + // Space. + duk_push_string(ctx, "space"); + duk_push_c_function(ctx, space, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + + duk_pop(ctx); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t draw(duk_context *ctx) +{ + try { + auto& sprite = self(ctx); + auto& window = dukx_require_window(ctx, 0); + auto cell = duk_require_uint(ctx, 1); + auto point = dukx_get_point(ctx, 2); + + if (cell >= (sprite.rows() * sprite.columns())) { + duk_error(ctx, DUK_ERR_RANGE_ERROR, "%d is out of range", cell); + } + + sprite.draw(window, cell, point); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +const duk_function_list_entry methods[] = { + { "draw", draw, 3 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +void dukx_load_sprite(duk_context *ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 1); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "Sprite"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_sprite.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,31 @@ +/* + * js_sprite.hpp -- 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_HPP +#define MALIKANIA_JS_SPRITE_HPP + +#include "duktape.hpp" +#include "sprite.hpp" + +namespace malikania { + +void dukx_load_sprite(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_SPRITE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_window.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,290 @@ +/* + * js_window.cpp -- window management (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 <cassert> + +#include "js_color.hpp" +#include "js_font.hpp" +#include "js_line.hpp" +#include "js_point.hpp" +#include "js_rectangle.hpp" +#include "js_window.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff""\xff""malikania-window-ptr"); +const std::string prototype("\xff""\xff""malikania-window-prototype"); + +window& self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Window object"); + } + + return *static_cast<window*>(ptr); +} + +duk_ret_t constructor(duk_context* ctx) +{ + StackAssert sa(ctx); + + if (!duk_is_constructor_call(ctx)) { + duk_error(ctx, DUK_ERR_ERROR, "window must be new-constructed"); + } + + // TODO: add parameters. + try { + duk_push_this(ctx); + duk_push_pointer(ctx, new window); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t clear(duk_context* ctx) +{ + try { + self(ctx).clear(); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t present(duk_context* ctx) +{ + try { + self(ctx).present(); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawingColor(duk_context* ctx) +{ + try { + dukx_push_color(ctx, self(ctx).drawing_color()); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 1; +} + +duk_ret_t drawLine(duk_context* ctx) +{ + try { + self(ctx).draw_line(dukx_require_line(ctx, 0)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawLines(duk_context* ctx) +{ + try { + self(ctx).draw_lines(dukx_get_array(ctx, 0, dukx_get_point)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawPoint(duk_context* ctx) +{ + try { + self(ctx).draw_point(dukx_require_point(ctx, 0)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawPoints(duk_context* ctx) +{ + try { + self(ctx).draw_points(dukx_get_array(ctx, 0, dukx_get_point)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawRectangle(duk_context* ctx) +{ + try { + self(ctx).draw_rectangle(dukx_require_rect(ctx, 0)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawRectangles(duk_context* ctx) +{ + try { + self(ctx).draw_rectangles(dukx_get_array(ctx, 0, dukx_get_rect)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t drawText(duk_context* ctx) +{ + try { + auto& win = self(ctx); + auto text = duk_require_string(ctx, 0); + auto& font = dukx_require_font(ctx, 1); + auto rect = dukx_get_rect(ctx, 2); + + if (!rect.is_null()) { + win.draw_text(text, font, rect); + } else { + win.draw_text(text, font, point{rect.x(), rect.y()}); + } + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t fillRectangle(duk_context* ctx) +{ + try { + self(ctx).fill_rectangle(dukx_require_rect(ctx, 0)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t fillRectangles(duk_context* ctx) +{ + try { + self(ctx).fill_rectangles(dukx_get_array(ctx, 0, dukx_get_rect)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk_ret_t setDrawingColor(duk_context* ctx) +{ + try { + self(ctx).set_drawing_color(dukx_require_color(ctx, 0)); + } catch (const std::exception &ex) { + duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +const duk_function_list_entry methods[] = { + { "clear", clear, 0 }, + { "drawingColor", drawingColor, 0 }, + { "drawLine", drawLine, 1 }, + { "drawLines", drawLines, 1 }, + { "drawPoint", drawPoint, 1 }, + { "drawPoints", drawPoints, 1 }, + { "drawRectangle", drawRectangle, 1 }, + { "drawRectangles", drawRectangles, 1 }, + { "drawText", drawText, 3 }, + { "fillRectangle", fillRectangle, 1 }, + { "fillRectangles", fillRectangles, 1 }, + { "present", present, 0 }, + { "setDrawingColor", setDrawingColor, 1 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +#if 0 + +void dukx_new_window(duk_context* ctx, window*window) +{ + assert(ctx); + assert(window); + + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_push_pointer(ctx, window); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); +} + +#endif + +window& dukx_require_window(duk_context* ctx, duk_idx_t index) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_prop_string(ctx, index, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Window object"); + } + + return *static_cast<window*>(ptr); +} + +void dukx_load_window(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 0); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "Window"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient-js/malikania/js_window.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,33 @@ +/* + * js_window.hpp -- window management (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_WINDOW_HPP +#define MALIKANIA_JS_WINDOW_HPP + +#include "duktape.hpp" +#include "window.hpp" + +namespace malikania { + +window& dukx_require_window(duk_context* ctx, duk_idx_t index); + +void dukx_load_window(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_WINDOW_HPP
--- a/libclient/CMakeLists.txt Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/CMakeLists.txt Tue Nov 29 21:21:36 2016 +0100 @@ -20,42 +20,42 @@ HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/malikania/animation.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/animator.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-resources-loader.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-loading.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-map.hpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client.hpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client_resources_loader.hpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target.hpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-loading.hpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-map.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/color.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/label.hpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/label.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/line.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/point.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/rectangle.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/size.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/sprite.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/window.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/font-backend.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/image-backend.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/window-backend.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/font_backend.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/image_backend.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/window_backend.hpp ) set( SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/malikania/animator.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-resources-loader.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-loading.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-map.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client_resources_loader.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-loading.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/client-target-map.cpp ${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/label.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/malikania/label.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/sprite.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/window.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/font-backend.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/image-backend.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/window-backend.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/font_backend.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/image_backend.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/${WITH_BACKEND_DIRECTORY}/window_backend.cpp ) find_package(SDL2 REQUIRED)
--- a/libclient/malikania/animation.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/animation.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -33,16 +33,15 @@ namespace malikania { -class Window; +class window; /** - * \class AnimationFrame * \brief Animation frame description. * - * A frame is a duration before switching to the next sprite cell. It is currently implemented as a class for future - * usage. + * A frame is a duration before switching to the next sprite cell. It is + * currently implemented as a class for future usage. */ -class AnimationFrame { +class animation_frame { private: std::uint16_t m_delay; @@ -52,7 +51,7 @@ * * \param delay the optional delay */ - inline AnimationFrame(std::uint16_t delay = 100) noexcept + inline animation_frame(std::uint16_t delay = 100) noexcept : m_delay(delay) { } @@ -71,25 +70,25 @@ /** * \brief List of frames. */ -using AnimationFrames = std::vector<AnimationFrame>; +using animation_frames = std::vector<animation_frame>; /** - * \class Animation * \brief Animation description. * - * An animation is a sprite with a set of frames containing a delay for showing all sprites in a specific amount of - * time. + * An animation is a sprite with a set of frames containing a delay for showing + * all sprites in a specific amount of time. * - * Because an animation contains an image, a state (time, current cell) it must be constructed with an Animator object - * so the user is able to use the same animation on different parts of the screen without having to duplicate + * Because an animation contains an image, a state (time, current cell) it must + * be constructed with an animator object so the user is able to use the same + * animation on different parts of the screen without having to duplicate * resources. * * \see Animator */ -class Animation { +class animation { private: - Sprite m_sprite; - AnimationFrames m_frames; + malikania::sprite m_sprite; + malikania::animation_frames m_frames; public: /** @@ -98,7 +97,7 @@ * \param sprite the sprite image * \param frames the frames to show */ - inline Animation(Sprite sprite, AnimationFrames frames) noexcept + inline animation(malikania::sprite sprite, animation_frames frames) noexcept : m_sprite(std::move(sprite)) , m_frames(std::move(frames)) { @@ -109,7 +108,7 @@ * * \return the sprite */ - inline const Sprite &sprite() const noexcept + inline const malikania::sprite& sprite() const noexcept { return m_sprite; } @@ -119,7 +118,7 @@ * * \return the sprite */ - inline Sprite &sprite() noexcept + inline malikania::sprite& sprite() noexcept { return m_sprite; } @@ -129,7 +128,7 @@ * * \return the frames */ - inline const AnimationFrames &frames() const noexcept + inline const animation_frames& frames() const noexcept { return m_frames; } @@ -141,7 +140,7 @@ * \param index the index * \return the frame */ - inline const AnimationFrame &operator[](unsigned index) const noexcept + inline const animation_frame& operator[](unsigned index) const noexcept { assert(index < m_frames.size());
--- a/libclient/malikania/animator.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/animator.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,17 +21,18 @@ namespace malikania { -Animator::Animator(Animation &animation) noexcept +animator::animator(animation& animation) noexcept : m_animation(animation) { } -void Animator::update() noexcept +void animator::update() noexcept { - unsigned total = m_animation.sprite().rows() * m_animation.sprite().columns(); + auto total = m_animation.sprite().rows() * m_animation.sprite().columns(); - if (m_current >= total) + if (m_current >= total) { return; + } if (m_timer.elapsed().wall / 1000000LL >= m_animation[m_current].delay()) { m_current ++; @@ -39,11 +40,11 @@ } } -void Animator::draw(Window &window, const Point &point) +void animator::draw(window& window, const point& point) { - // TODO: assert ? - if (m_current >= m_animation.sprite().rows() * m_animation.sprite().columns()) + if (m_current >= m_animation.sprite().rows() * m_animation.sprite().columns()) { return; + } m_animation.sprite().draw(window, m_current, point); }
--- a/libclient/malikania/animator.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/animator.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -28,20 +28,19 @@ namespace malikania { -class Animation; -class Point; -class Window; +class animation; +class point; +class window; /** - * \class Animator * \brief Object for drawing animations. * * The animator contains an animation and a state. */ -class Animator { +class animator { private: boost::timer::cpu_timer m_timer; - Animation &m_animation; + animation& m_animation; unsigned m_current{0}; public: @@ -51,12 +50,13 @@ * \pre animation must not be null * \param animation the animation */ - Animator(Animation &animation) noexcept; + animator(animation& animation) noexcept; /** * Update the animator state. * - * This function should be called in the main loop to update the cell to draw before calling draw(). + * This function should be called in the main loop to update the cell to + * draw before calling draw(). */ void update() noexcept; @@ -66,7 +66,7 @@ * \param window the window * \param position the position in the window */ - void draw(Window &window, const Point &position); + void draw(window& window, const point& position); }; } // !malikania
--- a/libclient/malikania/backend/sdl/font-backend.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * font-backend.cpp -- font object (SDL2 implementation) - * - * 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 <malikania/backend/sdl/common-sdl.hpp> - -#include <malikania/size.hpp> -#include <malikania/font.hpp> - -#include "font-backend.hpp" - -using namespace std::string_literals; - -namespace malikania { - -Font::Backend::Backend(std::string data, unsigned size) - : m_font(nullptr, nullptr) -{ - auto rw = SDLx_RWFromBinary(std::move(data)); - - if (rw == nullptr) - throw std::runtime_error(SDL_GetError()); - - m_font = Handle(TTF_OpenFontRW(rw, true, size), TTF_CloseFont); - - if (m_font == NULL) - throw std::runtime_error(TTF_GetError()); -} - -Size Font::Backend::clip(const Font &, const std::string &text) const -{ - int width, height; - - if (TTF_SizeUTF8(m_font.get(), text.c_str(), &width, &height) != 0) - throw std::runtime_error(SDL_GetError()); - - return Size(static_cast<unsigned>(width), static_cast<unsigned>(height)); -} - -} // !malikania
--- a/libclient/malikania/backend/sdl/font-backend.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * font-backend.hpp -- font object (SDL2 implementation) - * - * 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_FONT_BACKEND_HPP -#define MALIKANIA_FONT_BACKEND_HPP - -#include <memory> - -#include <SDL.h> -#include <SDL_ttf.h> - -#include <malikania/font.hpp> - -namespace malikania { - -class Font; -class Size; - -class Font::Backend { -private: - using Handle = std::unique_ptr<TTF_Font, void (*)(TTF_Font*)>; - - Handle m_font; - -public: - Backend(std::string data, unsigned size); - - inline TTF_Font *font() noexcept - { - return m_font.get(); - } - - Size clip(const Font &self, const std::string &text) const; -}; - -} // !malikania - -#endif // !MALIKANIA_FONT_BACKEND_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/backend/sdl/font_backend.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,57 @@ +/* + * font_backend.cpp -- font object (SDL2 implementation) + * + * 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 <malikania/backend/sdl/sdl_util.hpp> + +#include <malikania/size.hpp> +#include <malikania/font.hpp> + +#include "font_backend.hpp" + +using namespace std::string_literals; + +namespace malikania { + +font::backend_impl::backend_impl(std::string data, unsigned size) + : m_font(nullptr, nullptr) +{ + auto rw = SDLx_RWFromBinary(std::move(data)); + + if (rw == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + m_font = {TTF_OpenFontRW(rw, true, size), TTF_CloseFont}; + + if (m_font == nullptr) { + throw std::runtime_error(TTF_GetError()); + } +} + +size font::backend_impl::clip(const malikania::font&, const std::string& text) const +{ + int width, height; + + if (TTF_SizeUTF8(m_font.get(), text.c_str(), &width, &height) != 0) { + throw std::runtime_error(SDL_GetError()); + } + + return malikania::size(static_cast<unsigned>(width), static_cast<unsigned>(height)); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/backend/sdl/font_backend.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,51 @@ +/* + * font_backend.hpp -- font object (SDL2 implementation) + * + * 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_FONT_BACKEND_HPP +#define MALIKANIA_FONT_BACKEND_HPP + +#include <memory> + +#include <SDL.h> +#include <SDL_ttf.h> + +#include <malikania/font.hpp> + +namespace malikania { + +class font; +class size; + +class font::backend_impl { +private: + std::unique_ptr<TTF_Font, void (*)(TTF_Font*)> m_font; + +public: + backend_impl(std::string data, unsigned size); + + inline TTF_Font* font() noexcept + { + return m_font.get(); + } + + malikania::size clip(const malikania::font& self, const std::string& text) const; +}; + +} // !malikania + +#endif // !MALIKANIA_FONT_BACKEND_HPP
--- a/libclient/malikania/backend/sdl/image-backend.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * image-backend.cpp -- image object (SDL2 implementation) - * - * 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 <SDL_image.h> - -#include <malikania/backend/sdl/common-sdl.hpp> - -#include "image-backend.hpp" -#include "window-backend.hpp" - -using namespace std::string_literals; - -namespace malikania { - -void Image::Backend::createTexture(Window &window) -{ - m_texture = Texture(SDL_CreateTextureFromSurface(window.backend().renderer(), m_surface.get()), SDL_DestroyTexture); - - if (m_texture == nullptr) - throw std::runtime_error(SDL_GetError()); -} - -Image::Backend::Backend(Image &, std::string data) - : m_surface(nullptr, nullptr) - , m_texture(nullptr, nullptr) -{ - // Initialize the texture. - auto rw = SDLx_RWFromBinary(std::move(data)); - - if (rw == nullptr) - throw std::runtime_error(SDL_GetError()); - - m_surface = Surface(IMG_Load_RW(rw, true), SDL_FreeSurface); - - if (!m_surface) - throw std::runtime_error(SDL_GetError()); - - m_size = Size(static_cast<unsigned>(m_surface->w), static_cast<unsigned>(m_surface->h)); -} - -void Image::Backend::draw(Window &window, const Point &point) -{ - if (!m_texture) - createTexture(window); - - SDL_Rect target; - - target.x = static_cast<int>(point.x()); - target.y = static_cast<int>(point.y()); - target.w = static_cast<int>(m_size.width()); - target.h = static_cast<int>(m_size.height()); - - if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), nullptr, &target) < 0) - throw std::runtime_error(SDL_GetError()); -} - -void Image::Backend::draw(Window &window, const Rectangle &source, const Rectangle &target) -{ - if (!m_texture) - createTexture(window); - - SDL_Rect sr, st; - - sr.x = source.x(); - sr.y = source.y(); - sr.w = static_cast<int>(source.width()); - sr.h = static_cast<int>(source.height()); - - st.x = target.x(); - st.y = target.y(); - st.w = static_cast<int>(target.width()); - st.h = static_cast<int>(target.height()); - - /* Readjust .w, .h if null */ - if (source.isNull()) { - sr.w = static_cast<int>(m_size.width()); - sr.h = static_cast<int>(m_size.height()); - } - if (target.isNull()) { - st.w = static_cast<int>(m_size.width()); - st.h = static_cast<int>(m_size.height()); - } - - if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), &sr, &st) < 0) - throw std::runtime_error(SDL_GetError()); -} - -} // !malikania
--- a/libclient/malikania/backend/sdl/image-backend.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * image-backend.hpp -- image object (SDL2 implementation) - * - * 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_IMAGE_BACKEND_HPP -#define MALIKANIA_IMAGE_BACKEND_HPP - -#include <memory> - -#include <SDL.h> - -#include <malikania/size.hpp> -#include <malikania/image.hpp> - -namespace malikania { - -class Image; -class Point; -class Rectangle; -class Window; - -class Image::Backend { -private: - using Surface = std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)>; - using Texture = std::unique_ptr<SDL_Texture, void (*)(SDL_Texture *)>; - - Surface m_surface; - Texture m_texture; - Size m_size; - - void createTexture(Window &window); - -public: - Backend(Image &self, std::string data); - - inline SDL_Texture *texture() noexcept - { - return m_texture.get(); - } - - inline const Size &size() const noexcept - { - return m_size; - } - - void draw(Window &window, const Point &position); - - void draw(Window &window, const Rectangle &source, const Rectangle &target); -}; - -} // !malikania - -#endif // !MALIKANIA_IMAGE_BACKEND_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/backend/sdl/image_backend.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,119 @@ +/* + * image_backend.cpp -- image object (SDL2 implementation) + * + * 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 <SDL_image.h> + +#include <malikania/backend/sdl/sdl_util.hpp> + +#include "image_backend.hpp" +#include "window_backend.hpp" + +using namespace std::string_literals; + +namespace malikania { + +void image::backend_impl::create_texture(window& window) +{ + m_texture = { + SDL_CreateTextureFromSurface(window.backend().renderer(), m_surface.get()), + SDL_DestroyTexture + }; + + if (m_texture == nullptr) { + throw std::runtime_error(SDL_GetError()); + } +} + +image::backend_impl::backend_impl(image&, std::string data) + : m_surface(nullptr, nullptr) + , m_texture(nullptr, nullptr) +{ + auto rw = SDLx_RWFromBinary(std::move(data)); + + if (rw == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + m_surface = {IMG_Load_RW(rw, true), SDL_FreeSurface}; + + if (!m_surface) { + throw std::runtime_error(SDL_GetError()); + } + + m_size = malikania::size( + static_cast<unsigned>(m_surface->w), + static_cast<unsigned>(m_surface->h) + ); +} + +void image::backend_impl::draw(window& window, const point& point) +{ + /* + * Create texture at this step so the image constructor does not need the + * window. + */ + if (!m_texture) { + create_texture(window); + } + + SDL_Rect target; + + target.x = static_cast<int>(point.x()); + target.y = static_cast<int>(point.y()); + target.w = static_cast<int>(m_size.width()); + target.h = static_cast<int>(m_size.height()); + + if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), nullptr, &target) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void image::backend_impl::draw(window& window, const rectangle& source, const rectangle& target) +{ + if (!m_texture) { + create_texture(window); + } + + SDL_Rect sr, st; + + sr.x = source.x(); + sr.y = source.y(); + sr.w = static_cast<int>(source.width()); + sr.h = static_cast<int>(source.height()); + + st.x = target.x(); + st.y = target.y(); + st.w = static_cast<int>(target.width()); + st.h = static_cast<int>(target.height()); + + // Readjust .w, .h if null. + if (source.is_null()) { + sr.w = static_cast<int>(m_size.width()); + sr.h = static_cast<int>(m_size.height()); + } + if (target.is_null()) { + st.w = static_cast<int>(m_size.width()); + st.h = static_cast<int>(m_size.height()); + } + + if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), &sr, &st) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/backend/sdl/image_backend.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,65 @@ +/* + * image_backend.hpp -- image object (SDL2 implementation) + * + * 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_IMAGE_BACKEND_HPP +#define MALIKANIA_IMAGE_BACKEND_HPP + +#include <memory> + +#include <SDL.h> + +#include <malikania/size.hpp> +#include <malikania/image.hpp> + +namespace malikania { + +class image; +class point; +class rectangle; +class window; + +class image::backend_impl { +private: + std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> m_surface; + std::unique_ptr<SDL_Texture, void (*)(SDL_Texture *)> m_texture; + + malikania::size m_size; + + void create_texture(window& window); + +public: + backend_impl(image& self, std::string data); + + inline SDL_Texture* texture() noexcept + { + return m_texture.get(); + } + + inline const malikania::size& size() const noexcept + { + return m_size; + } + + void draw(window& window, const point& position); + + void draw(window& window, const rectangle& source, const rectangle& target); +}; + +} // !malikania + +#endif // !MALIKANIA_IMAGE_BACKEND_HPP
--- a/libclient/malikania/backend/sdl/window-backend.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* - * window-backend.cpp -- window object (SDL2 implementation) - * - * 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 <SDL.h> -#include <SDL_ttf.h> - -#include <stdexcept> - -#include <malikania/color.hpp> -#include <malikania/line.hpp> -#include <malikania/point.hpp> -#include <malikania/rectangle.hpp> - -#include "font-backend.hpp" -#include "window-backend.hpp" - -namespace malikania { - -Window::Backend::Backend(Window &, unsigned width, unsigned height, const std::string &title) - : m_window(nullptr, nullptr) - , m_renderer(nullptr, nullptr) -{ - SDL_SetMainReady(); - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); - - m_window = WindowHandle( - SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL), - SDL_DestroyWindow - ); - - if (m_window == nullptr) - throw std::runtime_error(SDL_GetError()); - - // Create renderer. - m_renderer = RendererHandle( - SDL_CreateRenderer(m_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), - SDL_DestroyRenderer - ); - - if (m_renderer == nullptr) - throw std::runtime_error(SDL_GetError()); - - if (TTF_Init() == -1) - throw std::runtime_error(TTF_GetError()); -} - -void Window::Backend::poll(Window &self) -{ - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYUP: - self.onKeyUp(event.key.keysym.sym); - break; - case SDL_KEYDOWN: - self.onKeyDown(event.key.keysym.sym); - break; - case SDL_QUIT: - self.onQuit(); - break; - default: - break; - } - } -} - -void Window::Backend::clear() -{ - SDL_RenderClear(m_renderer.get()); -} - -void Window::Backend::present() -{ - SDL_RenderPresent(m_renderer.get()); -} - -#if 0 - -// TODO: see later if it's really needed - -Size Window::Backend::resolution() -{ - SDL_DisplayMode current; - int width = 0; - int height = 0; - for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { - int error = SDL_GetCurrentDisplayMode(i, ¤t); - if (error == 0) { - // Get the last one - // TODO test with only one display mode, but we have to test with more than that - width = current.w; - height = current.hpp; - } else { - throw std::runtime_error("Could not get display mode for video display" + std::string(SDL_GetError())); - } - } - - return Size((unsigned)width, (unsigned)height); -} - -#endif - -Color Window::Backend::drawingColor() const -{ - SDL_Color color; - - if (SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a) < 0) - throw std::runtime_error(SDL_GetError()); - - return Color(color.r, color.g, color.b, color.a); -} - -void Window::Backend::setDrawingColor(const Color &color) -{ - if (SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()) < 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawLine(const Line &line) -{ - if (SDL_RenderDrawLine(m_renderer.get(), line.x1(), line.y1(), line.x2(), line.y2()) != 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawLines(const std::vector<Point> &points) -{ - std::vector<SDL_Point> sdlPoints(points.size()); - - for (unsigned i = 0; i < points.size(); ++i) - sdlPoints[i] = SDL_Point{points[i].x(), points[i].y()}; - - if (SDL_RenderDrawLines(m_renderer.get(), sdlPoints.data(), sdlPoints.size()) < 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawPoint(const Point &point) -{ - if (SDL_RenderDrawPoint(m_renderer.get(), point.x(), point.y()) != 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawPoints(const std::vector<Point> &points) -{ - std::vector<SDL_Point> sdlPoints(points.size()); - - for (unsigned i = 0; i < points.size(); ++i) - sdlPoints[i] = SDL_Point{points[i].x(), points[i].y()}; - - if (SDL_RenderDrawPoints(m_renderer.get(), sdlPoints.data(), sdlPoints.size()) != 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawRectangle(const Rectangle &rectangle) -{ - SDL_Rect rect{rectangle.x(), rectangle.y(), static_cast<int>(rectangle.width()), static_cast<int>(rectangle.height())}; - - if (SDL_RenderDrawRect(m_renderer.get(), &rect) < 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawRectangles(const std::vector<Rectangle> &rectangles) -{ - std::vector<SDL_Rect> sdlRects(rectangles.size()); - - for (unsigned i = 0; i < rectangles.size(); ++i) - sdlRects[i] = SDL_Rect{rectangles[i].x(), rectangles[i].y(), - static_cast<int>(rectangles[i].width()), static_cast<int>(rectangles[i].height())}; - - if (SDL_RenderDrawRects(m_renderer.get(), sdlRects.data(), sdlRects.size()) != 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::fillRectangle(const Rectangle &rectangle) -{ - SDL_Rect rect{rectangle.x(), rectangle.y(), static_cast<int>(rectangle.width()), static_cast<int>(rectangle.height())}; - - if (SDL_RenderFillRect(m_renderer.get(), &rect) < 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::fillRectangles(const std::vector<Rectangle> &rectangles) -{ - std::vector<SDL_Rect> sdlRects(rectangles.size()); - - for (unsigned i = 0; i < rectangles.size(); ++i) - sdlRects[i] = SDL_Rect{rectangles[i].x(), rectangles[i].y(), - static_cast<int>(rectangles[i].width()), static_cast<int>(rectangles[i].height())}; - - if (SDL_RenderFillRects(m_renderer.get(), sdlRects.data(), sdlRects.size()) != 0) - throw std::runtime_error(SDL_GetError()); -} - -void Window::Backend::drawText(const std::string &text, Font &font, const Rectangle &rectangle) -{ - SDL_Color color = {0, 0, 0, 255}; - SDL_Surface *message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); - SDL_Texture *texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); - SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; - SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); - SDL_FreeSurface(message); - SDL_DestroyTexture(texture); -} - -void Window::Backend::drawText(const std::string &text, Font &font, const Point &point) -{ - SDL_Color color = {0, 0, 0, 0}; - SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a); - SDL_Surface *message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); - SDL_Texture *texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); - SDL_Rect rect{point.x(), point.y(), message->w, message->h}; - SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); - SDL_FreeSurface(message); - SDL_DestroyTexture(texture); -} - -void Window::Backend::close() -{ -} - -} // !malikania
--- a/libclient/malikania/backend/sdl/window-backend.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * window-backend.hpp -- window object (SDL2 implementation) - * - * 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_WINDOW_BACKEND_HPP -#define MALIKANIA_WINDOW_BACKEND_HPP - -#include <memory> -#include <vector> - -#include <SDL.h> - -#include <malikania/window.hpp> - -namespace malikania { - -class Window::Backend { -private: - using WindowHandle = std::unique_ptr<SDL_Window, void (*)(SDL_Window *)>; - using RendererHandle = std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer *)>; - - WindowHandle m_window; - RendererHandle m_renderer; - -public: - Backend(Window &self, unsigned width, unsigned height, const std::string &title); - - inline SDL_Renderer *renderer() noexcept - { - return m_renderer.get(); - } - - void poll(Window &self); - - void close(); - - void clear(); - - void present(); - - Color drawingColor() const; - - void setDrawingColor(const Color &color); - - void drawLine(const Line &line); - - void drawLines(const std::vector<Point> &points); - - void drawPoint(const Point &point); - - void drawPoints(const std::vector<Point> &points); - - void drawRectangle(const Rectangle &rect); - - void drawRectangles(const std::vector<Rectangle> &rects); - - void fillRectangle(const Rectangle &rect); - - void fillRectangles(const std::vector<Rectangle> &rects); - - void drawText(const std::string &text, Font &font, const Rectangle &rectangle); - - void drawText(const std::string &text, Font &font, const Point &point); -}; - -} // !malikania - -#endif // !MALIKANIA_WINDOW_BACKEND_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/backend/sdl/window_backend.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,270 @@ +/* + * window_backend.cpp -- window object (SDL2 implementation) + * + * 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 <SDL.h> +#include <SDL_ttf.h> + +#include <stdexcept> + +#include <malikania/color.hpp> +#include <malikania/line.hpp> +#include <malikania/point.hpp> +#include <malikania/rectangle.hpp> + +#include "font_backend.hpp" +#include "window_backend.hpp" + +namespace malikania { + +window::backend_impl::backend_impl(window&, unsigned width, unsigned height, const std::string& title) + : m_window(nullptr, nullptr) + , m_renderer(nullptr, nullptr) +{ + SDL_SetMainReady(); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); + + m_window = { + SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL), + SDL_DestroyWindow + }; + + if (m_window == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + // Create renderer. + m_renderer = { + SDL_CreateRenderer(m_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), + SDL_DestroyRenderer + }; + + if (m_renderer == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + if (TTF_Init() == -1) { + throw std::runtime_error(TTF_GetError()); + } +} + +void window::backend_impl::poll(window&) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYUP: + //self.onKeyUp(event.key.keysym.sym); + break; + case SDL_KEYDOWN: + //self.onKeyDown(event.key.keysym.sym); + break; + case SDL_QUIT: + //self.onQuit(); + break; + default: + break; + } + } +} + +void window::backend_impl::clear() +{ + SDL_RenderClear(m_renderer.get()); +} + +void window::backend_impl::present() +{ + SDL_RenderPresent(m_renderer.get()); +} + +#if 0 + +// TODO: see later if it's really needed + +Size window::backend_impl::resolution() +{ + SDL_DisplayMode current; + int width = 0; + int height = 0; + for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { + int error = SDL_GetCurrentDisplayMode(i, ¤t); + if (error == 0) { + // Get the last one + // TODO test with only one display mode, but we have to test with more than that + width = current.w; + height = current.hpp; + } else { + throw std::runtime_error("Could not get display mode for video display" + std::string(SDL_GetError())); + } + } + + return Size((unsigned)width, (unsigned)height); +} + +#endif + +color window::backend_impl::drawing_color() const +{ + SDL_Color color; + + if (SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a) < 0) { + throw std::runtime_error(SDL_GetError()); + } + + return {color.r, color.g, color.b, color.a}; +} + +void window::backend_impl::set_drawing_color(const color& color) +{ + if (SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_line(const line& line) +{ + if (SDL_RenderDrawLine(m_renderer.get(), line.x1(), line.y1(), line.x2(), line.y2()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_lines(const std::vector<point>& points) +{ + std::vector<SDL_Point> sdlpoints(points.size()); + + for (unsigned i = 0; i < points.size(); ++i) { + sdlpoints[i] = {points[i].x(), points[i].y()}; + } + + if (SDL_RenderDrawLines(m_renderer.get(), sdlpoints.data(), sdlpoints.size()) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_point(const point& point) +{ + if (SDL_RenderDrawPoint(m_renderer.get(), point.x(), point.y()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_points(const std::vector<point>& points) +{ + std::vector<SDL_Point> sdlpoints(points.size()); + + for (unsigned i = 0; i < points.size(); ++i) { + sdlpoints[i] = {points[i].x(), points[i].y()}; + } + + if (SDL_RenderDrawPoints(m_renderer.get(), sdlpoints.data(), sdlpoints.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_rectangle(const rectangle& rectangle) +{ + SDL_Rect rect{ + rectangle.x(), + rectangle.y(), + static_cast<int>(rectangle.width()), + static_cast<int>(rectangle.height()) + }; + + if (SDL_RenderDrawRect(m_renderer.get(), &rect) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_rectangles(const std::vector<rectangle>& rectangles) +{ + std::vector<SDL_Rect> sdlrects(rectangles.size()); + + for (unsigned i = 0; i < rectangles.size(); ++i) { + sdlrects[i] = { + rectangles[i].x(), + rectangles[i].y(), + static_cast<int>(rectangles[i].width()), + static_cast<int>(rectangles[i].height()) + }; + } + + if (SDL_RenderDrawRects(m_renderer.get(), sdlrects.data(), sdlrects.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::fill_rectangle(const rectangle& rectangle) +{ + SDL_Rect rect{ + rectangle.x(), + rectangle.y(), + static_cast<int>(rectangle.width()), + static_cast<int>(rectangle.height()) + }; + + if (SDL_RenderFillRect(m_renderer.get(), &rect) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::fill_rectangles(const std::vector<rectangle>& rectangles) +{ + std::vector<SDL_Rect> sdlrects(rectangles.size()); + + for (unsigned i = 0; i < rectangles.size(); ++i) { + sdlrects[i] = { + rectangles[i].x(), + rectangles[i].y(), + static_cast<int>(rectangles[i].width()), + static_cast<int>(rectangles[i].height()) + }; + } + + if (SDL_RenderFillRects(m_renderer.get(), sdlrects.data(), sdlrects.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_text(const std::string& text, font& font, const rectangle& rectangle) +{ + SDL_Color color = {0, 0, 0, 255}; + SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); + SDL_Rect rect = {rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; + SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); + SDL_FreeSurface(message); + SDL_DestroyTexture(texture); +} + +void window::backend_impl::draw_text(const std::string &text, font& font, const point& point) +{ + SDL_Color color = {0, 0, 0, 0}; + SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a); + SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); + SDL_Rect rect = {point.x(), point.y(), message->w, message->h}; + SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); + SDL_FreeSurface(message); + SDL_DestroyTexture(texture); +} + +void window::backend_impl::close() +{ +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/backend/sdl/window_backend.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,79 @@ +/* + * window_backend.hpp -- window object (SDL2 implementation) + * + * 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_WINDOW_BACKEND_HPP +#define MALIKANIA_WINDOW_BACKEND_HPP + +#include <memory> +#include <vector> + +#include <SDL.h> + +#include <malikania/window.hpp> + +namespace malikania { + +class window::backend_impl { +private: + std::unique_ptr<SDL_Window, void (*)(SDL_Window *)> m_window; + std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer *)> m_renderer; + +public: + backend_impl(window& self, unsigned width, unsigned height, const std::string& title); + + inline SDL_Renderer* renderer() noexcept + { + return m_renderer.get(); + } + + void poll(window& self); + + void close(); + + void clear(); + + void present(); + + color drawing_color() const; + + void set_drawing_color(const color& color); + + void draw_line(const line& line); + + void draw_lines(const std::vector<point>& points); + + void draw_point(const point& point); + + void draw_points(const std::vector<point>& points); + + void draw_rectangle(const rectangle& rect); + + void draw_rectangles(const std::vector<rectangle>& rects); + + void fill_rectangle(const rectangle& rect); + + void fill_rectangles(const std::vector<rectangle>& rects); + + void draw_text(const std::string& text, font& font, const rectangle& rectangle); + + void draw_text(const std::string& text, font& font, const point& point); +}; + +} // !malikania + +#endif // !MALIKANIA_WINDOW_BACKEND_HPP
--- a/libclient/malikania/client-resources-loader.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * client-resources-loader.cpp -- load shared resources files for the client - * - * 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 <cassert> - -#include "animation.hpp" -#include "client-resources-loader.hpp" -#include "size.hpp" -#include "sprite.hpp" - -using json = nlohmann::json; - -namespace malikania { - -Size ClientResourcesLoader::requireSize(const std::string &id, const json &object, const std::string &property) const -{ - assert(object.is_object()); - - auto it = object.find(property); - - if (it == object.end() || !it->is_array()) - throw std::runtime_error(id + ": missing '" + property + "' property (array expected)"); - if (it->size() != 2) - throw std::runtime_error(id + ": property '" + property + "' must have two values"); - if (!(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) - throw std::runtime_error(id + ": property '" + property + "' must have to integer values"); - - return Size((*it)[0].get<int>(), (*it)[1].get<int>()); -} - -Size ClientResourcesLoader::getSize(const std::string &, const json &object, const std::string &key) const noexcept -{ - assert(object.is_object()); - - auto it = object.find(key); - - if (it == object.end() || !it->is_array() || it->size() != 2 || !(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) - return Size(); - - return Size((*it)[0].get<int>(), (*it)[1].get<int>()); -} - -Font ClientResourcesLoader::loadFont(const std::string &id, unsigned size) -{ - return Font(locator().read(id), size); -} - -Image ClientResourcesLoader::loadImage(const std::string &id) -{ - return Image(locator().read(id)); -} - -Sprite ClientResourcesLoader::loadSprite(const std::string &id) -{ - auto value = json::parse(locator().read(id)); - - if (!value.is_object()) - throw std::runtime_error(id + ": not a JSON object"); - - return Sprite( - loadImage(requireString(id, value, "image")), - requireSize(id, value, "cell"), - getSize(id, value, "size"), - getSize(id, value, "space"), - getSize(id, value, "margin") - ); -} - -Animation ClientResourcesLoader::loadAnimation(const std::string &id) -{ - auto value = json::parse(locator().read(id)); - - if (!value.is_object()) - throw std::runtime_error(id + ": not a JSON object"); - - Sprite sprite = loadSprite(requireString(id, value, "sprite")); - - // Load all frames. - json property = value["frames"]; - - if (!property.is_array()) - throw std::runtime_error(id + ": missing 'frames' property (array expected)"); - - AnimationFrames frames; - - int index = 0; - for (auto it = property.begin(); it != property.end(); ++it) { - if (!it->is_object()) - throw std::runtime_error(id + ": frame " + std::to_string(index) + ": not a JSON object"); - - auto delay = it->find("delay"); - - if (delay == it->end() || !delay->is_number_integer()) - throw std::runtime_error(id + ": frame " + std::to_string(index) + ": missing 'delay' property (int expected)"); - - frames.emplace_back(delay->get<int>()); - } - - return Animation(std::move(sprite), std::move(frames)); -} - -} // !malikania
--- a/libclient/malikania/client-resources-loader.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * client-resources-loader.hpp -- load shared resources files for the client - * - * 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_CLIENT_RESOURCES_LOADER_HPP -#define MALIKANIA_CLIENT_RESOURCES_LOADER_HPP - -#include <malikania/resources-loader.hpp> - -#include "animation.hpp" -#include "font.hpp" -#include "image.hpp" -#include "size.hpp" -#include "sprite.hpp" - -namespace malikania { - -/** - * \class ClientResourcesLoader - * \brief Load client resources. - */ -class ClientResourcesLoader : public ResourcesLoader { -protected: - /** - * Require a size object from an object property. - * - * The size is an array of two integers (e.g. [ 1, 2 ]). - * - * \pre object.isObject() - * \param id the resource id - * \param object the object - * \param property the property - * \return the size - * \throw std::runtime_error if the property is not a size - */ - Size requireSize(const std::string &id, const nlohmann::json &object, const std::string &property) const; - - /** - * Get a size object or a default one if not present or invalid. - * - * \pre object.isObject() - * \param id the resource id - * \param object the object - * \param property the property - * \return the size or default one - */ - Size getSize(const std::string &id, const nlohmann::json &object, const std::string &property) const noexcept; - -public: - /** - * Client resources loader constructor. - * - * The window is required because some of the resources require it. - * - * \param window the window - * \param locator the resources locator - */ - inline ClientResourcesLoader(ResourcesLocator &locator) - : ResourcesLoader(locator) - { - } - - /** - * Load a font. - * - * \param id the resource id - * \param size the desired size - * \return the font - * \throw std::runtime_error on errors - */ - virtual Font loadFont(const std::string &id, unsigned size); - - /** - * Load an image. - * - * \param id the resource id - * \return the image - * \throw std::runtime_error on errors - */ - virtual Image loadImage(const std::string &id); - - /** - * Load a sprite. - * - * \param id the resource id - * \return the sprite - * \throw std::runtime_error on errors - */ - virtual Sprite loadSprite(const std::string &id); - - /** - * Load an animation. - * - * \param id the resource id - * \return the animation - * \throw std::runtime_error on errors - */ - virtual Animation loadAnimation(const std::string &id); -}; - -} // !malikania - -#endif // !MALIKANIA_CLIENT_RESOURCES_LOADER_HPP
--- a/libclient/malikania/client.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/client.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -19,6 +19,8 @@ #ifndef MALIKANIA_CLIENT_HPP #define MALIKANIA_CLIENT_HPP +#if 0 + #include <memory> #include "window.hpp" @@ -70,4 +72,6 @@ } // !malikania +#endif + #endif // !MALIKANIA_CLIENT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client_resources_loader.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,134 @@ +/* + * client_resources_loader.cpp -- load shared resources files for the client + * + * 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 <boost/format.hpp> + +#include <cassert> + +#include "animation.hpp" +#include "client_resources_loader.hpp" +#include "size.hpp" +#include "sprite.hpp" + +using boost::str; +using boost::format; + +namespace malikania { + +size client_resources_loader::require_size(const std::string& id, + const nlohmann::json& object, + const std::string& property) const +{ + assert(object.is_object()); + + auto it = object.find(property); + + if (it == object.end() || !it->is_array()) { + throw std::runtime_error(str(format("%s: missing '%' property (array expected)") % id % property)); + } + if (it->size() != 2) { + throw std::runtime_error(str(format("%s: property '%s' muve have two values") % id % property)); + } + if (!(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) { + throw std::runtime_error(str(format("%s: property '%s' must contains two ints"))); + } + + return size((*it)[0].get<int>(), (*it)[1].get<int>()); +} + +size client_resources_loader::get_size(const std::string&, + const nlohmann::json& object, + const std::string& key) const noexcept +{ + assert(object.is_object()); + + auto it = object.find(key); + + if (it == object.end() || !it->is_array() || it->size() != 2 || + !(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) { + return size(); + } + + return size((*it)[0].get<int>(), (*it)[1].get<int>()); +} + +font client_resources_loader::load_font(const std::string& id, unsigned size) +{ + return font(locator().read(id), size); +} + +image client_resources_loader::load_image(const std::string& id) +{ + return image(locator().read(id)); +} + +sprite client_resources_loader::load_sprite(const std::string& id) +{ + auto value = nlohmann::json::parse(locator().read(id)); + + if (!value.is_object()) { + throw std::runtime_error(id + ": not a JSON object"); + } + + return sprite( + load_image(require_string(id, value, "image")), + require_size(id, value, "cell"), + get_size(id, value, "size"), + get_size(id, value, "space"), + get_size(id, value, "margin") + ); +} + +animation client_resources_loader::load_animation(const std::string& id) +{ + auto value = nlohmann::json::parse(locator().read(id)); + + if (!value.is_object()) { + throw std::runtime_error(id + ": not a JSON object"); + } + + auto sprite = load_sprite(require_string(id, value, "sprite")); + + // Load all frames. + auto property = value["frames"]; + + if (!property.is_array()) { + throw std::runtime_error(id + ": missing 'frames' property (array expected)"); + } + + animation_frames frames; + int index = 0; + + for (auto it = property.begin(); it != property.end(); ++it) { + if (!it->is_object()) { + throw std::runtime_error(id + ": frame " + std::to_string(index) + ": not a JSON object"); + } + + auto delay = it->find("delay"); + + if (delay == it->end() || !delay->is_number_integer()) { + throw std::runtime_error(id + ": frame " + std::to_string(index) + ": missing 'delay' property (int expected)"); + } + + frames.emplace_back(delay->get<int>()); + } + + return animation(std::move(sprite), std::move(frames)); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client_resources_loader.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,125 @@ +/* + * client_resources_loader.hpp -- load shared resources files for the client + * + * 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_CLIENT_RESOURCES_LOADER_HPP +#define MALIKANIA_CLIENT_RESOURCES_LOADER_HPP + +/* + * \file client_resources_loader.hpp + * \brief Load client assets. + */ + +#include <malikania/resources_loader.hpp> + +#include "animation.hpp" +#include "font.hpp" +#include "image.hpp" +#include "size.hpp" +#include "sprite.hpp" + +namespace malikania { + +/** + * \brief Load client resources. + */ +class client_resources_loader : public resources_loader { +protected: + /** + * Require a size object from an object property. + * + * The size is an array of two integers (e.g. [ 1, 2 ]). + * + * \pre object.is_object() + * \param id the resource id + * \param object the object + * \param property the property + * \return the size + * \throw std::runtime_error if the property is not a size + */ + size require_size(const std::string& id, + const nlohmann::json& object, + const std::string& property) const; + + /** + * Get a size object or a default one if not present or invalid. + * + * \pre object.is_object() + * \param id the resource id + * \param object the object + * \param property the property + * \return the size or default one + */ + size get_size(const std::string& id, + const nlohmann::json& object, + const std::string& property) const noexcept; + +public: + /** + * Client resources loader constructor. + * + * The window is required because some of the resources require it. + * + * \param window the window + * \param locator the resources locator + */ + inline client_resources_loader(resources_locator& locator) + : resources_loader(locator) + { + } + + /** + * Load a font. + * + * \param id the resource id + * \param size the desired size + * \return the font + * \throw std::runtime_error on errors + */ + virtual font load_font(const std::string& id, unsigned size); + + /** + * Load an image. + * + * \param id the resource id + * \return the image + * \throw std::runtime_error on errors + */ + virtual image load_image(const std::string& id); + + /** + * Load a sprite. + * + * \param id the resource id + * \return the sprite + * \throw std::runtime_error on errors + */ + virtual sprite load_sprite(const std::string& id); + + /** + * Load an animation. + * + * \param id the resource id + * \return the animation + * \throw std::runtime_error on errors + */ + virtual animation load_animation(const std::string& id); +}; + +} // !malikania + +#endif // !MALIKANIA_CLIENT_RESOURCES_LOADER_HPP
--- a/libclient/malikania/color.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/color.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -16,8 +16,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <cctype> +#include <locale> #include <unordered_map> -#include <cctype> #include "color.hpp" @@ -35,10 +36,12 @@ */ std::uint8_t value(char digit) { - if (std::isdigit(digit)) + if (std::isdigit(digit, {})) { return digit - '0'; - if ((digit = std::toupper(digit)) < 'A' || digit > 'F') + } + if ((digit = std::toupper(digit, {})) < 'A' || digit > 'F') { throw std::invalid_argument("invalid hexadecimal value: " + std::to_string(digit)); + } return digit - 55; } @@ -201,7 +204,7 @@ } // !namespace -Color::Color(const std::string &name) +color::color(const std::string& name) { if (!name.empty()) { // Parse #rrggbb or #rgb. @@ -214,14 +217,16 @@ m_red = value(name[1], name[1]); m_green = value(name[2], name[2]); m_blue = value(name[3], name[3]); - } else + } else { throw std::invalid_argument("invalid format"); + } } else { // Name lookup. auto it = colors.find(name); - if (it == colors.end()) + if (it == colors.end()) { throw std::invalid_argument(name + " is not a valid color"); + } // Assign the color to *this. *this = it->second;
--- a/libclient/malikania/color.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/color.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -19,16 +19,20 @@ #ifndef MALIKANIA_COLOR_HPP #define MALIKANIA_COLOR_HPP +/** + * \file color.hpp + * \brief Colors. + */ + #include <cstdint> #include <string> namespace malikania { /** - * \class Color - * \brief Color description + * \brief color description */ -class Color { +class color { private: std::uint8_t m_red{0}; std::uint8_t m_green{0}; @@ -39,7 +43,7 @@ /** * Default color to black. */ - inline Color() noexcept = default; + inline color() noexcept = default; /** * Constructor with all fields. @@ -49,7 +53,7 @@ * \param blue the blue value * \param alpha the alpha value */ - inline Color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha) noexcept + inline color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha) noexcept : m_red(red) , m_green(green) , m_blue(blue) @@ -62,7 +66,7 @@ * * \param hex the color */ - inline Color(std::uint32_t hex) noexcept + inline color(std::uint32_t hex) noexcept : m_red((hex >> 16) & 0xff) , m_green((hex >> 8) & 0xff) , m_blue(hex & 0xff) @@ -78,7 +82,7 @@ * \param name the color name * \throw std::invalid_argument if the color does not exist or is invalid */ - Color(const std::string &name); + color(const std::string& name); /** * Get the red value.
--- a/libclient/malikania/font.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/font.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -16,25 +16,25 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "font-backend.hpp" +#include "font_backend.hpp" namespace malikania { -Font::Font(std::string data, unsigned size) - : m_backend(std::make_unique<Backend>(std::move(data), size)) +font::font(std::string data, unsigned size) + : m_backend(std::make_unique<backend_impl>(std::move(data), size)) , m_size(size) { } -Font::Font(Font &&other) noexcept = default; +font::font(font&& other) noexcept = default; -Font::~Font() noexcept = default; +font::~font() noexcept = default; -Size Font::clip(const std::string &text) const +size font::clip(const std::string& text) const { return m_backend->clip(*this, text); } -Font &Font::operator=(Font &&other) noexcept = default; +font& font::operator=(font&& other) noexcept = default; } // !malikania
--- a/libclient/malikania/font.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/font.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -20,8 +20,8 @@ #define MALIKANIA_FONT_HPP /** - * \file Font.hpp - * \brief Fonts. + * \file font.hpp + * \brief fonts. */ #include <memory> @@ -32,14 +32,13 @@ namespace malikania { /** - * \class Font - * \brief Font object. + * \brief font object. */ -class Font { +class font { private: - class Backend; + class backend_impl; - std::unique_ptr<Backend> m_backend; + std::unique_ptr<backend_impl> m_backend; unsigned m_size; public: @@ -49,19 +48,19 @@ * \param data the raw data * \param size the size */ - Font(std::string data, unsigned size); + font(std::string data, unsigned size); /** * Default move constructor. * * \param other the other font */ - Font(Font &&other) noexcept; + font(font&& other) noexcept; /** * Default destructor. */ - virtual ~Font() noexcept; + virtual ~font() noexcept; /** * Get the font size. @@ -78,7 +77,7 @@ * * \return the backend */ - inline const Backend &backend() const noexcept + inline const backend_impl& backend() const noexcept { return *m_backend; } @@ -88,7 +87,7 @@ * * \return the backend */ - inline Backend &backend() noexcept + inline backend_impl& backend() noexcept { return *m_backend; } @@ -99,7 +98,7 @@ * \param text the text to clip * \return the required size */ - Size clip(const std::string &text) const; + malikania::size clip(const std::string& text) const; /** * Default move assignment operator. @@ -107,7 +106,7 @@ * \param other the other font * \return this */ - Font &operator=(Font &&other) noexcept; + font& operator=(font&& other) noexcept; }; } // !malikania
--- a/libclient/malikania/image.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/image.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -16,34 +16,34 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "image-backend.hpp" +#include "image_backend.hpp" namespace malikania { -Image::Image(std::string data) - : m_backend(std::make_unique<Backend>(*this, std::move(data))) +image::image(std::string data) + : m_backend(new backend_impl(*this, std::move(data))) { } -Image::Image(Image &&) noexcept = default; +image::image(image&&) noexcept = default; -Image::~Image() noexcept = default; +image::~image() noexcept = default; -const Size &Image::size() const noexcept +const malikania::size& image::size() const noexcept { return m_backend->size(); } -void Image::draw(Window &window, const Point &position) +void image::draw(window& window, const point& position) { m_backend->draw(window, position); } -void Image::draw(Window &window, const Rectangle &source, const Rectangle &target) +void image::draw(window& window, const rectangle& source, const rectangle& target) { m_backend->draw(window, source, target); } -Image &Image::operator=(Image &&) noexcept = default; +image& image::operator=(image&&) noexcept = default; } // !malikania
--- a/libclient/malikania/image.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/image.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -33,17 +33,16 @@ namespace malikania { -class Window; +class window; /** - * \class Image * \brief Image object. */ -class Image { +class image { private: - class Backend; + class backend_impl; - std::unique_ptr<Backend> m_backend; + std::unique_ptr<backend_impl> m_backend; public: /** @@ -52,26 +51,26 @@ * \param window the window * \param data the data */ - Image(std::string data); + image(std::string data); /** * Default move constructor. * * \param other the other image */ - Image(Image &&other) noexcept; + image(image&& other) noexcept; /** * Default destructor. */ - ~Image() noexcept; + ~image() noexcept; /** * Overloaded function. * * \return the backend */ - inline Backend &backend() noexcept + inline class backend_impl& backend() noexcept { return *m_backend; } @@ -81,7 +80,7 @@ * * \return the backend */ - inline const Backend &backend() const noexcept + inline const backend_impl& backend() const noexcept { return *m_backend; } @@ -91,7 +90,7 @@ * * \return the size */ - const Size &size() const noexcept; + const malikania::size& size() const noexcept; /** * Draw the image to the window. @@ -99,7 +98,7 @@ * \param window the window * \param position the position */ - void draw(Window &window, const Point &position = {0, 0}); + void draw(window& window, const point& position = {0, 0}); /** * Overloaded function. @@ -108,7 +107,7 @@ * \param source the source to clip * \param target the target destination */ - void draw(Window &window, const Rectangle &source, const Rectangle &target); + void draw(window& window, const rectangle& source, const rectangle& target); /** * Default move assignment operator. @@ -116,7 +115,7 @@ * \param other the other image * \return this */ - Image &operator=(Image &&image) noexcept; + image& operator=(image&& image) noexcept; }; } // !malikania
--- a/libclient/malikania/line.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/line.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,18 +21,17 @@ /** * \file line.hpp - * \brief Line description. + * \brief line description. */ namespace malikania { /** - * \class Line - * \brief Line description. + * \brief line description. * * A line has an origin (x, y) and a destination (x, y). */ -class Line { +class line { private: int m_x1; int m_y1; @@ -48,7 +47,7 @@ * \param x2 the second x * \param y2 the second y */ - inline Line(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) noexcept + inline line(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) noexcept : m_x1(x1) , m_y1(y1) , m_x2(x2) @@ -104,7 +103,7 @@ * \param l2 the second line * \return true if they equal */ -inline bool operator==(const Line &l1, const Line &l2) noexcept +inline bool operator==(const line& l1, const line& l2) noexcept { return l1.x1() == l2.x1() && l1.x2() == l2.x2() && l1.y1() == l2.y1() && l1.y2() == l2.y2(); } @@ -116,7 +115,7 @@ * \param l2 the second line * \return false if they equal */ -inline bool operator!=(const Line &l1, const Line &l2) noexcept +inline bool operator!=(const line& l1, const line& l2) noexcept { return !(l1 == l2); }
--- a/libclient/malikania/point.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/point.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,16 +21,15 @@ /** * \file point.hpp - * \brief Point description. + * \brief point description. */ namespace malikania { /** - * \class Point - * \brief Point coordinate. + * \brief point coordinate. */ -class Point { +class point { private: int m_x; int m_y; @@ -42,7 +41,7 @@ * \param x the x * \param y the y */ - inline Point(int x = 0, int y = 0) noexcept + inline point(int x = 0, int y = 0) noexcept : m_x(x) , m_y(y) { @@ -76,7 +75,7 @@ * \param p2 the second point * \return true if they equal */ -inline bool operator==(const Point &p1, const Point &p2) noexcept +inline bool operator==(const point& p1, const point& p2) noexcept { return p1.x() == p2.x() && p1.y() == p2.y(); } @@ -88,7 +87,7 @@ * \param p2 the second point * \return false if they equal */ -inline bool operator!=(const Point &p1, const Point &p2) noexcept +inline bool operator!=(const point& p1, const point& p2) noexcept { return !(p1 == p2); }
--- a/libclient/malikania/rectangle.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/rectangle.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,20 +21,19 @@ /** * \file rectangle.hpp - * \brief Rectangle description. + * \brief rectangle description. */ namespace malikania { /** - * \class Rectangle - * \brief Rectangle description. + * \brief rectangle description. * * A rectangle has coordinates (x, y) and dimensions (width, height). * * They are commonly used for clipping images into the window. */ -class Rectangle { +class rectangle { private: int m_x; int m_y; @@ -50,7 +49,7 @@ * \param width the width * \param height the height */ - inline Rectangle(int x = 0, int y = 0, unsigned width = 0, unsigned height = 0) noexcept + inline rectangle(int x = 0, int y = 0, unsigned width = 0, unsigned height = 0) noexcept : m_x(x) , m_y(y) , m_width(width) @@ -103,7 +102,7 @@ * * \return true if weight and height are 0 */ - inline bool isNull() const noexcept + inline bool is_null() const noexcept { return m_width == 0 && m_height == 0; } @@ -116,9 +115,10 @@ * \param r2 the second rectangle * \return true if they equal */ -inline bool operator==(const Rectangle &r1, const Rectangle &r2) noexcept +inline bool operator==(const rectangle& r1, const rectangle& r2) noexcept { - return r1.x() == r2.x() && r1.y() == r2.y() && r1.width() == r2.width() && r1.height() == r2.height(); + return r1.x() == r2.x() && r1.y() == r2.y() && + r1.width() == r2.width() && r1.height() == r2.height(); } /** @@ -128,7 +128,7 @@ * \param r2 the second rectangle * \return false if they equal */ -inline bool operator!=(const Rectangle &r1, const Rectangle &r2) noexcept +inline bool operator!=(const rectangle& r1, const rectangle& r2) noexcept { return !(r1 == r2); }
--- a/libclient/malikania/size.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/size.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -22,10 +22,9 @@ namespace malikania { /** - * \class Size - * \brief Size description. + * \brief size description. */ -class Size { +class size { private: unsigned m_width; unsigned m_height; @@ -37,7 +36,7 @@ * \param width the size width * \param height the size height */ - inline Size(unsigned width = 0, unsigned height = 0) noexcept + inline size(unsigned width = 0, unsigned height = 0) noexcept : m_width(width) , m_height(height) { @@ -68,7 +67,7 @@ * * \return true if height and width are 0 */ - inline bool isNull() const noexcept + inline bool is_null() const noexcept { return m_height == 0 && m_width == 0; } @@ -81,7 +80,7 @@ * \param s2 the second size * \return true if they equal */ -inline bool operator==(const Size &s1, const Size &s2) noexcept +inline bool operator==(const size& s1, const size& s2) noexcept { return s1.width() == s2.width() && s1.height() == s2.height(); } @@ -93,7 +92,7 @@ * \param s2 the second size * \return false if they equal */ -inline bool operator!=(const Size &s1, const Size &s2) noexcept +inline bool operator!=(const size& s1, const size& s2) noexcept { return !(s1 == s2); }
--- a/libclient/malikania/sprite.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/sprite.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -22,7 +22,11 @@ namespace malikania { -Sprite::Sprite(Image image, Size cell, Size size, Size space, Size margin) noexcept +sprite::sprite(malikania::image image, + malikania::size cell, + malikania::size size, + malikania::size space, + malikania::size margin) noexcept : m_image(std::move(image)) , m_cell(std::move(cell)) , m_margin(std::move(margin)) @@ -33,15 +37,16 @@ assert(m_cell.height() > 0); // If size is not specified, take from image. - if (m_size.isNull()) + if (m_size.is_null()) { m_size = m_image.size(); + } // Compute number of cells. m_rows = (m_size.height() - (margin.height() * 2) + m_space.height()) / (m_cell.height() + m_space.height()); m_columns = (m_size.width() - (m_margin.width() * 2) + m_space.width()) / (m_cell.width() + m_space.width()); } -void Sprite::draw(Window &window, unsigned cell, const Point &point) +void sprite::draw(window& window, unsigned cell, const point& point) { assert(cell < m_rows * m_columns); @@ -53,8 +58,8 @@ int x = m_margin.width() + (hindex * m_space.width()) + (hindex * m_cell.width()); int y = m_margin.height() + (vindex * m_space.height()) + (vindex * m_cell.height()); - Rectangle source(x, y, m_cell.width(), m_cell.height()); - Rectangle target(point.x(), point.y(), m_cell.width(), m_cell.height()); + rectangle source(x, y, m_cell.width(), m_cell.height()); + rectangle target(point.x(), point.y(), m_cell.width(), m_cell.height()); m_image.draw(window, source, target); }
--- a/libclient/malikania/sprite.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/sprite.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -28,20 +28,16 @@ namespace malikania { -class Point; -class Window; - /** - * \class Sprite * \brief A Sprite is an image divided into cells. */ -class Sprite { +class sprite { private: - Image m_image; - Size m_cell; - Size m_margin; - Size m_space; - Size m_size; + malikania::image m_image; + malikania::size m_cell; + malikania::size m_margin; + malikania::size m_space; + malikania::size m_size; unsigned m_rows; unsigned m_columns; @@ -56,14 +52,18 @@ * \param space the optional space between cells * \param size the sprite size (if 0, taken from the image) */ - Sprite(Image image, Size cell, Size margin = { 0, 0 }, Size space = { 0, 0 }, Size size = { 0, 0 }) noexcept; + sprite(malikania::image image, + malikania::size cell, + malikania::size margin = { 0, 0 }, + malikania::size space = { 0, 0 }, + malikania::size size = { 0, 0 }) noexcept; /** * Get the underlying image. * * \return the image */ - inline const Image &image() const noexcept + inline const malikania::image& image() const noexcept { return m_image; } @@ -73,7 +73,7 @@ * * \return the image */ - inline Image &image() noexcept + inline malikania::image& image() noexcept { return m_image; } @@ -83,7 +83,7 @@ * * \return the cell size */ - inline const Size &cell() const noexcept + inline const size& cell() const noexcept { return m_cell; } @@ -93,7 +93,7 @@ * * \return the margin size */ - inline const Size &margin() noexcept + inline const size& margin() noexcept { return m_margin; } @@ -103,7 +103,7 @@ * * \return the space size */ - inline const Size &space() const noexcept + inline const size& space() const noexcept { return m_space; } @@ -136,7 +136,7 @@ * \param cell the cell index * \param position the position in the window */ - void draw(Window &window, unsigned cell, const Point &position); + void draw(window& window, unsigned cell, const point& position); }; } // !malikania
--- a/libclient/malikania/window.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/window.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -19,100 +19,100 @@ #include <stdexcept> #include "color.hpp" -#include "window-backend.hpp" +#include "window_backend.hpp" namespace malikania { -Window::Window(unsigned width, unsigned height, const std::string &title) - : m_backend(std::make_unique<Backend>(*this, width, height, title)) +window::window(unsigned width, unsigned height, const std::string& title) + : m_backend(std::make_unique<backend_impl>(*this, width, height, title)) { } -Window::Window(Window &&) = default; +window::window(window&&) noexcept = default; -Window::~Window() = default; +window::~window() noexcept = default; -void Window::poll() +void window::poll() { m_backend->poll(*this); } -void Window::clear() +void window::clear() { m_backend->clear(); } -void Window::present() +void window::present() { m_backend->present(); } -void Window::close() noexcept +void window::close() noexcept { - m_isOpen = false; + m_is_open = false; m_backend->close(); } -Color Window::drawingColor() const +color window::drawing_color() const { - return m_backend->drawingColor(); + return m_backend->drawing_color(); } -void Window::setDrawingColor(const Color &color) +void window::set_drawing_color(const color& color) { - m_backend->setDrawingColor(color); + m_backend->set_drawing_color(color); } -void Window::drawLine(const Line &line) +void window::draw_line(const line& line) { - m_backend->drawLine(line); + m_backend->draw_line(line); } -void Window::drawLines(const std::vector<Point> &points) +void window::draw_lines(const std::vector<point>& points) { - m_backend->drawLines(points); + m_backend->draw_lines(points); } -void Window::drawPoint(const Point &point) +void window::draw_point(const point& point) { - m_backend->drawPoint(point); + m_backend->draw_point(point); } -void Window::drawPoints(const std::vector<Point> &points) +void window::draw_points(const std::vector<point>& points) { - m_backend->drawPoints(points); + m_backend->draw_points(points); } -void Window::drawRectangle(const Rectangle &rectangle) +void window::draw_rectangle(const rectangle& rectangle) { - m_backend->drawRectangle(rectangle); + m_backend->draw_rectangle(rectangle); } -void Window::drawRectangles(const std::vector<Rectangle> &rectangles) +void window::draw_rectangles(const std::vector<rectangle>& rectangles) { - m_backend->drawRectangles(rectangles); + m_backend->draw_rectangles(rectangles); } -void Window::fillRectangle(const Rectangle &rectangle) +void window::fill_rectangle(const rectangle& rectangle) { - m_backend->fillRectangle(rectangle); + m_backend->fill_rectangle(rectangle); } -void Window::fillRectangles(const std::vector<Rectangle> &rectangles) +void window::fill_rectangles(const std::vector<rectangle>& rectangles) { - m_backend->fillRectangles(rectangles); + m_backend->fill_rectangles(rectangles); } -void Window::drawText(const std::string &text, Font &font, const Rectangle &rectangle) +void window::draw_text(const std::string& text, font& font, const rectangle& rectangle) { - m_backend->drawText(text, font, rectangle); + m_backend->draw_text(text, font, rectangle); } -void Window::drawText(const std::string &text, Font &font, const Point &point) +void window::draw_text(const std::string& text, font& font, const point& point) { - m_backend->drawText(text, font, point); + m_backend->draw_text(text, font, point); } -Window &Window::operator=(Window &&) = default; +window& window::operator=(window&&) noexcept = default; } // !malikania
--- a/libclient/malikania/window.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libclient/malikania/window.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -31,61 +31,24 @@ namespace malikania { -class Color; -class Line; -class Font; -class Point; -class Rectangle; +class color; +class line; +class font; +class point; +class rectangle; /** * \brief Main window class and drawing. */ -class Window { +class window { private: - class Backend; + class backend_impl; - std::function<void ()> m_onQuit; - std::function<void (unsigned)> m_onKeyDown; - std::function<void (unsigned)> m_onKeyUp; + std::unique_ptr<backend_impl> m_backend; - std::unique_ptr<Backend> m_backend; - - bool m_isOpen{true}; + bool m_is_open{true}; public: - inline void onQuit() - { - if (m_onQuit) - m_onQuit(); - } - - inline void onKeyDown(unsigned key) - { - if (m_onKeyDown) - m_onKeyDown(key); - } - - inline void onKeyUp(unsigned key) - { - if (m_onKeyUp) - m_onKeyUp(key); - } - - inline void setOnQuit(std::function<void ()> fn) noexcept - { - m_onQuit = std::move(fn); - } - - inline void setOnKeyDown(std::function<void (unsigned)> fn) noexcept - { - m_onKeyDown = std::move(fn); - } - - inline void setOnKeyUp(std::function<void (unsigned)> fn) noexcept - { - m_onKeyUp = std::move(fn); - } - /** * Create a window. * @@ -94,26 +57,26 @@ * \param title the optional title * \throw std::runtime_error on errors */ - Window(unsigned width = 640, unsigned height = 480, const std::string &title = "Malikania"); + window(unsigned width = 640, unsigned height = 480, const std::string& title = "Malikania Engine"); /** * Move constructor defaulted. */ - Window(Window &&); + window(window&&) noexcept; /** * Virtual destructor defaulted. */ - virtual ~Window(); + virtual ~window() noexcept; /** * Tells if the window is open. * * \return true if open */ - inline bool isOpen() const noexcept + inline bool is_open() const noexcept { - return m_isOpen; + return m_is_open; } /** @@ -121,7 +84,7 @@ * * \return the backend */ - inline const Backend &backend() const noexcept + inline const backend_impl& backend() const noexcept { return *m_backend; } @@ -131,7 +94,7 @@ * * \return the backend */ - inline Backend &backend() noexcept + inline backend_impl& backend() noexcept { return *m_backend; } @@ -161,42 +124,42 @@ * * \return the color */ - Color drawingColor() const; + color drawing_color() const; /** * Set the drawing color. * * \param color the color */ - void setDrawingColor(const Color &color); + void set_drawing_color(const color& color); /** * Draw a line. * * \param line the line */ - void drawLine(const Line &line); + void draw_line(const line& line); /** * Draw a several lines. * * \param the lines vertices */ - void drawLines(const std::vector<Point> &points); + void draw_lines(const std::vector<point>& points); /** * Draw a point. * * \param point the point */ - void drawPoint(const Point &point); + void draw_point(const point& point); /** * Draw a list of points. * * \param points the points */ - void drawPoints(const std::vector<Point> &points); + void draw_points(const std::vector<point>& points); /** * Draw a rectangle (only borders). @@ -204,7 +167,7 @@ * \param rect the rectangle * \see fillRectangle */ - void drawRectangle(const Rectangle &rect); + void draw_rectangle(const rectangle& rect); /** * Draw a list of rectangles. @@ -212,7 +175,7 @@ * \param rects the rectangles * \see fillRectangles */ - void drawRectangles(const std::vector<Rectangle> &rects); + void draw_rectangles(const std::vector<rectangle>& rects); /** * Fill the given rectangle with the current color. @@ -220,7 +183,7 @@ * \param rect the rectangle * \see drawRectangle */ - void fillRectangle(const Rectangle &rect); + void fill_rectangle(const rectangle& rect); /** * Fill the list of rectangles with the current color. @@ -228,7 +191,7 @@ * \param rects the list of rectangles * \see drawRectangles */ - void fillRectangles(const std::vector<Rectangle> &rects); + void fill_rectangles(const std::vector<rectangle>& rects); /** * Draw some text. @@ -239,7 +202,7 @@ * \param font the font * \param rectangle the rectangle target */ - void drawText(const std::string &text, Font &font, const Rectangle &rectangle); + void draw_text(const std::string& text, font& font, const rectangle& rectangle); /** * Overloaded function. @@ -250,16 +213,16 @@ * \param font the font * \param point the text position */ - void drawText(const std::string &text, Font &font, const Point &point); + void draw_text(const std::string& text, font& font, const point& point); /** * Move assigment operator defaulted. * * \return this */ - Window &operator=(Window &&); + window& operator=(window&&) noexcept; }; } // !malikania -#endif // !_MALIKANIA_WINDOW_HPP_ +#endif // !MALIKANIA_WINDOW_HPP
--- a/libcommon-js/CMakeLists.txt Sun Nov 27 20:50:38 2016 +0100 +++ b/libcommon-js/CMakeLists.txt Tue Nov 29 21:21:36 2016 +0100 @@ -20,14 +20,14 @@ set( HEADERS - ${libcommon-js_SOURCE_DIR}/malikania/js-elapsed-timer.hpp - ${libcommon-js_SOURCE_DIR}/malikania/js-resources-loader.hpp + ${libcommon-js_SOURCE_DIR}/malikania/js_elapsed_timer.hpp + ${libcommon-js_SOURCE_DIR}/malikania/js_resources_loader.hpp ) set( SOURCES - ${libcommon-js_SOURCE_DIR}/malikania/js-elapsed-timer.cpp - ${libcommon-js_SOURCE_DIR}/malikania/js-resources-loader.cpp + ${libcommon-js_SOURCE_DIR}/malikania/js_elapsed_timer.cpp + ${libcommon-js_SOURCE_DIR}/malikania/js_resources_loader.cpp ) malikania_create_library(
--- a/libcommon-js/malikania/js-elapsed-timer.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* - * js-elapsed-timer.cpp -- - * - * Copyright (c) 2013-2016 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 <boost/timer/timer.hpp> - -#include <cassert> -#include <string> - -#include "duktape.hpp" - -namespace malikania { - -namespace { - -const std::string Signature("\xff" "\xff" "malikania-elapsed-timer-ptr"); - -boost::timer::cpu_timer& self(duk_context *ctx) -{ - StackAssert sa(ctx); - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, Signature.c_str()); - auto ptr = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!ptr) - duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an ElapsedTimer object"); - - return *static_cast<boost::timer::cpu_timer*>(ptr); -} - -/* - * Method: ElapsedTimer.pause - * ------------------------------------------------------------------ - * - * Pause the timer, without resetting the current elapsed time stored. - */ -duk_ret_t pause(duk_context *ctx) -{ - self(ctx).stop(); - - return 0; -} - -/* - * Method: ElapsedTimer.reset - * ------------------------------------------------------------------ - * - * Reset the elapsed time to 0, the status is not modified. - */ -duk_ret_t reset(duk_context *ctx) -{ - self(ctx).start(); - - return 0; -} - -/* - * Method: ElapsedTimer.restart - * ------------------------------------------------------------------ - * - * Restart the timer without resetting the current elapsed time. - */ -duk_ret_t restart(duk_context *ctx) -{ - self(ctx).resume(); - - return 0; -} - -/* - * Method: ElapsedTimer.elapsed - * ------------------------------------------------------------------ - * - * Get the number of elapsed milliseconds. - * - * Returns: - * The time elapsed. - */ -duk_ret_t elapsed(duk_context *ctx) -{ - duk_push_uint(ctx, self(ctx).elapsed().wall / 1000000LL); - - return 1; -} - -/* - * Function: Malikania.ElapsedTimer() [constructor] - * ------------------------------------------------------------------ - * - * Construct a new ElapsedTimer object. - */ -duk_ret_t constructor(duk_context *ctx) -{ - duk_push_this(ctx); - duk_push_pointer(ctx, new boost::timer::cpu_timer); - duk_put_prop_string(ctx, -2, Signature.c_str()); - duk_pop(ctx); - - return 0; -} - -/* - * Function: Malikania.ElapsedTimer() [destructor] - * ------------------------------------------------------------------ - * - * Destroy the timer. - */ -duk_ret_t destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, Signature.c_str()); - delete static_cast<boost::timer::cpu_timer*>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, Signature.c_str()); - - return 0; -} - -const duk_function_list_entry methods[] = { - { "elapsed", elapsed, 0 }, - { "pause", pause, 0 }, - { "reset", reset, 0 }, - { "restart", restart, 0 }, - { nullptr, nullptr, 0 } -}; - -} // !namespace - -void dukx_load_elapsedtimer(duk_context *ctx) noexcept -{ - StackAssert sa(ctx); - - duk_get_global_string(ctx, "Malikania"); - duk_push_c_function(ctx, constructor, 0); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_prop_string(ctx, -2, "ElapsedTimer"); - duk_pop(ctx); -} - -} // !malikania
--- a/libcommon-js/malikania/js-elapsed-timer.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * js-elapsed-timer.hpp -- - * - * Copyright (c) 2013-2016 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 MALIKANIA_JS_ELAPSED_TIMER_HPP -#define MALIKANIA_JS_ELAPSED_TIMER_HPP - -#include "duktape.hpp" - -namespace malikania { - -void dukx_load_elapsedtimer(duk_context *ctx) noexcept; - -} // !malikania - -#endif // !MALIKANIA_JS_ELAPSED_TIMER_HPP -
--- a/libcommon-js/malikania/js-resources-loader.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * js-resources-loader.cpp --resources loader (JavaScript binding) - * - * Copyright (c) 2013-2016 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 <cassert> - -#include "js-resources-loader.hpp" - -namespace malikania { - -namespace { - -const std::string Variable("\xff""\xff""malikania-resources-loader"); - -} // !namespace - -void dukx_put_loader(duk_context *ctx, ResourcesLoader *loader) -{ - assert(ctx); - assert(loader); - - StackAssert sa(ctx); - - duk_push_pointer(ctx, loader); - duk_put_global_string(ctx, Variable.c_str()); -} - -ResourcesLoader *duk_require_loader(duk_context *ctx) -{ - assert(ctx); - - StackAssert sa(ctx); - - duk_get_global_string(ctx, Variable.c_str()); - auto ptr = static_cast<ResourcesLoader *>(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - - return static_cast<ResourcesLoader *>(ptr); -} - -} // !malikania
--- a/libcommon-js/malikania/js-resources-loader.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * js-resources-loader.hpp --resources loader (JavaScript binding) - * - * Copyright (c) 2013-2016 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 MALIKANIA_JS_RESOURCES_LOADER_H -#define MALIKANIA_JS_RESOURCES_LOADER_H - -#include "duktape.hpp" -#include "resources-loader.hpp" - -namespace malikania { - -void dukx_put_loader(duk_context *ctx, ResourcesLoader *); - -ResourcesLoader *dukx_get_loader(duk_context *ctx); - -} // !malikania - -#endif // !MALIKANIA_JS_RESOURCES_LOADER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon-js/malikania/js_elapsed_timer.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,160 @@ +/* + * js_elapsed_timer.cpp -- ElapsedTimer (JavaScript binding) + * + * Copyright (c) 2013-2016 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 <boost/timer/timer.hpp> + +#include <cassert> +#include <string> + +#include "duktape.hpp" + +namespace malikania { + +namespace { + +const std::string signature("\xff" "\xff" "malikania-elapsed-timer-ptr"); + +boost::timer::cpu_timer& self(duk_context* ctx) +{ + StackAssert sa(ctx); + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, signature.c_str()); + auto ptr = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!ptr) { + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an ElapsedTimer object"); + } + + return *static_cast<boost::timer::cpu_timer*>(ptr); +} + +/* + * Method: ElapsedTimer.pause + * ------------------------------------------------------------------ + * + * Pause the timer, without resetting the current elapsed time stored. + */ +duk_ret_t pause(duk_context* ctx) +{ + self(ctx).stop(); + + return 0; +} + +/* + * Method: ElapsedTimer.reset + * ------------------------------------------------------------------ + * + * Reset the elapsed time to 0, the status is not modified. + */ +duk_ret_t reset(duk_context* ctx) +{ + self(ctx).start(); + + return 0; +} + +/* + * Method: ElapsedTimer.restart + * ------------------------------------------------------------------ + * + * Restart the timer without resetting the current elapsed time. + */ +duk_ret_t restart(duk_context* ctx) +{ + self(ctx).resume(); + + return 0; +} + +/* + * Method: ElapsedTimer.elapsed + * ------------------------------------------------------------------ + * + * Get the number of elapsed milliseconds. + * + * Returns: + * The time elapsed. + */ +duk_ret_t elapsed(duk_context* ctx) +{ + duk_push_uint(ctx, self(ctx).elapsed().wall / 1000000LL); + + return 1; +} + +/* + * Function: Malikania.ElapsedTimer() [constructor] + * ------------------------------------------------------------------ + * + * Construct a new ElapsedTimer object. + */ +duk_ret_t constructor(duk_context* ctx) +{ + duk_push_this(ctx); + duk_push_pointer(ctx, new boost::timer::cpu_timer); + duk_put_prop_string(ctx, -2, signature.c_str()); + duk_pop(ctx); + + return 0; +} + +/* + * Function: Malikania.ElapsedTimer() [destructor] + * ------------------------------------------------------------------ + * + * Destroy the timer. + */ +duk_ret_t destructor(duk_context* ctx) +{ + duk_get_prop_string(ctx, 0, signature.c_str()); + delete static_cast<boost::timer::cpu_timer*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + duk_del_prop_string(ctx, 0, signature.c_str()); + + return 0; +} + +const duk_function_list_entry methods[] = { + { "elapsed", elapsed, 0 }, + { "pause", pause, 0 }, + { "reset", reset, 0 }, + { "restart", restart, 0 }, + { nullptr, nullptr, 0 } +}; + +} // !namespace + +void dukx_load_elapsedtimer(duk_context* ctx) noexcept +{ + StackAssert sa(ctx); + + duk_get_global_string(ctx, "Malikania"); + duk_push_c_function(ctx, constructor, 0); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_push_c_function(ctx, destructor, 1); + duk_set_finalizer(ctx, -2); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_prop_string(ctx, -2, "ElapsedTimer"); + duk_pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon-js/malikania/js_elapsed_timer.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,30 @@ +/* + * js_elapsed_timer.hpp -- ElapsedTimer (JavaScript binding) + * + * Copyright (c) 2013-2016 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 MALIKANIA_JS_ELAPSED_TIMER_HPP +#define MALIKANIA_JS_ELAPSED_TIMER_HPP + +#include "duktape.hpp" + +namespace malikania { + +void dukx_load_elapsedtimer(duk_context* ctx) noexcept; + +} // !malikania + +#endif // !MALIKANIA_JS_ELAPSED_TIMER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon-js/malikania/js_resources_loader.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,54 @@ +/* + * js_resources_loader.cpp -- resources loader (JavaScript binding) + * + * Copyright (c) 2013-2016 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 <cassert> + +#include "js_resources_loader.hpp" + +namespace malikania { + +namespace { + +const std::string variable("\xff""\xff""malikania-resources-loader"); + +} // !namespace + +void dukx_put_loader(duk_context *ctx, resources_loader& loader) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_push_pointer(ctx, &loader); + duk_put_global_string(ctx, variable.c_str()); +} + +resources_loader& duk_require_loader(duk_context* ctx) +{ + assert(ctx); + + StackAssert sa(ctx); + + duk_get_global_string(ctx, variable.c_str()); + auto ptr = static_cast<resources_loader*>(duk_to_pointer(ctx, -1)); + duk_pop(ctx); + + return *static_cast<resources_loader*>(ptr); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon-js/malikania/js_resources_loader.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,33 @@ +/* + * js_resources_loader.hpp -- resources loader (JavaScript binding) + * + * Copyright (c) 2013-2016 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 MALIKANIA_JS_RESOURCES_LOADER_H +#define MALIKANIA_JS_RESOURCES_LOADER_H + +#include "duktape.hpp" +#include "resources_loader.hpp" + +namespace malikania { + +void dukx_put_loader(duk_context* ctx, resources_loader&); + +resources_loader& dukx_get_loader(duk_context* ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_RESOURCES_LOADER_H
--- a/libcommon/CMakeLists.txt Sun Nov 27 20:50:38 2016 +0100 +++ b/libcommon/CMakeLists.txt Tue Nov 29 21:21:36 2016 +0100 @@ -18,28 +18,26 @@ set( HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/application.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/duktape.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/game.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/id.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources-loader.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources-locator.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources_loader.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources_locator.hpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/util.hpp ) set( SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/application.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources-loader.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources-locator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources_loader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/resources_locator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/util.cpp ) if (WITH_BACKEND_SDL) find_package(SDL2 REQUIRED) - list(APPEND HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/malikania/backend/sdl/common-sdl.hpp) - list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/malikania/backend/sdl/common-sdl.cpp) + list(APPEND HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/malikania/backend/sdl/sdl_util.hpp) + list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/malikania/backend/sdl/sdl_util.cpp) list(APPEND INCLUDES ${SDL2_INCLUDE_DIRS}) list(APPEND LIBRARIES ${SDL2_LIBRARIES}) endif ()
--- a/libcommon/malikania/application.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * application.cpp -- main application class - * - * 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 "application.hpp" - -namespace malikania { - -Application::Application(int, char **) -{ - // TODO: find the executable path -} - -} // !malikania
--- a/libcommon/malikania/application.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * application.hpp -- main application class - * - * 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_APPLICATION_HPP -#define MALIKANIA_APPLICATION_HPP - -/** - * \file application.hpp - * \brief Main class for the client or server - */ - -namespace malikania { - -/** - * \class Application - * \brief Main class for argument parsing and executable path retrievement - */ -class Application { -public: - /** - * Construct the application. - * - * \param argc the argument count - * \param argv the arguments - */ - Application(int argc, char **argv); - - /** - * Virtual destructor defaulted. - */ - virtual ~Application() = default; -}; - -} // !malikania - -#endif // !MALIKANIA_APPLICATION_HPP
--- a/libcommon/malikania/backend/sdl/common-sdl.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -/* - * CommonSdl.cpp -- common SDL2 related code - * - * 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 <cerrno> -#include <cstdint> -#include <cstring> -#include <new> - -#include "common-sdl.hpp" - -namespace malikania { - -namespace { - -/* - * RWFromBinary implementation - * ------------------------------------------------------------------ - * - * A little bit inspired by official SDL_RWFromMem implementation, largely modified to match our conventions and the - * C++ code. - */ - -class Buffer { -public: - std::string m_data; - std::uint64_t m_position; - std::uint64_t m_length; - - inline Buffer(std::string data) noexcept - : m_data(std::move(data)) - , m_position(0U) - , m_length(m_data.length()) - { - } -}; - -Sint64 size(SDL_RWops *ops) noexcept -{ - return reinterpret_cast<Buffer *>(ops->hidden.unknown.data1)->m_length; -} - -Sint64 seek(SDL_RWops *ops, Sint64 offset, int whence) noexcept -{ - Buffer *data = reinterpret_cast<Buffer *>(ops->hidden.unknown.data1); - Sint64 position = data->m_position; - - switch (whence) { - case RW_SEEK_SET: - position = offset; - break; - case RW_SEEK_CUR: - position = data->m_position + offset; - break; - case RW_SEEK_END: - position = data->m_length + offset; - break; - default: - break; - } - - if (position < 0) - position = 0; - else if ((std::uint64_t)position > data->m_length) - position = data->m_length; - - return (data->m_position = position); -} - -size_t read(SDL_RWops *ops, void *dst, std::size_t size, std::size_t number) noexcept -{ - Buffer *data = reinterpret_cast<Buffer *>(ops->hidden.unknown.data1); - size_t total = number * size; - size_t avail = data->m_length - data->m_position; - - if (number <= 0 || size <= 0 || ((total / number) != static_cast<std::size_t>(size))) - return 0; - if (total > avail) - total = avail; - - SDL_memcpy(dst, &data->m_data[data->m_position], total); - - data->m_position += total; - - return (total / size); -} - -size_t write(SDL_RWops *, const void *, size_t, size_t) noexcept -{ - SDL_SetError("write not supported"); - - return -1; -} - -int close(SDL_RWops *ops) noexcept -{ - if (ops != nullptr) { - delete reinterpret_cast<Buffer *>(ops->hidden.unknown.data1); - SDL_FreeRW(ops); - } - - return 0; -} - -} // !namespace - -SDL_RWops *SDLx_RWFromBinary(std::string data) noexcept -{ - SDL_RWops *ops = SDL_AllocRW(); - - if (ops == nullptr) - return nullptr; - - ops->hidden.unknown.data1 = new (std::nothrow) Buffer(std::move(data)); - - if (ops->hidden.unknown.data1 == nullptr) { - SDL_SetError("%s", std::strerror(errno)); - SDL_FreeRW(ops); - return nullptr; - } - - ops->type = SDL_RWOPS_UNKNOWN; - ops->seek = seek; - ops->size = size; - ops->read = read; - ops->write = write; - ops->close = close; - - return ops; -} - -} // !malikania
--- a/libcommon/malikania/backend/sdl/common-sdl.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * CommonSdl.hpp -- common SDL2 related code - * - * 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_COMMON_SDL_HPP -#define MALIKANIA_COMMON_SDL_HPP - -#include <SDL.h> - -#include <string> - -namespace malikania { - -/** - * Create a SDL_RWops that owns the binary data. - * - * This is a safe alternative to SDL_RWFromMem because it owns the memory pointed by data until it is closed. The - * data is moved so there are no copies. - * - * The stream has read-only support and can not write. - * - * Seeking past-the-end or past-the-begin readjust the position to the end or begin respectively. - * - * \param data the data - * \return the object or nullptr on errors - */ -SDL_RWops *SDLx_RWFromBinary(std::string data) noexcept; - -} // !malikania - -#endif // !MALIKANIA_COMMON_SDL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/backend/sdl/sdl_util.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,148 @@ +/* + * sdl_util.cpp -- common SDL2 related code + * + * 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 <cerrno> +#include <cstdint> +#include <cstring> +#include <new> + +#include "sdl_util.hpp" + +namespace malikania { + +namespace { + +/* + * RWFromBinary implementation + * ------------------------------------------------------------------ + * + * A little bit inspired by official SDL_RWFromMem implementation, largely + * modified to match our conventions and the C++ code. + */ + +class buffer { +public: + std::string m_data; + std::uint64_t m_position; + std::uint64_t m_length; + + inline buffer(std::string data) noexcept + : m_data(std::move(data)) + , m_position(0ULL) + , m_length(m_data.length()) + { + } +}; + +Sint64 size(SDL_RWops* ops) noexcept +{ + return reinterpret_cast<buffer*>(ops->hidden.unknown.data1)->m_length; +} + +Sint64 seek(SDL_RWops* ops, Sint64 offset, int whence) noexcept +{ + buffer *data = reinterpret_cast<buffer*>(ops->hidden.unknown.data1); + Sint64 position = data->m_position; + + switch (whence) { + case RW_SEEK_SET: + position = offset; + break; + case RW_SEEK_CUR: + position = data->m_position + offset; + break; + case RW_SEEK_END: + position = data->m_length + offset; + break; + default: + break; + } + + if (position < 0LL) { + position = 0LL; + } else if (static_cast<std::uint64_t>(position) > data->m_length) { + position = data->m_length; + } + + return (data->m_position = position); +} + +std::size_t read(SDL_RWops* ops, void* dst, std::size_t size, std::size_t number) noexcept +{ + buffer* data = reinterpret_cast<buffer*>(ops->hidden.unknown.data1); + std::size_t total = number * size; + std::size_t avail = data->m_length - data->m_position; + + if (number <= 0U || size <= 0U || ((total / number) != static_cast<std::size_t>(size))) { + return 0; + } + if (total > avail) { + total = avail; + } + + SDL_memcpy(dst, &data->m_data[data->m_position], total); + data->m_position += total; + + return total / size; +} + +std::size_t write(SDL_RWops*, const void*, std::size_t, std::size_t) noexcept +{ + SDL_SetError("write not supported"); + return -1; +} + +int close(SDL_RWops* ops) noexcept +{ + if (ops != nullptr) { + delete reinterpret_cast<buffer*>(ops->hidden.unknown.data1); + SDL_FreeRW(ops); + } + + return 0; +} + +} // !namespace + +SDL_RWops* SDLx_RWFromBinary(std::string data) noexcept +{ + SDL_RWops* ops = SDL_AllocRW(); + + if (ops == nullptr) { + return nullptr; + } + + ops->hidden.unknown.data1 = new (std::nothrow) buffer(std::move(data)); + + if (ops->hidden.unknown.data1 == nullptr) { + SDL_SetError("%s", std::strerror(errno)); + SDL_FreeRW(ops); + return nullptr; + } + + ops->type = SDL_RWOPS_UNKNOWN; + ops->seek = seek; + ops->size = size; + ops->read = read; + ops->write = write; + ops->close = close; + + return ops; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/backend/sdl/sdl_util.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,51 @@ +/* + * sdl_util.hpp -- common SDL2 related code + * + * 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_COMMON_SDL_UTIL_HPP +#define MALIKANIA_COMMON_SDL_UTIL_HPP + +/** + * \file sdl_util.hpp + * \brief Utilities for SDL backend. + */ + +#include <SDL.h> + +#include <string> + +namespace malikania { + +/** + * Create a SDL_RWops that owns the binary data. + * + * This is a safe alternative to SDL_RWFromMem because it owns the memory + * pointed by data until it is closed. The data is moved so there are no copies. + * + * The stream has read-only support and can not write. + * + * Seeking past-the-end or past-the-begin readjust the position to the end or + * begin respectively. + * + * \param data the data + * \return the object or nullptr on errors + */ +SDL_RWops* SDLx_RWFromBinary(std::string data) noexcept; + +} // !malikania + +#endif // !MALIKANIA_COMMON_SDL_UTIL_HPP
--- a/libcommon/malikania/game.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libcommon/malikania/game.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -19,6 +19,11 @@ #ifndef MALIKANIA_GAME_HPP #define MALIKANIA_GAME_HPP +/** + * \file game.hpp + * \brief Game description. + */ + #include <cassert> #include <string> #include <vector> @@ -26,91 +31,15 @@ namespace malikania { /** - * \class Game - * \brief Basic game class. + * \brief Basic game description. */ -class Game { -private: - std::string m_name; - std::string m_version; - std::string m_requires; - std::string m_license; - std::string m_author; - +class game { public: - /** - * Construct a game. - * - * \pre name must not be empty - * \pre version must not be empty - * \pre requires must not be empty - * \param name the game name - * \param version the version - * \param requires the engine version required - * \param license the license (Optional) - * \param authors the authors (Optional) - */ - inline Game(std::string name, std::string version, std::string requires, std::string license, std::string author) - : m_name(std::move(name)) - , m_version(std::move(version)) - , m_requires(std::move(requires)) - , m_license(std::move(license)) - , m_author(std::move(author)) - { - assert(!m_name.empty()); - assert(!m_version.empty()); - assert(!m_requires.empty()); - } - - /** - * Get the game name. - * - * \return the name - */ - inline const std::string &name() const noexcept - { - return m_name; - } - - /** - * Get the author. - * - * \return the author - */ - inline const std::string &author() const noexcept - { - return m_author; - } - - /** - * Get the license. - * - * \return the license - */ - inline const std::string &license() const noexcept - { - return m_license; - } - - /** - * Get the license. - * - * \return the license - */ - inline const std::string &version() const noexcept - { - return m_version; - } - - /** - * Get the engine version required to run the game. - * - * \return the version required - */ - inline const std::string &requires() const noexcept - { - return m_requires; - } + std::string name; + std::string version; + std::string requires; + std::string license; + std::string author; }; } // !malikania
--- a/libcommon/malikania/id.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libcommon/malikania/id.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -25,26 +25,32 @@ */ #include <limits> +#include <memory> #include <queue> #include <stdexcept> namespace malikania { +template <typename T> +class id; + /** - * \class IdGen * \brief Integer id generator * - * This class helps generating and release unique integer id that can be used anywhere. The ids are generated in a - * sequence and when an id is released it is reused instead of incrementing the next number. + * This class helps generating and release unique integer id that can be used + * anywhere. The ids are generated in a sequence and when an id is released it + * is reused instead of incrementing the next number. * * The template can use any integral integer but unsigned are preferred. * * The maximum number of id is equal to std::numeric_limits<T>::max - 1. */ template <typename T> -class IdGen { +class id_generator { private: - static_assert(std::numeric_limits<T>::is_integer, "IdGen requires integral types"); + static_assert(std::numeric_limits<T>::is_integer, "id_generator requires integral types"); + + friend class id<T>; T m_current{0}; std::priority_queue<T> m_reusable; @@ -56,98 +62,46 @@ * \return the id * \throw std::out_of_range if no number is available */ - T next(); - - /** - * Release the player id. - * - * \param id the id not needed anymore - */ - inline void release(T id) noexcept - { - m_reusable.push(id); - } - - /** - * Reset the ids to 0 and remove the queue. - */ - void reset() noexcept; + std::unique_ptr<id<T>> next(); }; -template <typename T> -T IdGen<T>::next() -{ - T id; - - if (m_reusable.size() > 0) { - id = m_reusable.top(); - m_reusable.pop(); - } else { - if (m_current == std::numeric_limits<T>::max()) - throw std::out_of_range("no id available"); - - id = m_current++; - } - - return id; -} - -template <typename T> -void IdGen<T>::reset() noexcept -{ - m_current = 0; - - while (!m_reusable.empty()) - m_reusable.pop(); -} - /** - * \class Id * \brief RAII based id owner * - * This class is similar to a std::lock_guard or std::unique_lock in a way that the id is acquired - * when the object is instanciated and released when destroyed. + * This class is similar to a std::lock_guard or std::unique_lock in a way that + * the id is acquired when the object is instanciated and released when + * destroyed. * - * This class does not take ownership of the IdGen so it must still exists when the Id is destroyed. + * This class does not take ownership of the id_generator so it must still + * exists when the id is destroyed. */ template <typename T> -class Id { +class id { private: - IdGen<T> &m_gen; + friend class id_generator<T>; + + id_generator<T>& m_gen; T m_id; -public: /** - * Construct a new Id and take the next number. + * Construct a new id and take the next number. * * \param gen the generator * \throw any exception if IdGen fails to give an id. */ - inline Id(IdGen<T> &gen) - : m_gen(gen) - , m_id(m_gen.next()) - { - } - - /** - * Construct an Id with an already taken number. - * - * \param gen the generator - * \param id the id - * \warning be sure that the id was taken from this generator - */ - Id(IdGen<T> &gen, T id) + inline id(id_generator<T>& gen, T id) noexcept : m_gen(gen) , m_id(id) { } +public: /** * Destroy the id and release the number. */ - ~Id() noexcept + ~id() noexcept { - m_gen.release(m_id); + m_gen.m_reusable.push(m_id); } /** @@ -159,15 +113,46 @@ { return m_id; } +}; - /** - * Convert the id to the number. - */ - inline operator T() const noexcept - { - return m_id; +template <typename T> +std::unique_ptr<id<T>> id_generator<T>::next() +{ + T i; + + if (m_reusable.size() > 0) { + i = m_reusable.top(); + m_reusable.pop(); + } else { + if (m_current == std::numeric_limits<T>::max()) { + throw std::out_of_range("no id available"); + } + + i = m_current++; } -}; + + return std::unique_ptr<id<T>>(new id<T>(*this, i)); +} + +/** + * Typedef for std::uint8_t. + */ +using id8 = id<std::uint8_t>; + +/** + * Typedef for std::uint16_t. + */ +using id16 = id<std::uint16_t>; + +/** + * Typedef for std::uint32_t. + */ +using id32 = id<std::uint32_t>; + +/** + * Typedef for std::uint64_t. + */ +using id64 = id<std::uint64_t>; } // !malikania
--- a/libcommon/malikania/resources-loader.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * resources-loader.cpp -- load shared resources files - * - * 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 <cassert> - -#include "game.hpp" -#include "resources-loader.hpp" -#include "resources-locator.hpp" - -using json = nlohmann::json; - -namespace malikania { - -void ResourcesLoader::requires(const std::string &id, - const json &object, - const std::unordered_map<std::string, json::value_t> props) const -{ - assert(object.is_object()); - - for (const auto &pair : props) { - auto it = object.find(pair.first); - - if (it == object.end() || it->type() != pair.second) { - std::string msg = id + ": missing '" + pair.first + "' property ("; - - switch (pair.second) { - case json::value_t::array: - msg += "array"; - break; - case json::value_t::boolean: - msg += "boolean"; - break; - case json::value_t::number_float: - case json::value_t::number_integer: - case json::value_t::number_unsigned: - msg += "number"; - break; - case json::value_t::object: - msg += "object"; - break; - case json::value_t::string: - msg += "string"; - break; - default: - break; - } - - msg += " expected)"; - - throw std::runtime_error(std::move(msg)); - } - } -} - -std::string ResourcesLoader::requireString(const std::string &id, - const nlohmann::json &object, - const std::string &property) const -{ - assert(object.is_object()); - - auto it = object.find(property); - - if (it == object.end() || !it->is_string()) - throw std::runtime_error(id + ": missing '" + property + "' property (string expected)"); - - return *it; -} - -ResourcesLoader::ResourcesLoader(ResourcesLocator &locator) - : m_locator(locator) -{ -} - -Game ResourcesLoader::loadGame() const -{ - auto value = json::parse(m_locator.read("game.json")); - - if (!value.is_object()) - throw std::runtime_error("game.json: not a JSON object"); - - requires("game.json", value, { - { "name", json::value_t::string }, - { "version", json::value_t::string }, - { "requires", json::value_t::string } - }); - - return Game(value["name"], - value["version"], - value["requires"], - value.count("license") > 0 ? value["license"] : "", - value.count("author") > 0 ? value["author"] : ""); -} - -} // !malikania
--- a/libcommon/malikania/resources-loader.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -/* - * resources-loader.hpp -- load shared resources files - * - * 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_RESOURCES_LOADER_HPP -#define MALIKANIA_RESOURCES_LOADER_HPP - -#include <string> -#include <unordered_map> - -#include <json.hpp> - -#include "resources-locator.hpp" - -namespace malikania { - -class Game; - -/** - * \class ResourcesLoader - * \brief Open resources files using a ResourcesLocator. - * - * This class is used to load resources files that are common to the server and the client. - * - * \see ResourcesLoaderClient - * \see ResourcesLoaderServer - */ -class ResourcesLoader { -private: - ResourcesLocator &m_locator; - -protected: - /** - * Check that an object has the specified properties of the given type. - * - * Throws an error when any of the property is missing or not the correct type. - * - * You can use this function when you have lot of properties to extract, otherwise, you can use one of the - * require* or get* functions to avoid performances overhead. - * - * \pre object.isObject() - * \param id the resource id - * \param object the object - * \param props the properties - * \throw std::runtime_error when a property is missing / invalid - */ - void requires(const std::string &id, - const nlohmann::json &object, - const std::unordered_map<std::string, nlohmann::json::value_t> props) const; - - /** - * Require a string. - * - * \pre object.isObject() - * \param id the resource id - * \param object the object - * \param property the property - * \return the string - * \throw std::runtime_error if the property is not a string or missing - */ - std::string requireString(const std::string &id, const nlohmann::json &object, const std::string &property) const; - -public: - /** - * Construct the ResourcesLoader. - * - * \param locator the locator - */ - ResourcesLoader(ResourcesLocator &locator); - - /** - * Virtual destructor defaulted. - */ - virtual ~ResourcesLoader() = default; - - /** - * Get the underlying locator. - * - * \return the locator - */ - inline ResourcesLocator &locator() noexcept - { - return m_locator; - } - - /** - * Load a game. - * - * \return the game - * \throw std::runtime_error on errors - */ - virtual Game loadGame() const; -}; - -} // !malikania - -#endif // !MALIKANIA_RESOURCES_LOADER_HPP
--- a/libcommon/malikania/resources-locator.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * resources-locator.cpp -- file and stream loader - * - * 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 <cerrno> -#include <cstring> -#include <fstream> -#include <iterator> -#include <stdexcept> - -#include "resources-locator.hpp" - -namespace malikania { - -ResourcesLocatorDirectory::ResourcesLocatorDirectory(std::string path) noexcept - : m_path(std::move(path)) -{ -} - -std::string ResourcesLocatorDirectory::read(const std::string &id) -{ - std::ifstream in(m_path + "/" + id, std::ifstream::in | std::ifstream::binary); - - if (!in) - throw std::runtime_error(std::strerror(errno)); - - return std::string(std::istreambuf_iterator<char>(in.rdbuf()), std::istreambuf_iterator<char>()); -} - -std::unique_ptr<std::istream> ResourcesLocatorDirectory::open(const std::string &id) -{ - std::unique_ptr<std::istream> ptr = std::make_unique<std::ifstream>(m_path + "/" + id); - - if (!(*ptr)) - throw std::runtime_error(std::strerror(errno)); - - return ptr; -} - -} // !malikania
--- a/libcommon/malikania/resources-locator.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * resources-locator.hpp -- file and stream loader - * - * 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_RESOURCES_LOCATOR_HPP -#define MALIKANIA_RESOURCES_LOCATOR_HPP - -#include <string> -#include <memory> -#include <istream> - -namespace malikania { - -/** - * \class ResourcesLocator - * \brief Load files from directories and zip. - */ -class ResourcesLocator { -public: - /** - * Read a whole resource as a string. - * - * \param id the resource id - * \return the string - * \throw std::runtime_error on any errors - */ - virtual std::string read(const std::string &id) = 0; - - /** - * Open a resource as a stream. - * - * \param id the resource id - * \return the stream - * \throw std::runtime_error on any errors - */ - virtual std::unique_ptr<std::istream> open(const std::string &id) = 0; -}; - -/** - * \class ResourcesLocatorDirectory - * \brief Load a game from a directory. - */ -class ResourcesLocatorDirectory : public ResourcesLocator { -private: - std::string m_path; - -public: - /** - * Load the game from the directory. - * - * \param path the base directory - */ - ResourcesLocatorDirectory(std::string path) noexcept; - - /** - * @copydoc ResourcesLocator::read - */ - std::string read(const std::string &id) override; - - /** - * @copydoc ResourcesLocator::open - */ - std::unique_ptr<std::istream> open(const std::string &id) override; -}; - -} // !malikania - -#endif // !MALIKANIA_RESOURCES_LOCATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/resources_loader.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,108 @@ +/* + * resources_loader.cpp -- load shared resources files + * + * 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 <boost/format.hpp> + +#include <cassert> + +#include "game.hpp" +#include "resources_loader.hpp" +#include "resources_locator.hpp" + +namespace malikania { + +void resources_loader::requires(const std::string& id, + const nlohmann::json& object, + const std::unordered_map<std::string, nlohmann::json::value_t>& props) const +{ + assert(object.is_object()); + + for (const auto& pair : props) { + auto it = object.find(pair.first); + + if (it == object.end() || it->type() != pair.second) { + std::string type; + + switch (pair.second) { + case nlohmann::json::value_t::array: + type = "array"; + break; + case nlohmann::json::value_t::boolean: + type = "boolean"; + break; + case nlohmann::json::value_t::number_unsigned: + type = "number"; + break; + case nlohmann::json::value_t::object: + type = "object"; + break; + case nlohmann::json::value_t::string: + type = "string"; + break; + default: + break; + } + + throw std::runtime_error(boost::str( + boost::format("%s: missing '%s' property (%s expected)") % id % pair.first % type)); + } + } +} + +std::string resources_loader::require_string(const std::string& id, + const nlohmann::json& object, + const std::string& property) const +{ + assert(object.is_object()); + + auto it = object.find(property); + + if (it == object.end() || !it->is_string()) { + throw std::runtime_error(id + ": missing '" + property + "' property (string expected)"); + } + + return *it; +} + +resources_loader::resources_loader(resources_locator& locator) + : m_locator(locator) +{ +} + +game resources_loader::load_game() const +{ + auto value = nlohmann::json::parse(m_locator.read("game.json")); + + if (!value.is_object()) { + throw std::runtime_error("game.json: not a JSON object"); + } + + requires("game.json", value, { + { "name", nlohmann::json::value_t::string }, + { "version", nlohmann::json::value_t::string }, + { "requires", nlohmann::json::value_t::string } + }); + + return game{value["name"], + value["version"], + value["requires"], + value.count("license") > 0 ? value["license"] : "", + value.count("author") > 0 ? value["author"] : ""}; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/resources_loader.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,114 @@ +/* + * resources_loader.hpp -- load shared resources files + * + * 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_RESOURCES_LOADER_HPP +#define MALIKANIA_RESOURCES_LOADER_HPP + +#include <string> +#include <unordered_map> + +#include <json.hpp> + +#include "resources_locator.hpp" + +namespace malikania { + +class game; + +/** + * \brief Open resources files using a resources_locator. + * + * This class is used to load resources files that are common to the server and + * the client. + * + * \see client_resources_loader + */ +class resources_loader { +private: + resources_locator& m_locator; + +protected: + /** + * Check that an object has the specified properties of the given type. + * + * Throws an error when any of the property is missing or not the correct + * type. + * + * You can use this function when you have lot of properties to extract, + * otherwise, you can use one of the require* or get* functions to avoid + * performances overhead. + * + * \pre object.is_object() + * \param id the resource id + * \param object the object + * \param props the properties + * \throw std::runtime_error when a property is missing / invalid + */ + void requires(const std::string& id, + const nlohmann::json& object, + const std::unordered_map<std::string, nlohmann::json::value_t>& props) const; + + /** + * Require a string. + * + * \pre object.isObject() + * \param id the resource id + * \param object the object + * \param property the property + * \return the string + * \throw std::runtime_error if the property is not a string or missing + */ + std::string require_string(const std::string& id, + const nlohmann::json& object, + const std::string& property) const; + +public: + /** + * Construct the resources loader. + * + * \param locator the locator + */ + resources_loader(resources_locator& locator); + + /** + * Virtual destructor defaulted. + */ + virtual ~resources_loader() noexcept = default; + + /** + * Get the underlying locator. + * + * \return the locator + */ + inline resources_locator& locator() noexcept + { + return m_locator; + } + + /** + * Load a game. + * + * \return the game + * \throw std::runtime_error on errors + */ + virtual game load_game() const; +}; + +} // !malikania + +#endif // !MALIKANIA_RESOURCES_LOADER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/resources_locator.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,56 @@ +/* + * resources_locator.cpp -- file and stream loader + * + * 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 <cerrno> +#include <cstring> +#include <fstream> +#include <iterator> +#include <stdexcept> + +#include "resources_locator.hpp" + +namespace malikania { + +directory_resources_locator::directory_resources_locator(std::string path) noexcept + : m_path(std::move(path)) +{ +} + +std::string directory_resources_locator::read(const std::string &id) +{ + std::ifstream in(m_path + "/" + id, std::ifstream::in | std::ifstream::binary); + + if (!in) { + throw std::runtime_error(std::strerror(errno)); + } + + return std::string(std::istreambuf_iterator<char>(in.rdbuf()), std::istreambuf_iterator<char>()); +} + +std::unique_ptr<std::istream> directory_resources_locator::open(const std::string &id) +{ + auto ptr = std::make_unique<std::ifstream>(m_path + "/" + id); + + if (!(*ptr)) { + throw std::runtime_error(std::strerror(errno)); + } + + return ptr; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/resources_locator.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,85 @@ +/* + * resources_locator.hpp -- file and stream loader + * + * 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_RESOURCES_LOCATOR_HPP +#define MALIKANIA_RESOURCES_LOCATOR_HPP + +#include <string> +#include <memory> +#include <istream> + +namespace malikania { + +/** + * \brief Abstract assets locator. + */ +class resources_locator { +public: + /** + * Default destructor. + */ + virtual ~resources_locator() = default; + + /** + * Read a whole resource as a string. + * + * \param id the resource id + * \return the string + * \throw std::runtime_error on any errors + */ + virtual std::string read(const std::string& id) = 0; + + /** + * Open a resource as a stream. + * + * \param id the resource id + * \return the stream + * \throw std::runtime_error on any errors + */ + virtual std::unique_ptr<std::istream> open(const std::string& id) = 0; +}; + +/** + * \brief Load a game from a directory. + */ +class directory_resources_locator : public resources_locator { +private: + std::string m_path; + +public: + /** + * Load the game from the directory. + * + * \param path the base directory + */ + directory_resources_locator(std::string path) noexcept; + + /** + * \copydoc resources_locator::read + */ + std::string read(const std::string& id) override; + + /** + * \copydoc resources_locator::open + */ + std::unique_ptr<std::istream> open(const std::string& id) override; +}; + +} // !malikania + +#endif // !MALIKANIA_RESOURCES_LOCATOR_HPP
--- a/libcommon/malikania/signals.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * signals.h -- synchronous observer mechanism - * - * Copyright (c) 2016 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 MALIKANIA_SIGNALS_HPP -#define MALIKANIA_SIGNALS_HPP - -/** - * \file signals.hpp - * \brief Synchronous callbacks. - */ - -#include <algorithm> -#include <cstdint> -#include <functional> -#include <stack> -#include <unordered_map> -#include <vector> - -namespace malikania { - -/** - * \brief Stores and call registered functions. - * - * This class is intended to be use as a public field in the desired object. - * - * The user just have to call one of connect(), disconnect() or the call - * operator to use this class. - * - * It stores the callable as std::function so type-erasure is complete. - * - * The user is responsible of taking care that the object is still alive - * in case that the function takes a reference to the object. - * - * It is forbidden to connect, disconnect, clearing the signal from a callback, - * instead you should postpone this operation for example, in an event loop - * event. - * - * It is also forbidden to throw in user callbacks, to make such guarantee, the - * call operator is noexcept. - */ -template <typename... Args> -class Signal { -public: - /** - * \brief Opaque connection identifier. - * \see disconnect - */ - using Index = std::intmax_t; - -private: - using Function = std::function<void (Args...)>; - using List = std::vector<Function>; - using Stack = std::stack<Index>; - - List m_functions; - Stack m_reuseable; - -#if !defined(NDEBUG) - mutable bool m_locked{false}; -#endif - - template <typename Func> - inline Index add(Func &&function) - { - assert(!m_locked); - - std::size_t id; - - if (!m_reuseable.empty()) { - id = m_reuseable.top(); - m_functions[id] = std::forward<Func>(function); - m_reuseable.pop(); - } else { - m_functions.push_back(std::forward<Func>(function)); - id = m_functions.size() - 1; - } - - return id; - } - -public: - /** - * Register a new function to the signal. - * - * \pre must not be called from an handler - * \param function the function to copy - * \return the index for removing - * \throw exceptions on bad allocation - */ - inline Index connect(const Function &function) - { - return add(function); - } - - /** - * Overloaded function for move semantics. - * - * \pre must not be called from an handler - * \param function the function to move - * \return the connection index - * \throw exceptions on bad allocation - */ - inline Index connect(Function &&function) - { - return add(function); - } - - /** - * Disconnect an handler. - * - * \pre must not be called from an handler - * \param id the id to disconnect (will be set to 0) - */ - inline void disconnect(Index &id) - { - assert(!m_locked); - - if (id < 0 || static_cast<std::size_t>(id) >= m_functions.size()) - return; - - m_functions[id] = nullptr; - m_reuseable.push(id); - id = -1; - } - - /** - * Remove all registered functions. - * - * \pre must not be called from an handler - */ - inline void clear() noexcept - { - assert(!m_locked); - - m_functions.clear(); - - while (!m_reuseable.empty()) - m_reuseable.pop(); - } - - /** - * Get the number of signals connected. - * - * \return the number - */ - inline std::size_t size() const noexcept - { - return std::count_if(m_functions.begin(), m_functions.end(), [&] (auto fn) { - return fn != nullptr; - }); - } - - /** - * Call every functions. - * - * \pre must not be called from an handler - * \param args the arguments to pass to the signal - */ - void operator()(Args... args) const noexcept - { - assert(!m_locked); - - m_locked = true; - - for (auto &f : m_functions) - if (f) - f(args...); - - m_locked = false; - } -}; - -} // !malikania - -#endif // !MALIKANIA_SIGNALS_HPP
--- a/libcommon/malikania/util.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libcommon/malikania/util.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -22,7 +22,7 @@ namespace util { -std::vector<std::string> netsplit(std::string &input) +std::vector<std::string> netsplit(std::string& input) { std::vector<std::string> ret; std::string::size_type pos;
--- a/libcommon/malikania/util.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libcommon/malikania/util.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -39,7 +39,7 @@ * \param input the buffer to split and update * \return the list of received message or empty if not ready */ -std::vector<std::string> netsplit(std::string &input); +std::vector<std::string> netsplit(std::string& input); /** * Clamp the value between low and high.
--- a/libserver/CMakeLists.txt Sun Nov 27 20:50:38 2016 +0100 +++ b/libserver/CMakeLists.txt Tue Nov 29 21:21:36 2016 +0100 @@ -21,13 +21,13 @@ set( HEADERS ${libmlk-server_SOURCE_DIR}/malikania/account.hpp - ${libmlk-server_SOURCE_DIR}/malikania/dao-account.hpp + ${libmlk-server_SOURCE_DIR}/malikania/account_dao.hpp ${libmlk-server_SOURCE_DIR}/malikania/database.hpp ) set( SOURCES - ${libmlk-server_SOURCE_DIR}/malikania/dao-account.cpp + ${libmlk-server_SOURCE_DIR}/malikania/account_dao.cpp ${libmlk-server_SOURCE_DIR}/malikania/database.cpp )
--- a/libserver/malikania/account.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libserver/malikania/account.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -32,145 +32,22 @@ /** * \brief Account model */ -class Account { -private: - std::uint64_t m_id{0}; - std::string m_name; - std::string m_email; - std::string m_firstName; - std::string m_lastName; - std::string m_password; - +class account { public: - /** - * Get the id. - * - * \return the id - */ - inline std::uint64_t id() const noexcept - { - return m_id; - } - - /** - * Set the id. - * - * \param id the id - */ - inline void setId(std::uint64_t id) noexcept - { - m_id = id; - } - - /** - * Get the account name. - * - * \return the name - */ - inline const std::string &name() const noexcept - { - return m_name; - } - - /** - * Set the account name. - * - * \param name the name - */ - inline void setName(std::string name) noexcept - { - m_name = std::move(name); - } - - /** - * Get the email. - * - * \return the email address - */ - inline const std::string &email() const noexcept - { - return m_email; - } - - /** - * Set the email. - * - * \param email the email address - */ - inline void setEmail(std::string email) noexcept - { - m_email = std::move(email); - } - - /** - * Get the first name. - * - * \return the first name - */ - inline const std::string &firstName() const noexcept - { - return m_firstName; - } - - /** - * Set the first name. - * - * \param firstName the first name - */ - inline void setFirstName(std::string firstName) noexcept - { - m_firstName = std::move(firstName); - } - - /** - * Get the last name. - * - * \return the last name - */ - inline const std::string &lastName() const noexcept - { - return m_lastName; - } - - /** - * Set the last name. - * - * \param lastName the last name - */ - inline void setLastName(std::string lastName) noexcept - { - m_lastName = std::move(lastName); - } - - /** - * Get the password. - * - * \return the password - */ - inline const std::string &password() const noexcept - { - return m_password; - } - - /** - * Set the password. - * - * \param password the password - */ - inline void setPassword(std::string password) noexcept - { - m_password = std::move(password); - } + std::uint64_t id; + std::string name; + std::string email; + std::string first_name; + std::string last_name; + std::string password; }; -inline bool operator==(const Account &ac1, const Account &ac2) noexcept +inline bool operator==(const account &ac1, const account &ac2) noexcept { - return ac1.id() == ac2.id() && ac1.name() == ac2.name() && ac1.email() == ac2.email() && - ac1.firstName() == ac2.firstName() && ac1.lastName() == ac2.lastName() && - ac1.password() == ac2.password(); + return ac1.id == ac2.id; } -inline bool operator!=(const Account &ac1, const Account &ac2) noexcept +inline bool operator!=(const account &ac1, const account &ac2) noexcept { return !(ac1 == ac2); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/account_dao.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,68 @@ +/* + * dao-account.cpp -- database account management + * + * Copyright (c) 2013-2016 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 "account.hpp" +#include "account_dao.hpp" +#include "database.hpp" + +namespace malikania { + +using create_func = void (account&); +using remove_func = void (const account&); +using update_func = void (account&); +using get_func = account (std::uint64_t); +using list_func = std::vector<account> (); +using count_func = std::uint64_t (); +using clear_func = void (); + +void account_dao::create(account& account) +{ + m_database.handle().get<create_func>("malikania_account_create")(account); +} + +void account_dao::remove(const account& account) +{ + m_database.handle().get<remove_func>("malikania_account_remove")(account); +} + +void account_dao::update(account& account) +{ + m_database.handle().get<update_func>("malikania_account_update")(account); +} + +account account_dao::get(uint64_t id) +{ + return m_database.handle().get<get_func>("malikania_account_get")(id); +} + +std::vector<account> account_dao::list() +{ + return m_database.handle().get<list_func>("malikania_account_list")(); +} + +std::uint64_t account_dao::count() +{ + return m_database.handle().get<count_func>("malikania_account_count")(); +} + +void account_dao::clear() +{ + m_database.handle().get<clear_func>("malikania_account_clear")(); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/account_dao.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,115 @@ +/* + * account_dao.hpp -- database account management + * + * Copyright (c) 2013-2016 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 MALIKANIA_SERVER_ACCOUNT_DAO_HPP +#define MALIKANIA_SERVER_ACCOUNT_DAO_HPP + +/** + * \file account_dao.hpp + * \brief Database account management. + */ + +#include <cstdint> +#include <vector> + +namespace malikania { + +class database; +class account; + +/** + * \brief Account DAO. + */ +class account_dao { +private: + database& m_database; + +public: + /** + * Constructor. + * + * \param database the database + */ + inline account_dao(database& database) noexcept + : m_database(database) + { + } + + /** + * Create the given account. + * + * The object will be modified in place. + * + * \param account the account to add + * \throw std::exception on errors + */ + void create(account& account); + + /** + * Remove the given account, all data that references this account is + * deleted too. + * + * \param account the account + * \throw std::exception on errors + */ + void remove(const account& account); + + /** + * Update account only, does not recurse into objects that references the + * account. + * + * \param account the account + * \throw std::exception on errors + */ + void update(account& account); + + /** + * Get an account. + * + * \param id the account id + * \return the account + * \throw std::exception if not found + */ + account get(std::uint64_t id); + + /** + * Get the list of account. + * + * \throw std::exception on errors + */ + std::vector<account> list(); + + /** + * Get the number of accounts. + * + * \return the number of account. + */ + std::uint64_t count(); + + /** + * Remove all accounts recursively. + * + * \throw std::exception on errors + * \warning use with care + */ + void clear(); +}; + +} // !malikania + +#endif // !MALIKANIA_SERVER_ACCOUNT_DAO_HPP
--- a/libserver/malikania/connection-service.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - * connection-service.cpp -- manage clients server side - * - * Copyright (c) 2016 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 <iostream> - -#include "dao-account.hpp" -#include "connection-state-ready.hpp" -#include "connection-service.hpp" -#include "server.hpp" - -namespace malikania { - -void ConnectionService::slotAuthentication(Server &server, - Connection &connection, - const std::string &login, - const std::string &password) -{ - AccountDao dao(server.database()); - - try { - if (dao.authenticate(login, password)) { - std::cout << "client successfully authenticated" << std::endl; - server.post([&connection] (auto &) { - connection.setState(std::make_unique<Connection::ReadyState>()); - }); - } else { - std::cout << "client failed to authenticate" << std::endl; - connection.error("authentication failed"); - } - } catch (const std::exception &ex) { - // FATAL ERROR?? - } -} - -void ConnectionService::slotDisconnect(Server &, Connection &) -{ - std::cout << "client disconnected" << std::endl; -} - -void ConnectionService::syncMaster(Server &server) -{ - try { - auto socket = net::TlsSocket(m_master.accept()); - - socket.setCertificate(m_settings.certificate); - socket.setPrivateKey(m_settings.key); - - auto conn = std::make_unique<Connection>(std::move(socket)); - auto &ref = *conn; - - conn->onAuthentication.connect([this, &server, &ref] (auto login, auto password) { - this->slotAuthentication(server, ref, login, password); - }); - conn->onDisconnect.connect([this, &server, &ref] () { - this->slotDisconnect(server, ref); - }); - - m_clients.push_back(std::move(conn)); - - std::cout << "new client connected" << std::endl; - } catch (const std::exception &ex) { - // LOG ERROR SOMEWHERE - } -} - -void ConnectionService::syncClients(net::Listener<> &listener, const net::ListenerStatus &status) -{ - for (auto it = m_clients.begin(); it != m_clients.end(); ) { - auto &cnt = *it; - - if (cnt->handle() == status.socket) - cnt->sync(listener, status.flags); - - if (cnt->state().id() == "disconnected") - it = m_clients.erase(it); - else - ++ it; - } -} - -ConnectionService::ConnectionService(ConnectionSettings settings) - : m_settings(std::move(settings)) - , m_master(any(m_settings.type & ConnectionSettings::Ipv6) ? AF_INET6 : AF_INET, 0) -{ - if (any(m_settings.type & ConnectionSettings::Ipv6)) { - m_master.set(net::option::Ipv6Only(m_settings.type == ConnectionSettings::Ipv6)); - m_master.set(net::option::SockBlockMode(false)); - - if (m_settings.address == "*") - m_master.bind(net::ipv6::any(m_settings.port)); - else - m_master.bind(net::ipv6::pton(m_settings.address, m_settings.port)); - } else { - if (m_settings.address == "*") - m_master.bind(net::ipv4::any(m_settings.port)); - else - m_master.bind(net::ipv4::pton(m_settings.address, m_settings.port)); - } - - m_master.listen(256); -} - -void ConnectionService::prepare(Server &, net::Listener<> &listener) -{ - listener.reset(m_master.handle(), net::Condition::Readable); - - for (auto &cnt : m_clients) - cnt->prepare(listener); -} - -void ConnectionService::sync(Server &server, - net::Listener<> &listener, - const net::ListenerStatus &status) -{ - if (status.socket == m_master.handle()) - syncMaster(server); - else - syncClients(listener, status); -} - -} // !malikania
--- a/libserver/malikania/connection-service.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -/* - * connection-service.hpp -- manage clients server side - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_SERVICE_HPP -#define MALIKANIA_CONNECTION_SERVICE_HPP - -#include <cstdint> -#include <memory> -#include <vector> - -#include "connection.hpp" - -namespace malikania { - -class Server; - -/** - * \brief Connections parameters - */ -class ConnectionSettings { -public: - enum Type { - Ipv4 = (1 << 0), //!< Add IPv4 - Ipv6 = (1 << 1), //!< Add IPv6 - All = (Ipv4 | Ipv6) //!< Use both IPv4 and IPv6 on same port - } type{All}; - - std::string certificate; //!< Certificate file - std::string key; //!< Private key file - std::string address{"*"}; //!< Address to bind - std::uint16_t port{3320}; //!< Port to use -}; - -/** - * \brief Manage connections on the server - */ -class ConnectionService { -private: - ConnectionSettings m_settings; - net::TcpSocket m_master; - std::vector<std::unique_ptr<Connection>> m_clients; - - void slotAuthentication(Server &, Connection &, const std::string &, const std::string &); - void slotDisconnect(Server &, Connection &); - - void syncMaster(Server &server); - void syncClients(net::Listener<> &listener, const net::ListenerStatus &status); - -public: - ConnectionService(ConnectionSettings settings); - - inline const std::vector<std::unique_ptr<Connection>> &clients() const noexcept - { - return m_clients; - } - - inline std::vector<std::unique_ptr<Connection>> &clients() noexcept - { - return m_clients; - } - - void prepare(Server &server, net::Listener<> &listener); - - void sync(Server &server, net::Listener<> &listener, const net::ListenerStatus &status); -}; - -/** - * \cond ENUM_HIDDEN_SYMBOLS - */ - -inline ConnectionSettings::Type operator^(ConnectionSettings::Type v1, ConnectionSettings::Type v2) noexcept -{ - return static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); -} - -inline ConnectionSettings::Type operator&(ConnectionSettings::Type v1, ConnectionSettings::Type v2) noexcept -{ - return static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); -} - -inline ConnectionSettings::Type operator|(ConnectionSettings::Type v1, ConnectionSettings::Type v2) noexcept -{ - return static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); -} - -inline ConnectionSettings::Type operator~(ConnectionSettings::Type v) noexcept -{ - return static_cast<ConnectionSettings::Type>(~static_cast<unsigned>(v)); -} - -inline ConnectionSettings::Type &operator|=(ConnectionSettings::Type &v1, ConnectionSettings::Type v2) noexcept -{ - v1 = static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); - - return v1; -} - -inline ConnectionSettings::Type &operator&=(ConnectionSettings::Type &v1, ConnectionSettings::Type v2) noexcept -{ - v1 = static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); - - return v1; -} - -inline ConnectionSettings::Type &operator^=(ConnectionSettings::Type &v1, ConnectionSettings::Type v2) noexcept -{ - v1 = static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); - - return v1; -} - -/** - * \endcond - */ - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_SERVICE_HPP
--- a/libserver/malikania/connection-state-authenticating.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * connection-state-authenticating.cpp -- user is authenticating - * - * Copyright (c) 2016 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 "connection-state-authenticating.hpp" - -namespace malikania { - -void Connection::AuthenticatingState::prepare(Connection &conn, net::Listener<> &listener) -{ - listener.reset(conn.m_socket.handle(), net::Condition::Readable); -} - -void Connection::AuthenticatingState::sync(Connection &conn, net::Listener<> &, net::Condition) -{ - recv(conn, m_input); - - auto value = next(conn, m_input); - - if (!value.is_object()) - return; - - auto login = value.find("login"); - auto password = value.find("password"); - - if (login != value.end() && login->is_string() && - password != value.end() && password->is_string()) - conn.onAuthentication(*login, *password); -} - -std::string Connection::AuthenticatingState::id() const noexcept -{ - return "authenticating"; -} - -} // !malikania
--- a/libserver/malikania/connection-state-authenticating.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * connection-state-authenticating.hpp -- user is authenticating - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_AUTHENTICATING_HPP -#define MALIKANIA_CONNECTION_STATE_AUTHENTICATING_HPP - -/** - * \file connection-state-authenticating.hpp - * \brief User is authenticating. - */ - -#include "connection-state.hpp" - -namespace malikania { - -/** - * \brief User is authenticating. - */ -class Connection::AuthenticatingState : public Connection::State { -private: - std::string m_input; - -public: - void prepare(Connection &conn, net::Listener<> &listener) override; - - void sync(Connection &conn, net::Listener<> &, net::Condition) override; - - std::string id() const noexcept override; -}; - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_STATE_AUTHENTICATING_HPP
--- a/libserver/malikania/connection-state-closing.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * connection-state-closing.hpp -- closing connection to the user - * - * Copyright (c) 2016 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 "connection-state-disconnected.hpp" -#include "connection-state-closing.hpp" - -namespace malikania { - -void Connection::ClosingState::prepare(Connection &conn, net::Listener<> &listener) -{ - if (conn.m_output.empty()) - listener.remove(conn.handle()); - else - listener.reset(conn.handle(), net::Condition::Writable); -} - -void Connection::ClosingState::sync(Connection &conn, net::Listener<> &, net::Condition) -{ - send(conn, conn.m_output); - - if (conn.m_output.empty()) - conn.m_stateNext = std::make_unique<DisconnectedState>(); -} - -std::string Connection::ClosingState::id() const noexcept -{ - return "closing"; -} - -} // !malikania
--- a/libserver/malikania/connection-state-closing.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * connection-state-closing.hpp -- closing connection to the user - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_CLOSING_HPP -#define MALIKANIA_CONNECTION_STATE_CLOSING_HPP - -/** - * \file connection-state-closing.hpp - * \brief Closing connection to the user. - */ - -#include "connection-state.hpp" - -namespace malikania { - -/** - * \brief Closing connection to the user. - */ -class Connection::ClosingState : public Connection::State { -public: - void prepare(Connection &conn, net::Listener<> &listener) override; - - void sync(Connection &conn, net::Listener<> &, net::Condition) override; - - std::string id() const noexcept override; -}; - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_STATE_CLOSING_HPP
--- a/libserver/malikania/connection-state-disconnected.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * connection-state-disconnected.cpp -- client is down and will be removed - * - * Copyright (c) 2016 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 "connection-state-disconnected.hpp" - -namespace malikania { - -void Connection::DisconnectedState::prepare(Connection &, net::Listener<> &) -{ -} - -void Connection::DisconnectedState::sync(Connection &, net::Listener<> &, net::Condition) -{ -} - -std::string Connection::DisconnectedState::id() const noexcept -{ - return "disconnected"; -} - -} // !malikania
--- a/libserver/malikania/connection-state-disconnected.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * connection-state-disconnected.hpp -- client is down and will be removed - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_DISCONNECTED_HPP -#define MALIKANIA_CONNECTION_STATE_DISCONNECTED_HPP - -/** - * \file connection-state-disconected.hpp - * \brief Client is down and will be removed. - */ - -#include "connection-state.hpp" - -namespace malikania { - -/** - * \brief Client is down and will be removed. - */ -class Connection::DisconnectedState : public Connection::State { -public: - void prepare(Connection &conn, net::Listener<> &listener) override; - - void sync(Connection &conn, net::Listener<> &, net::Condition) override; - - std::string id() const noexcept override; -}; - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_STATE_DISCONNECTED_HPP
--- a/libserver/malikania/connection-state-greeting.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * connection-state-greeting.cpp -- greeting the user - * - * Copyright (c) 2016 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 <json.hpp> - -#include "connection-state-authenticating.hpp" -#include "connection-state-greeting.hpp" - -namespace malikania { - -Connection::GreetingState::GreetingState() -{ - // TODO: this is just an example. - m_output += nlohmann::json::object({ - { "malikania", "0.1.0" } - }).dump(); - m_output += "\r\n\r\n"; -} - -void Connection::GreetingState::prepare(Connection &conn, net::Listener<> &listener) -{ - listener.reset(conn.m_socket.handle(), net::Condition::Writable); -} - -void Connection::GreetingState::sync(Connection &conn, net::Listener<> &listener, net::Condition condition) -{ - assert(condition == net::Condition::Writable); - - if (m_output.length() > 0) - send(conn, m_output); - else { - listener.unset(conn.handle(), net::Condition::Writable); - conn.m_stateNext = std::make_unique<AuthenticatingState>(); - } -} - -std::string Connection::GreetingState::id() const noexcept -{ - return "greeting"; -} - -} // !malikania
--- a/libserver/malikania/connection-state-greeting.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * connection-state-greeting.hpp -- greeting the user - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_GREETING_HPP -#define MALIKANIA_CONNECTION_STATE_GREETING_HPP - -/** - * \file connection-state-greeting.hpp - * \brief Greeting the user. - */ - -#include "connection-state.hpp" - -namespace malikania { - -/** - * \brief Greeting the user. - */ -class Connection::GreetingState : public Connection::State { -private: - std::string m_output; - -public: - GreetingState(); - - void prepare(Connection &conn, net::Listener<> &listener) override; - - void sync(Connection &conn, net::Listener<> &listener, net::Condition condition) override; - - std::string id() const noexcept override; -}; - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_STATE_GREETING_HPP
--- a/libserver/malikania/connection-state-ready.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * connection-state-ready.cpp -- client is ready - * - * Copyright (c) 2016 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 "connection-state-ready.hpp" - -namespace malikania { - -void Connection::ReadyState::prepare(Connection &conn, net::Listener<> &listener) -{ - if (!conn.m_output.empty()) - listener.reset(conn.handle(), net::Condition::Writable); - - listener.reset(conn.handle(), net::Condition::Readable); -} - -void Connection::ReadyState::sync(Connection &conn, net::Listener<> &lst, net::Condition cond) -{ - if (bool(cond & net::Condition::Readable)) - recv(conn, conn.m_input); - - if (bool(cond & net::Condition::Writable)) { - send(conn, conn.m_output); - - if (conn.m_output.empty()) - lst.unset(conn.handle(), net::Condition::Writable); - } -} - -std::string Connection::ReadyState::id() const noexcept -{ - return "ready"; -} - -} // !malikania
--- a/libserver/malikania/connection-state-ready.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * connection-state-ready.hpp -- client is ready - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_READY_HPP -#define MALIKANIA_CONNECTION_STATE_READY_HPP - -/** - * \file connection-state-ready.hpp - * \brief Client is ready. - */ - -#include "connection-state.hpp" - -namespace malikania { - -/** - * \brief Client is ready. - */ -class Connection::ReadyState : public Connection::State { -public: - void prepare(Connection &conn, net::Listener<> &listener) override; - - void sync(Connection &conn, net::Listener<> &listener, net::Condition condition) override; - - std::string id() const noexcept override; -}; - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_STATE_READY_HPP
--- a/libserver/malikania/connection-state.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * connection-state.cpp -- base class for connection state - * - * Copyright (c) 2016 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 <iostream> - -#include "connection-state-disconnected.hpp" -#include "connection-state.hpp" -#include "util.hpp" - -namespace malikania { - -void Connection::State::close(Connection &conn) noexcept -{ - conn.onDisconnect(); - conn.m_state = std::make_unique<DisconnectedState>(); -} - -void Connection::State::recv(Connection &conn, std::string &input) noexcept -{ - try { - std::string buffer; - std::size_t size = 512; - - buffer.resize(size); - buffer.resize(conn.m_socket.recv(&buffer[0], size)); - - if (buffer.size() == 0) - close(conn); - - input += buffer; - } catch (const net::WantReadError &) { - conn.m_handshake = Handshake::Reading; - } catch (const net::WantWriteError &) { - conn.m_handshake = Handshake::Writing; - } catch (const std::exception &) { - close(conn); - } -} - -void Connection::State::send(Connection &conn, std::string &output) noexcept -{ - assert(output.length() != 0); - - try { - auto nsent = conn.m_socket.send(&output[0], output.length()); - - if (nsent == 0) - close(conn); - - output.erase(0, nsent); - } catch (const net::WantReadError &) { - conn.m_handshake = Handshake::Reading; - } catch (const net::WantWriteError &) { - conn.m_handshake = Handshake::Writing; - } catch (const std::exception &) { - close(conn); - } -} - -nlohmann::json Connection::State::next(Connection &conn, std::string &input) noexcept -{ - nlohmann::json object; - - try { - object = util::json::next(input); - } catch (const std::exception &) { - close(conn); - } - - return object; -} - -} // !malikania
--- a/libserver/malikania/connection-state.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * connection-state.hpp -- base class for connection state - * - * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_HPP -#define MALIKANIA_CONNECTION_STATE_HPP - -/** - * \file connection-state.hpp - * \brief Base class for connection state. - */ - -#include <json.hpp> - -#include "connection.hpp" - -namespace malikania { - -/** - * \brief Base class for connection state. - */ -class Connection::State { -protected: - void close(Connection &conn) noexcept; - - void recv(Connection &conn, std::string &input) noexcept; - - void send(Connection &conn, std::string &output) noexcept; - - nlohmann::json next(Connection &conn, std::string &input) noexcept; - -public: - /** - * Default constructor. - */ - State() = default; - - /** - * Virtual destructor defaulted. - */ - virtual ~State() = default; - - /** - * Prepare the listener about that connection. - * - * This function should not care about handshake status because the - * connection object will never call this function if a handshake is - * taking place. - * - * \param connection the connection - * \param listener the listener - */ - virtual void prepare(Connection &connection, net::Listener<> &listener) = 0; - - virtual void sync(Connection &, net::Listener<> &, net::Condition) = 0; - - virtual std::string id() const noexcept = 0; -}; - -} // !malikania - -#endif // !MALIKANIA_CONNECTION_STATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_service.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,136 @@ +/* + * connection-service.cpp -- manage clients server side + * + * Copyright (c) 2016 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 <iostream> + +#include "dao-account.hpp" +#include "connection-state-ready.hpp" +#include "connection-service.hpp" +#include "server.hpp" + +namespace malikania { + +void ConnectionService::slotAuthentication(Server &server, + Connection &connection, + const std::string &login, + const std::string &password) +{ + AccountDao dao(server.database()); + + try { + if (dao.authenticate(login, password)) { + std::cout << "client successfully authenticated" << std::endl; + server.post([&connection] (auto &) { + connection.setState(std::make_unique<Connection::ReadyState>()); + }); + } else { + std::cout << "client failed to authenticate" << std::endl; + connection.error("authentication failed"); + } + } catch (const std::exception &ex) { + // FATAL ERROR?? + } +} + +void ConnectionService::slotDisconnect(Server &, Connection &) +{ + std::cout << "client disconnected" << std::endl; +} + +void ConnectionService::syncMaster(Server &server) +{ + try { + auto socket = net::TlsSocket(m_master.accept()); + + socket.setCertificate(m_settings.certificate); + socket.setPrivateKey(m_settings.key); + + auto conn = std::make_unique<Connection>(std::move(socket)); + auto &ref = *conn; + + conn->onAuthentication.connect([this, &server, &ref] (auto login, auto password) { + this->slotAuthentication(server, ref, login, password); + }); + conn->onDisconnect.connect([this, &server, &ref] () { + this->slotDisconnect(server, ref); + }); + + m_clients.push_back(std::move(conn)); + + std::cout << "new client connected" << std::endl; + } catch (const std::exception &ex) { + // LOG ERROR SOMEWHERE + } +} + +void ConnectionService::syncClients(net::Listener<> &listener, const net::ListenerStatus &status) +{ + for (auto it = m_clients.begin(); it != m_clients.end(); ) { + auto &cnt = *it; + + if (cnt->handle() == status.socket) + cnt->sync(listener, status.flags); + + if (cnt->state().id() == "disconnected") + it = m_clients.erase(it); + else + ++ it; + } +} + +ConnectionService::ConnectionService(ConnectionSettings settings) + : m_settings(std::move(settings)) + , m_master(any(m_settings.type & ConnectionSettings::Ipv6) ? AF_INET6 : AF_INET, 0) +{ + if (any(m_settings.type & ConnectionSettings::Ipv6)) { + m_master.set(net::option::Ipv6Only(m_settings.type == ConnectionSettings::Ipv6)); + m_master.set(net::option::SockBlockMode(false)); + + if (m_settings.address == "*") + m_master.bind(net::ipv6::any(m_settings.port)); + else + m_master.bind(net::ipv6::pton(m_settings.address, m_settings.port)); + } else { + if (m_settings.address == "*") + m_master.bind(net::ipv4::any(m_settings.port)); + else + m_master.bind(net::ipv4::pton(m_settings.address, m_settings.port)); + } + + m_master.listen(256); +} + +void ConnectionService::prepare(Server &, net::Listener<> &listener) +{ + listener.reset(m_master.handle(), net::Condition::Readable); + + for (auto &cnt : m_clients) + cnt->prepare(listener); +} + +void ConnectionService::sync(Server &server, + net::Listener<> &listener, + const net::ListenerStatus &status) +{ + if (status.socket == m_master.handle()) + syncMaster(server); + else + syncClients(listener, status); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_service.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,133 @@ +/* + * connection-service.hpp -- manage clients server side + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_SERVICE_HPP +#define MALIKANIA_CONNECTION_SERVICE_HPP + +#include <cstdint> +#include <memory> +#include <vector> + +#include "connection.hpp" + +namespace malikania { + +class Server; + +/** + * \brief Connections parameters + */ +class ConnectionSettings { +public: + enum Type { + Ipv4 = (1 << 0), //!< Add IPv4 + Ipv6 = (1 << 1), //!< Add IPv6 + All = (Ipv4 | Ipv6) //!< Use both IPv4 and IPv6 on same port + } type{All}; + + std::string certificate; //!< Certificate file + std::string key; //!< Private key file + std::string address{"*"}; //!< Address to bind + std::uint16_t port{3320}; //!< Port to use +}; + +/** + * \brief Manage connections on the server + */ +class ConnectionService { +private: + ConnectionSettings m_settings; + net::TcpSocket m_master; + std::vector<std::unique_ptr<Connection>> m_clients; + + void slotAuthentication(Server &, Connection &, const std::string &, const std::string &); + void slotDisconnect(Server &, Connection &); + + void syncMaster(Server &server); + void syncClients(net::Listener<> &listener, const net::ListenerStatus &status); + +public: + ConnectionService(ConnectionSettings settings); + + inline const std::vector<std::unique_ptr<Connection>> &clients() const noexcept + { + return m_clients; + } + + inline std::vector<std::unique_ptr<Connection>> &clients() noexcept + { + return m_clients; + } + + void prepare(Server &server, net::Listener<> &listener); + + void sync(Server &server, net::Listener<> &listener, const net::ListenerStatus &status); +}; + +/** + * \cond ENUM_HIDDEN_SYMBOLS + */ + +inline ConnectionSettings::Type operator^(ConnectionSettings::Type v1, ConnectionSettings::Type v2) noexcept +{ + return static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); +} + +inline ConnectionSettings::Type operator&(ConnectionSettings::Type v1, ConnectionSettings::Type v2) noexcept +{ + return static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); +} + +inline ConnectionSettings::Type operator|(ConnectionSettings::Type v1, ConnectionSettings::Type v2) noexcept +{ + return static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); +} + +inline ConnectionSettings::Type operator~(ConnectionSettings::Type v) noexcept +{ + return static_cast<ConnectionSettings::Type>(~static_cast<unsigned>(v)); +} + +inline ConnectionSettings::Type &operator|=(ConnectionSettings::Type &v1, ConnectionSettings::Type v2) noexcept +{ + v1 = static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); + + return v1; +} + +inline ConnectionSettings::Type &operator&=(ConnectionSettings::Type &v1, ConnectionSettings::Type v2) noexcept +{ + v1 = static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); + + return v1; +} + +inline ConnectionSettings::Type &operator^=(ConnectionSettings::Type &v1, ConnectionSettings::Type v2) noexcept +{ + v1 = static_cast<ConnectionSettings::Type>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); + + return v1; +} + +/** + * \endcond + */ + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_SERVICE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,88 @@ +/* + * connection-state.cpp -- base class for connection state + * + * Copyright (c) 2016 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 <iostream> + +#include "connection-state-disconnected.hpp" +#include "connection-state.hpp" +#include "util.hpp" + +namespace malikania { + +void Connection::State::close(Connection &conn) noexcept +{ + conn.onDisconnect(); + conn.m_state = std::make_unique<DisconnectedState>(); +} + +void Connection::State::recv(Connection &conn, std::string &input) noexcept +{ + try { + std::string buffer; + std::size_t size = 512; + + buffer.resize(size); + buffer.resize(conn.m_socket.recv(&buffer[0], size)); + + if (buffer.size() == 0) + close(conn); + + input += buffer; + } catch (const net::WantReadError &) { + conn.m_handshake = Handshake::Reading; + } catch (const net::WantWriteError &) { + conn.m_handshake = Handshake::Writing; + } catch (const std::exception &) { + close(conn); + } +} + +void Connection::State::send(Connection &conn, std::string &output) noexcept +{ + assert(output.length() != 0); + + try { + auto nsent = conn.m_socket.send(&output[0], output.length()); + + if (nsent == 0) + close(conn); + + output.erase(0, nsent); + } catch (const net::WantReadError &) { + conn.m_handshake = Handshake::Reading; + } catch (const net::WantWriteError &) { + conn.m_handshake = Handshake::Writing; + } catch (const std::exception &) { + close(conn); + } +} + +nlohmann::json Connection::State::next(Connection &conn, std::string &input) noexcept +{ + nlohmann::json object; + + try { + object = util::json::next(input); + } catch (const std::exception &) { + close(conn); + } + + return object; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,76 @@ +/* + * connection-state.hpp -- base class for connection state + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_HPP +#define MALIKANIA_CONNECTION_STATE_HPP + +/** + * \file connection-state.hpp + * \brief Base class for connection state. + */ + +#include <json.hpp> + +#include "connection.hpp" + +namespace malikania { + +/** + * \brief Base class for connection state. + */ +class Connection::State { +protected: + void close(Connection &conn) noexcept; + + void recv(Connection &conn, std::string &input) noexcept; + + void send(Connection &conn, std::string &output) noexcept; + + nlohmann::json next(Connection &conn, std::string &input) noexcept; + +public: + /** + * Default constructor. + */ + State() = default; + + /** + * Virtual destructor defaulted. + */ + virtual ~State() = default; + + /** + * Prepare the listener about that connection. + * + * This function should not care about handshake status because the + * connection object will never call this function if a handshake is + * taking place. + * + * \param connection the connection + * \param listener the listener + */ + virtual void prepare(Connection &connection, net::Listener<> &listener) = 0; + + virtual void sync(Connection &, net::Listener<> &, net::Condition) = 0; + + virtual std::string id() const noexcept = 0; +}; + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_STATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_authenticating.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,50 @@ +/* + * connection-state-authenticating.cpp -- user is authenticating + * + * Copyright (c) 2016 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 "connection-state-authenticating.hpp" + +namespace malikania { + +void Connection::AuthenticatingState::prepare(Connection &conn, net::Listener<> &listener) +{ + listener.reset(conn.m_socket.handle(), net::Condition::Readable); +} + +void Connection::AuthenticatingState::sync(Connection &conn, net::Listener<> &, net::Condition) +{ + recv(conn, m_input); + + auto value = next(conn, m_input); + + if (!value.is_object()) + return; + + auto login = value.find("login"); + auto password = value.find("password"); + + if (login != value.end() && login->is_string() && + password != value.end() && password->is_string()) + conn.onAuthentication(*login, *password); +} + +std::string Connection::AuthenticatingState::id() const noexcept +{ + return "authenticating"; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_authenticating.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,48 @@ +/* + * connection-state-authenticating.hpp -- user is authenticating + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_AUTHENTICATING_HPP +#define MALIKANIA_CONNECTION_STATE_AUTHENTICATING_HPP + +/** + * \file connection-state-authenticating.hpp + * \brief User is authenticating. + */ + +#include "connection-state.hpp" + +namespace malikania { + +/** + * \brief User is authenticating. + */ +class Connection::AuthenticatingState : public Connection::State { +private: + std::string m_input; + +public: + void prepare(Connection &conn, net::Listener<> &listener) override; + + void sync(Connection &conn, net::Listener<> &, net::Condition) override; + + std::string id() const noexcept override; +}; + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_STATE_AUTHENTICATING_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_closing.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,45 @@ +/* + * connection-state-closing.hpp -- closing connection to the user + * + * Copyright (c) 2016 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 "connection-state-disconnected.hpp" +#include "connection-state-closing.hpp" + +namespace malikania { + +void Connection::ClosingState::prepare(Connection &conn, net::Listener<> &listener) +{ + if (conn.m_output.empty()) + listener.remove(conn.handle()); + else + listener.reset(conn.handle(), net::Condition::Writable); +} + +void Connection::ClosingState::sync(Connection &conn, net::Listener<> &, net::Condition) +{ + send(conn, conn.m_output); + + if (conn.m_output.empty()) + conn.m_stateNext = std::make_unique<DisconnectedState>(); +} + +std::string Connection::ClosingState::id() const noexcept +{ + return "closing"; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_closing.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,45 @@ +/* + * connection-state-closing.hpp -- closing connection to the user + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_CLOSING_HPP +#define MALIKANIA_CONNECTION_STATE_CLOSING_HPP + +/** + * \file connection-state-closing.hpp + * \brief Closing connection to the user. + */ + +#include "connection-state.hpp" + +namespace malikania { + +/** + * \brief Closing connection to the user. + */ +class Connection::ClosingState : public Connection::State { +public: + void prepare(Connection &conn, net::Listener<> &listener) override; + + void sync(Connection &conn, net::Listener<> &, net::Condition) override; + + std::string id() const noexcept override; +}; + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_STATE_CLOSING_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_disconnected.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,36 @@ +/* + * connection-state-disconnected.cpp -- client is down and will be removed + * + * Copyright (c) 2016 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 "connection-state-disconnected.hpp" + +namespace malikania { + +void Connection::DisconnectedState::prepare(Connection &, net::Listener<> &) +{ +} + +void Connection::DisconnectedState::sync(Connection &, net::Listener<> &, net::Condition) +{ +} + +std::string Connection::DisconnectedState::id() const noexcept +{ + return "disconnected"; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_disconnected.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,45 @@ +/* + * connection-state-disconnected.hpp -- client is down and will be removed + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_DISCONNECTED_HPP +#define MALIKANIA_CONNECTION_STATE_DISCONNECTED_HPP + +/** + * \file connection-state-disconected.hpp + * \brief Client is down and will be removed. + */ + +#include "connection-state.hpp" + +namespace malikania { + +/** + * \brief Client is down and will be removed. + */ +class Connection::DisconnectedState : public Connection::State { +public: + void prepare(Connection &conn, net::Listener<> &listener) override; + + void sync(Connection &conn, net::Listener<> &, net::Condition) override; + + std::string id() const noexcept override; +}; + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_STATE_DISCONNECTED_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_greeting.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,57 @@ +/* + * connection-state-greeting.cpp -- greeting the user + * + * Copyright (c) 2016 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 <json.hpp> + +#include "connection-state-authenticating.hpp" +#include "connection-state-greeting.hpp" + +namespace malikania { + +Connection::GreetingState::GreetingState() +{ + // TODO: this is just an example. + m_output += nlohmann::json::object({ + { "malikania", "0.1.0" } + }).dump(); + m_output += "\r\n\r\n"; +} + +void Connection::GreetingState::prepare(Connection &conn, net::Listener<> &listener) +{ + listener.reset(conn.m_socket.handle(), net::Condition::Writable); +} + +void Connection::GreetingState::sync(Connection &conn, net::Listener<> &listener, net::Condition condition) +{ + assert(condition == net::Condition::Writable); + + if (m_output.length() > 0) + send(conn, m_output); + else { + listener.unset(conn.handle(), net::Condition::Writable); + conn.m_stateNext = std::make_unique<AuthenticatingState>(); + } +} + +std::string Connection::GreetingState::id() const noexcept +{ + return "greeting"; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_greeting.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,50 @@ +/* + * connection-state-greeting.hpp -- greeting the user + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_GREETING_HPP +#define MALIKANIA_CONNECTION_STATE_GREETING_HPP + +/** + * \file connection-state-greeting.hpp + * \brief Greeting the user. + */ + +#include "connection-state.hpp" + +namespace malikania { + +/** + * \brief Greeting the user. + */ +class Connection::GreetingState : public Connection::State { +private: + std::string m_output; + +public: + GreetingState(); + + void prepare(Connection &conn, net::Listener<> &listener) override; + + void sync(Connection &conn, net::Listener<> &listener, net::Condition condition) override; + + std::string id() const noexcept override; +}; + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_STATE_GREETING_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_ready.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,49 @@ +/* + * connection-state-ready.cpp -- client is ready + * + * Copyright (c) 2016 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 "connection-state-ready.hpp" + +namespace malikania { + +void Connection::ReadyState::prepare(Connection &conn, net::Listener<> &listener) +{ + if (!conn.m_output.empty()) + listener.reset(conn.handle(), net::Condition::Writable); + + listener.reset(conn.handle(), net::Condition::Readable); +} + +void Connection::ReadyState::sync(Connection &conn, net::Listener<> &lst, net::Condition cond) +{ + if (bool(cond & net::Condition::Readable)) + recv(conn, conn.m_input); + + if (bool(cond & net::Condition::Writable)) { + send(conn, conn.m_output); + + if (conn.m_output.empty()) + lst.unset(conn.handle(), net::Condition::Writable); + } +} + +std::string Connection::ReadyState::id() const noexcept +{ + return "ready"; +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver/malikania/connection_state_ready.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -0,0 +1,45 @@ +/* + * connection-state-ready.hpp -- client is ready + * + * Copyright (c) 2016 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 MALIKANIA_CONNECTION_STATE_READY_HPP +#define MALIKANIA_CONNECTION_STATE_READY_HPP + +/** + * \file connection-state-ready.hpp + * \brief Client is ready. + */ + +#include "connection-state.hpp" + +namespace malikania { + +/** + * \brief Client is ready. + */ +class Connection::ReadyState : public Connection::State { +public: + void prepare(Connection &conn, net::Listener<> &listener) override; + + void sync(Connection &conn, net::Listener<> &listener, net::Condition condition) override; + + std::string id() const noexcept override; +}; + +} // !malikania + +#endif // !MALIKANIA_CONNECTION_STATE_READY_HPP
--- a/libserver/malikania/dao-account.cpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * dao-account.cpp -- database account management - * - * Copyright (c) 2013-2016 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 "account.hpp" -#include "dao-account.hpp" -#include "database.hpp" - -namespace malikania { - -using Create = void (Account&); -using Remove = void (const Account&); -using Update = void (Account&); -using Get = Account (std::uint64_t); -using List = std::vector<Account> (); -using Count = std::uint64_t (); -using Clear = void (); - -void AccountDao::create(Account &account) -{ - m_database.handle().get<Create>("malikania_account_create")(account); -} - -void AccountDao::remove(const Account &account) -{ - m_database.handle().get<Remove>("malikania_account_remove")(account); -} - -void AccountDao::update(Account &account) -{ - m_database.handle().get<Update>("malikania_account_update")(account); -} - -Account AccountDao::get(uint64_t id) -{ - return m_database.handle().get<Get>("malikania_account_get")(id); -} - -std::vector<Account> AccountDao::list() -{ - return m_database.handle().get<List>("malikania_account_list")(); -} - -std::uint64_t AccountDao::count() -{ - return m_database.handle().get<Count>("malikania_account_count")(); -} - -void AccountDao::clear() -{ - m_database.handle().get<Clear>("malikania_account_clear")(); -} - -} // !malikania
--- a/libserver/malikania/dao-account.hpp Sun Nov 27 20:50:38 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * dao-account.hpp -- database account management - * - * Copyright (c) 2013-2016 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 MALIKANIA_DAO_ACCOUNT_HPP -#define MALIKANIA_DAO_ACCOUNT_HPP - -/** - * \file dao-account.hpp - * \brief Database account management. - */ - -#include <cstdint> -#include <vector> - -namespace malikania { - -class Database; -class Account; - -/** - * \brief Account DAO. - */ -class AccountDao { -private: - Database &m_database; - -public: - /** - * Constructor. - * - * \param database the database - */ - inline AccountDao(Database &database) noexcept - : m_database(database) - { - } - - /** - * Create the given account. - * - * The object will be modified in place. - * - * \param account the account to add - * \throw std::exception on errors - */ - void create(Account &account); - - /** - * Remove the given account, all data that references this account is deleted too. - * - * \param account the account - * \throw std::exception on errors - */ - void remove(const Account &account); - - /** - * Update account only, does not recurse into objects that references the account. - * - * \param account the account - * \throw std::exception on errors - */ - void update(Account &account); - - /** - * Get an account. - * - * \param id the account id - * \return the account - * \throw std::exception if not found - */ - Account get(std::uint64_t id); - - /** - * Get the list of account. - * - * \throw std::exception on errors - */ - std::vector<Account> list(); - - /** - * Get the number of accounts. - * - * \return the number of account. - */ - std::uint64_t count(); - - /** - * Remove all accounts recursively. - * - * \throw std::exception on errors - * \warning use with care - */ - void clear(); -}; - -} // !malikania - -#endif // !MALIKANIA_DAO_ACCOUNT_HPP
--- a/libserver/malikania/database.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libserver/malikania/database.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -20,18 +20,18 @@ namespace malikania { -using Load = void (const std::unordered_map<std::string, std::string>&); -using Unload = void (); +using load_func = void (const std::unordered_map<std::string, std::string>&); +using unload_func = void (); -Database::Database(const std::string &path, const std::unordered_map<std::string, std::string> ¶ms) +database::database(const std::string& path, const std::unordered_map<std::string, std::string>& params) : m_dso(path) { - m_dso.get<Load>("malikania_driver_load")(params); + m_dso.get<load_func>("malikania_driver_load")(params); } -Database::~Database() +database::~database() { - m_dso.get<Unload>("malikania_driver_unload")(); + m_dso.get<unload_func>("malikania_driver_unload")(); } } // !malikania
--- a/libserver/malikania/database.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/libserver/malikania/database.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -34,7 +34,7 @@ /** * \brief Generic database. */ -class Database { +class database { private: boost::dll::shared_library m_dso; @@ -48,12 +48,12 @@ * \param params the parameters to pass to the driver * \throw std::exception on errors */ - Database(const std::string &type, const std::unordered_map<std::string, std::string> ¶ms); + database(const std::string& type, const std::unordered_map<std::string, std::string>& params); /** * Close the database. */ - ~Database(); + ~database(); /** * Get the associated dso handle.
--- a/server/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/server/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -16,40 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <iostream> - -#include "malikania/account.hpp" -#include "malikania/dao-account.hpp" -#include "malikania/database.hpp" - -using namespace malikania; - -int main(int, char **) +int main() { - try { - Database database("./pgsql", { - { "user", "kingdom" }, - { "host", "localhost" }, - { "database", "kingdomdb" } - }); - - AccountDao act(database); - Account account; - - account.setId(2); - - act.remove(account); - - for (const Account &ac : act.list()) { - std::cout << "id : " << ac.id() << std::endl; - std::cout << "name : " << ac.name() << std::endl; - std::cout << "email : " << ac.email() << std::endl; - std::cout << "firstname : " << ac.firstName() << std::endl; - std::cout << "lastname : " << ac.lastName() << std::endl; - } - } catch (const std::exception &ex) { - std::cerr << ex.what() << std::endl; - } - - return 0; }
--- a/tests/libclient/animation/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/animation/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Animation + * main.cpp -- test animation * * Copyright (c) 2013-2016 Malikania Authors * @@ -24,24 +24,22 @@ #include <malikania/animation.hpp> #include <malikania/animator.hpp> -#include <malikania/client-resources-loader.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/client_resources_loader.hpp> +#include <malikania/resources_locator.hpp> #include <malikania/window.hpp> -using namespace malikania; - using namespace std::chrono_literals; namespace { -Window window(400, 400); +malikania::window window(400, 400); } // !namespace class TestAnimation : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; + malikania::directory_resources_locator m_locator; + malikania::client_resources_loader m_loader; public: TestAnimation() @@ -54,7 +52,7 @@ TEST_F(TestAnimation, standard) { try { - Animation animation = m_loader.loadAnimation("animations/margins.json"); + auto animation = m_loader.load_animation("animations/margins.json"); ASSERT_EQ(12U, animation.frames().size()); ASSERT_EQ(500U, animation[0].delay()); @@ -79,15 +77,15 @@ boost::timer::cpu_timer timer; try { - Animation animation = m_loader.loadAnimation("animations/margins.json"); - Animator animator(animation); + malikania::animation animation = m_loader.load_animation("animations/margins.json"); + malikania::animator animator(animation); auto x = (400 / 2) - (animation.sprite().cell().width() / 2); auto y = (400 / 2) - (animation.sprite().cell().height() / 2); while (timer.elapsed().wall / 1000000LL < 8000) { window.clear(); - animator.draw(window, Point(x, y)); + animator.draw(window, malikania::point(x, y)); animator.update(); window.present(); }
--- a/tests/libclient/color/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/color/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Color + * main.cpp -- test color * * Copyright (c) 2013-2016 Malikania Authors * @@ -29,7 +29,7 @@ TEST(Basic, black) { - Color c; + color c; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -39,7 +39,7 @@ TEST(Basic, white) { - Color c{255, 255, 255, 255}; + color c{255, 255, 255, 255}; ASSERT_EQ(255, c.red()); ASSERT_EQ(255, c.green()); @@ -49,7 +49,7 @@ TEST(Basic, red) { - Color c{255, 0, 0, 255}; + color c{255, 0, 0, 255}; ASSERT_EQ(255, c.red()); ASSERT_EQ(0, c.green()); @@ -59,7 +59,7 @@ TEST(Basic, green) { - Color c{0, 255, 0, 255}; + color c{0, 255, 0, 255}; ASSERT_EQ(0, c.red()); ASSERT_EQ(255, c.green()); @@ -69,7 +69,7 @@ TEST(Basic, blue) { - Color c{0, 0, 255, 255}; + color c{0, 0, 255, 255}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -84,7 +84,7 @@ TEST(Hex, black) { - Color c{0xff000000}; + color c{0xff000000}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -94,7 +94,7 @@ TEST(Hex, white) { - Color c{0xffffffff}; + color c{0xffffffff}; ASSERT_EQ(255, c.red()); ASSERT_EQ(255, c.green()); @@ -104,7 +104,7 @@ TEST(Hex, red) { - Color c{0xffff0000}; + color c{0xffff0000}; ASSERT_EQ(255, c.red()); ASSERT_EQ(0, c.green()); @@ -114,7 +114,7 @@ TEST(Hex, green) { - Color c{0xff00ff00}; + color c{0xff00ff00}; ASSERT_EQ(0, c.red()); ASSERT_EQ(255, c.green()); @@ -124,7 +124,7 @@ TEST(Hex, blue) { - Color c{0xff0000ff}; + color c{0xff0000ff}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -141,7 +141,7 @@ TEST(Named, black) { - Color c{"black"}; + color c{"black"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -151,7 +151,7 @@ TEST(Named, white) { - Color c{"white"}; + color c{"white"}; ASSERT_EQ(255, c.red()); ASSERT_EQ(255, c.green()); @@ -161,7 +161,7 @@ TEST(Named, red) { - Color c{"red"}; + color c{"red"}; ASSERT_EQ(255, c.red()); ASSERT_EQ(0, c.green()); @@ -171,7 +171,7 @@ TEST(Named, green) { - Color c{"green"}; + color c{"green"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(128, c.green()); @@ -181,7 +181,7 @@ TEST(Named, blue) { - Color c{"blue"}; + color c{"blue"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -192,7 +192,7 @@ TEST(Named, wrong) { try { - Color c{"does not exist"}; + color c{"does not exist"}; FAIL() << "exception expected"; } catch (const std::exception &) { @@ -208,7 +208,7 @@ TEST(FullRgb, black) { - Color c{"#000000"}; + color c{"#000000"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -218,7 +218,7 @@ TEST(FullRgb, white) { - Color c{"#ffffff"}; + color c{"#ffffff"}; ASSERT_EQ(255, c.red()); ASSERT_EQ(255, c.green()); @@ -228,7 +228,7 @@ TEST(FullRgb, red) { - Color c{"#ff0000"}; + color c{"#ff0000"}; ASSERT_EQ(255, c.red()); ASSERT_EQ(0, c.green()); @@ -238,7 +238,7 @@ TEST(FullRgb, green) { - Color c{"#00ff00"}; + color c{"#00ff00"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(255, c.green()); @@ -248,7 +248,7 @@ TEST(FullRgb, blue) { - Color c{"#0000ff"}; + color c{"#0000ff"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -259,7 +259,7 @@ TEST(FullRgb, wrong) { try { - Color c{"#ghijkl"}; + color c{"#ghijkl"}; FAIL() << "exception expected"; } catch (const std::exception &) { @@ -275,7 +275,7 @@ TEST(ShortRgb, black) { - Color c{"#000"}; + color c{"#000"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -285,7 +285,7 @@ TEST(ShortRgb, white) { - Color c{"#fff"}; + color c{"#fff"}; ASSERT_EQ(255, c.red()); ASSERT_EQ(255, c.green()); @@ -295,7 +295,7 @@ TEST(ShortRgb, red) { - Color c{"#f00"}; + color c{"#f00"}; ASSERT_EQ(255, c.red()); ASSERT_EQ(0, c.green()); @@ -305,7 +305,7 @@ TEST(ShortRgb, green) { - Color c{"#0f0"}; + color c{"#0f0"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(255, c.green()); @@ -315,7 +315,7 @@ TEST(ShortRgb, blue) { - Color c{"#00f"}; + color c{"#00f"}; ASSERT_EQ(0, c.red()); ASSERT_EQ(0, c.green()); @@ -325,7 +325,7 @@ TEST(ShortRgb, combination) { - Color c{"#123"}; + color c{"#123"}; ASSERT_EQ(17, c.red()); ASSERT_EQ(34, c.green()); @@ -336,7 +336,7 @@ TEST(ShortRgb, wrong) { try { - Color c{"#ghi"}; + color c{"#ghi"}; FAIL() << "exception expected"; } catch (const std::exception &) {
--- a/tests/libclient/font/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/font/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,44 +21,44 @@ #include <gtest/gtest.h> -#include <malikania/client-resources-loader.hpp> +#include <malikania/client_resources_loader.hpp> #include <malikania/color.hpp> #include <malikania/font.hpp> #include <malikania/point.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/resources_locator.hpp> #include <malikania/window.hpp> -using namespace malikania; - using namespace std::chrono_literals; +namespace mlk = malikania; + namespace { -Window window(400, 400); +mlk::window window(400, 400); } // !namespace class TestFont : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; - Font m_font; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; + mlk::font m_font; public: TestFont() : m_locator(SOURCE_DIRECTORY "/resources") , m_loader(m_locator) - , m_font(m_loader.loadFont("DejaVuSans.ttf", 10)) + , m_font(m_loader.load_font("DejaVuSans.ttf", 10)) { - window.setDrawingColor(Color("black")); + window.set_drawing_color(mlk::color("black")); window.clear(); } }; TEST_F(TestFont, topleft) { - window.setDrawingColor(Color("white")); - window.drawText("top left", m_font, Point(10, 10)); + window.set_drawing_color(mlk::color("white")); + window.draw_text("top left", m_font, mlk::point(10, 10)); window.present(); std::this_thread::sleep_for(1s); @@ -66,10 +66,10 @@ TEST_F(TestFont, topright) { - Size dim = m_font.clip("top right"); + auto dim = m_font.clip("top right"); - window.setDrawingColor(Color("white")); - window.drawText("top right", m_font, Point(400 - dim.width() - 10, 10)); + window.set_drawing_color(mlk::color("white")); + window.draw_text("top right", m_font, mlk::point(400 - dim.width() - 10, 10)); window.present(); std::this_thread::sleep_for(1s); @@ -78,10 +78,10 @@ TEST_F(TestFont, bottomleft) { - Size dim = m_font.clip("bottom left"); + auto dim = m_font.clip("bottom left"); - window.setDrawingColor(Color("white")); - window.drawText("bottom left", m_font, Point(10, 400 - dim.height() - 10)); + window.set_drawing_color(mlk::color("white")); + window.draw_text("bottom left", m_font, mlk::point(10, 400 - dim.height() - 10)); window.present(); std::this_thread::sleep_for(1s); @@ -89,10 +89,10 @@ TEST_F(TestFont, bottomright) { - Size dim = m_font.clip("bottom right"); + auto dim = m_font.clip("bottom right"); - window.setDrawingColor(Color("white")); - window.drawText("bottom right", m_font, Point(400 - dim.width() - 10, 400 - dim.height() - 10)); + window.set_drawing_color(mlk::color("white")); + window.draw_text("bottom right", m_font, mlk::point(400 - dim.width() - 10, 400 - dim.height() - 10)); window.present(); std::this_thread::sleep_for(1s); @@ -100,10 +100,10 @@ TEST_F(TestFont, center) { - Size dim = m_font.clip("center"); + auto dim = m_font.clip("center"); - window.setDrawingColor(Color("white")); - window.drawText("center", m_font, Point(200 - (dim.width() / 2), 200 - (dim.height() -2))); + window.set_drawing_color(mlk::color("white")); + window.draw_text("center", m_font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2))); window.present(); std::this_thread::sleep_for(1s); @@ -111,10 +111,10 @@ TEST_F(TestFont, center2) { - Size dim = m_font.clip("The world is Malikania."); + auto dim = m_font.clip("The world is Malikania."); - window.setDrawingColor(Color("white")); - window.drawText("The world is Malikania.", m_font, Point(200 - (dim.width() / 2), 200 - (dim.height() -2))); + window.set_drawing_color(mlk::color("white")); + window.draw_text("The world is Malikania.", m_font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2))); window.present(); std::this_thread::sleep_for(3s);
--- a/tests/libclient/image/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/image/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,25 +21,25 @@ #include <gtest/gtest.h> -#include <malikania/client-resources-loader.hpp> +#include <malikania/client_resources_loader.hpp> #include <malikania/image.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/resources_locator.hpp> #include <malikania/window.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; namespace { -Window window(400, 400); +mlk::window window(400, 400); } // !namespace class TestImage : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; public: TestImage() @@ -52,7 +52,7 @@ TEST_F(TestImage, image100x10) { try { - Image image = m_loader.loadImage("images/100x10.png"); + auto image = m_loader.load_image("images/100x10.png"); ASSERT_EQ(100U, image.size().width()); ASSERT_EQ(10U, image.size().height()); @@ -64,7 +64,7 @@ TEST_F(TestImage, image16x16) { try { - Image image = m_loader.loadImage("images/16x16.png"); + auto image = m_loader.load_image("images/16x16.png"); ASSERT_EQ(16U, image.size().width()); ASSERT_EQ(16U, image.size().height()); @@ -76,7 +76,7 @@ TEST_F(TestImage, image10x100) { try { - Image image = m_loader.loadImage("images/10x100.png"); + auto image = m_loader.load_image("images/10x100.png"); ASSERT_EQ(10U, image.size().width()); ASSERT_EQ(100U, image.size().height()); @@ -88,7 +88,7 @@ TEST_F(TestImage, notfound) { try { - m_loader.loadImage("image-not-found"); + m_loader.load_image("image-not-found"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -103,12 +103,12 @@ TEST_F(TestImage, draw) { try { - auto image = m_loader.loadImage("images/smiley.png"); + auto image = m_loader.load_image("images/smiley.png"); auto x = (400 / 2) - (image.size().width() / 2); auto y = (400 / 2) - (image.size().height() / 2); window.clear(); - image.draw(window, Point(x, y)); + image.draw(window, mlk::point(x, y)); window.present(); std::this_thread::sleep_for(3s);
--- a/tests/libclient/js-animation/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-animation/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,20 +21,20 @@ #include <gtest/gtest.h> -#include <malikania/js-client-resources-loader.hpp> -#include <malikania/js-animation.hpp> -#include <malikania/js-animator.hpp> -#include <malikania/js-window.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/js_client_resources_loader.hpp> +#include <malikania/js_animation.hpp> +#include <malikania/js_animator.hpp> +#include <malikania/js_window.hpp> +#include <malikania/resources_locator.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; class TestAnimation : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; UniqueContext m_ctx; public: @@ -44,10 +44,10 @@ { duk_push_object(m_ctx); duk_put_global_string(m_ctx, "Malikania"); - dukx_load_animation(m_ctx); - dukx_load_animator(m_ctx); - dukx_load_window(m_ctx); - dukx_put_client_loader(m_ctx, &m_loader); + mlk::dukx_load_animation(m_ctx); + mlk::dukx_load_animator(m_ctx); + mlk::dukx_load_window(m_ctx); + dukx_put_client_loader(m_ctx, m_loader); } };
--- a/tests/libclient/js-color/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-color/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -18,7 +18,7 @@ #include <gtest/gtest.h> -#include <malikania/js-color.hpp> +#include <malikania/js_color.hpp> using namespace malikania; @@ -487,7 +487,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Color color = dukx_require_color(ctx, 0); + auto color = dukx_require_color(ctx, 0); duk_push_uint(ctx, color.red()); duk_put_global_string(ctx, "r"); @@ -601,7 +601,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Color color = dukx_get_color(ctx, 0); + auto color = dukx_get_color(ctx, 0); duk_push_uint(ctx, color.red()); duk_put_global_string(ctx, "r"); @@ -642,7 +642,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Color color = dukx_get_color(ctx, 0); + auto color = dukx_get_color(ctx, 0); duk_push_uint(ctx, color.red()); duk_put_global_string(ctx, "r"); @@ -683,7 +683,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Color color = dukx_get_color(ctx, 0); + auto color = dukx_get_color(ctx, 0); duk_push_uint(ctx, color.red()); duk_put_global_string(ctx, "r"); @@ -724,7 +724,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Color color = dukx_get_color(ctx, 0); + auto color = dukx_get_color(ctx, 0); duk_push_uint(ctx, color.red()); duk_put_global_string(ctx, "r");
--- a/tests/libclient/js-font/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-font/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,19 +21,19 @@ #include <gtest/gtest.h> -#include <malikania/js-client-resources-loader.hpp> -#include <malikania/js-font.hpp> -#include <malikania/js-window.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/js_client_resources_loader.hpp> +#include <malikania/js_font.hpp> +#include <malikania/js_window.hpp> +#include <malikania/resources_locator.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; class TestFont : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; UniqueContext m_ctx; public: @@ -43,9 +43,9 @@ { duk_push_object(m_ctx); duk_put_global_string(m_ctx, "Malikania"); - dukx_put_client_loader(m_ctx, &m_loader); - dukx_load_font(m_ctx); - dukx_load_window(m_ctx); + dukx_put_client_loader(m_ctx, m_loader); + mlk::dukx_load_font(m_ctx); + mlk::dukx_load_window(m_ctx); } }; @@ -64,8 +64,9 @@ "w.present();" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } std::this_thread::sleep_for(3s); } catch (const std::exception &ex) {
--- a/tests/libclient/js-image/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-image/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,19 +21,19 @@ #include <gtest/gtest.h> -#include <malikania/js-client-resources-loader.hpp> -#include <malikania/js-image.hpp> -#include <malikania/js-window.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/js_client_resources_loader.hpp> +#include <malikania/js_image.hpp> +#include <malikania/js_window.hpp> +#include <malikania/resources_locator.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; class TestImage : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; UniqueContext m_ctx; public: @@ -43,9 +43,9 @@ { duk_push_object(m_ctx); duk_put_global_string(m_ctx, "Malikania"); - dukx_load_image(m_ctx); - dukx_load_window(m_ctx); - dukx_put_client_loader(m_ctx, &m_loader); + mlk::dukx_load_image(m_ctx); + mlk::dukx_load_window(m_ctx); + dukx_put_client_loader(m_ctx, m_loader); } };
--- a/tests/libclient/js-line/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-line/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -18,7 +18,7 @@ #include <gtest/gtest.h> -#include <malikania/js-line.hpp> +#include <malikania/js_line.hpp> using namespace malikania; @@ -51,8 +51,9 @@ "y2 = r.y2;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x1"); ASSERT_EQ(0, duk_to_int(m_ctx, -1)); @@ -82,8 +83,9 @@ "y2 = r.y2;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x1"); ASSERT_EQ(10, duk_to_int(m_ctx, -1)); @@ -113,8 +115,9 @@ "y2 = r.y2;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x1"); ASSERT_EQ(10, duk_to_int(m_ctx, -1)); @@ -144,8 +147,9 @@ "y2 = r.y2;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x1"); ASSERT_EQ(10, duk_to_int(m_ctx, -1)); @@ -181,8 +185,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("TypeError", duk_to_string(m_ctx, -1)); @@ -204,7 +209,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Line line = dukx_require_line(ctx, 0); + auto line = dukx_require_line(ctx, 0); duk_push_int(ctx, line.x1()); duk_put_global_string(ctx, "x1"); @@ -221,8 +226,9 @@ auto ret = duk_peval_string(m_ctx, "build({ x1: 50, y1: 80, x2: 100, y2: 200 });"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x1"); ASSERT_EQ(50, duk_to_int(m_ctx, -1)); @@ -260,8 +266,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("Error", duk_to_string(m_ctx, -1)); @@ -283,7 +290,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Line line = dukx_get_line(ctx, 0); + auto line = dukx_get_line(ctx, 0); duk_push_int(ctx, line.x1()); duk_put_global_string(ctx, "x1"); @@ -300,8 +307,9 @@ auto ret = duk_peval_string(m_ctx, "build({});"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x1"); ASSERT_EQ(0, duk_to_int(m_ctx, -1));
--- a/tests/libclient/js-point/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-point/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -18,7 +18,7 @@ #include <gtest/gtest.h> -#include <malikania/js-point.hpp> +#include <malikania/js_point.hpp> using namespace malikania; @@ -49,8 +49,9 @@ "y = p.y;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(0, duk_to_int(m_ctx, -1)); @@ -72,8 +73,9 @@ "y = p.y;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(-10, duk_to_int(m_ctx, -1)); @@ -95,8 +97,9 @@ "y = p.y;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(100, duk_to_int(m_ctx, -1)); @@ -118,8 +121,9 @@ "y = p.y;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(100, duk_to_int(m_ctx, -1)); @@ -149,8 +153,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("TypeError", duk_to_string(m_ctx, -1)); @@ -172,7 +177,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Point point = dukx_require_point(ctx, 0); + auto point = dukx_require_point(ctx, 0); duk_push_int(ctx, point.x()); duk_put_global_string(ctx, "x"); @@ -185,8 +190,9 @@ auto ret = duk_peval_string(m_ctx, "build({ x: 100, y: 200 });"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(100, duk_to_int(m_ctx, -1)); @@ -218,8 +224,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("Error", duk_to_string(m_ctx, -1)); @@ -241,7 +248,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Point point = dukx_get_point(ctx, 0); + auto point = dukx_get_point(ctx, 0); duk_push_int(ctx, point.x()); duk_put_global_string(ctx, "x"); @@ -254,8 +261,9 @@ auto ret = duk_peval_string(m_ctx, "build({});"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(0, duk_to_int(m_ctx, -1));
--- a/tests/libclient/js-rectangle/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-rectangle/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -18,7 +18,7 @@ #include <gtest/gtest.h> -#include <malikania/js-rectangle.hpp> +#include <malikania/js_rectangle.hpp> using namespace malikania; @@ -51,8 +51,9 @@ "h = r.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(0, duk_to_int(m_ctx, -1)); @@ -82,8 +83,9 @@ "h = r.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(10, duk_to_int(m_ctx, -1)); @@ -113,8 +115,9 @@ "h = r.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(10, duk_to_int(m_ctx, -1)); @@ -144,8 +147,9 @@ "h = r.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(10, duk_to_int(m_ctx, -1)); @@ -181,8 +185,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("TypeError", duk_to_string(m_ctx, -1)); @@ -207,8 +212,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("RangeError", duk_to_string(m_ctx, -1)); @@ -230,7 +236,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Rectangle rect = dukx_require_rect(ctx, 0); + auto rect = dukx_require_rect(ctx, 0); duk_push_int(ctx, rect.x()); duk_put_global_string(ctx, "x"); @@ -247,8 +253,9 @@ auto ret = duk_peval_string(m_ctx, "build({ x: 50, y: 80, width: 100, height: 200 });"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(50, duk_to_int(m_ctx, -1)); @@ -286,8 +293,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("Error", duk_to_string(m_ctx, -1)); @@ -309,7 +317,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Rectangle rect = dukx_get_rect(ctx, 0); + auto rect = dukx_get_rect(ctx, 0); duk_push_int(ctx, rect.x()); duk_put_global_string(ctx, "x"); @@ -325,8 +333,9 @@ auto ret = duk_peval_string(m_ctx, "build({});"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "x"); ASSERT_EQ(0, duk_to_int(m_ctx, -1));
--- a/tests/libclient/js-size/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-size/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -18,7 +18,7 @@ #include <gtest/gtest.h> -#include <malikania/js-size.hpp> +#include <malikania/js_size.hpp> using namespace malikania; @@ -49,8 +49,9 @@ "h = s.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); ASSERT_EQ(0U, duk_to_uint(m_ctx, -1)); @@ -72,8 +73,9 @@ "h = s.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); ASSERT_EQ(100U, duk_to_uint(m_ctx, -1)); @@ -95,8 +97,9 @@ "h = s.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); ASSERT_EQ(100U, duk_to_uint(m_ctx, -1)); @@ -118,8 +121,9 @@ "h = s.height;" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); ASSERT_EQ(100U, duk_to_uint(m_ctx, -1)); @@ -149,8 +153,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("TypeError", duk_to_string(m_ctx, -1)); @@ -175,8 +180,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("RangeError", duk_to_string(m_ctx, -1)); @@ -201,8 +207,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("RangeError", duk_to_string(m_ctx, -1)); @@ -227,8 +234,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("RangeError", duk_to_string(m_ctx, -1)); @@ -253,8 +261,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("RangeError", duk_to_string(m_ctx, -1)); @@ -276,7 +285,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Size size = dukx_require_size(ctx, 0); + auto size = dukx_require_size(ctx, 0); duk_push_uint(ctx, size.width()); duk_put_global_string(ctx, "w"); @@ -289,8 +298,9 @@ auto ret = duk_peval_string(m_ctx, "build({ width: 100, height: 200 });"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); ASSERT_EQ(100U, duk_to_uint(m_ctx, -1)); @@ -322,8 +332,9 @@ "}" ); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "name"); ASSERT_STREQ("Error", duk_to_string(m_ctx, -1)); @@ -345,7 +356,7 @@ { try { duk_push_c_function(m_ctx, [] (auto ctx) { - Size size = dukx_get_size(ctx, 0); + auto size = dukx_get_size(ctx, 0); duk_push_uint(ctx, size.width()); duk_put_global_string(ctx, "w"); @@ -358,8 +369,9 @@ auto ret = duk_peval_string(m_ctx, "build({});"); - if (ret != 0) + if (ret != 0) { throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); ASSERT_EQ(0U, duk_to_uint(m_ctx, -1));
--- a/tests/libclient/js-sprite/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-sprite/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,172 +21,178 @@ #include <gtest/gtest.h> -#include <malikania/js-client-resources-loader.hpp> -#include <malikania/js-image.hpp> -#include <malikania/js-sprite.hpp> -#include <malikania/js-window.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/js_client_resources_loader.hpp> +#include <malikania/js_image.hpp> +#include <malikania/js_sprite.hpp> +#include <malikania/js_window.hpp> +#include <malikania/resources_locator.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; class TestSprite : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; - UniqueContext m_ctx; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; + UniqueContext m_ctx; public: - TestSprite() - : m_locator(SOURCE_DIRECTORY "/resources") - , m_loader(m_locator) - { + TestSprite() + : m_locator(SOURCE_DIRECTORY "/resources") + , m_loader(m_locator) + { duk_push_object(m_ctx); duk_put_global_string(m_ctx, "Malikania"); - dukx_load_image(m_ctx); - dukx_load_sprite(m_ctx); - dukx_load_window(m_ctx); - dukx_put_client_loader(m_ctx, &m_loader); - } + mlk::dukx_load_image(m_ctx); + mlk::dukx_load_sprite(m_ctx); + mlk::dukx_load_window(m_ctx); + dukx_put_client_loader(m_ctx, m_loader); + } }; TEST_F(TestSprite, cell) { - try { - auto ret = duk_peval_string(m_ctx, - "s = new Malikania.Sprite('sprites/margins.json');" - "w = s.cell.width;" - "h = s.cell.height;" - ); + try { + auto ret = duk_peval_string(m_ctx, + "s = new Malikania.Sprite('sprites/margins.json');" + "w = s.cell.width;" + "h = s.cell.height;" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); - ASSERT_EQ(32U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(32U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); duk_get_global_string(m_ctx, "h"); - ASSERT_EQ(32U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(32U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestSprite, columns) { - try { - auto ret = duk_peval_string(m_ctx, - "s = new Malikania.Sprite('sprites/margins.json');" - "n = s.columns;" - ); + try { + auto ret = duk_peval_string(m_ctx, + "s = new Malikania.Sprite('sprites/margins.json');" + "n = s.columns;" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "n"); - ASSERT_EQ(4U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(4U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestSprite, margins) { - try { - auto ret = duk_peval_string(m_ctx, - "s = new Malikania.Sprite('sprites/margins.json');" - "w = s.margins.width;" - "h = s.margins.height;" - ); + try { + auto ret = duk_peval_string(m_ctx, + "s = new Malikania.Sprite('sprites/margins.json');" + "w = s.margins.width;" + "h = s.margins.height;" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); - ASSERT_EQ(4U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(4U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); duk_get_global_string(m_ctx, "h"); - ASSERT_EQ(6U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(6U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestSprite, rows) { - try { - auto ret = duk_peval_string(m_ctx, - "s = new Malikania.Sprite('sprites/margins.json');" - "n = s.rows;" - ); + try { + auto ret = duk_peval_string(m_ctx, + "s = new Malikania.Sprite('sprites/margins.json');" + "n = s.rows;" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "n"); - ASSERT_EQ(3U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(3U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestSprite, space) { - try { - auto ret = duk_peval_string(m_ctx, - "s = new Malikania.Sprite('sprites/margins.json');" - "w = s.space.width;" - "h = s.space.height;" - ); + try { + auto ret = duk_peval_string(m_ctx, + "s = new Malikania.Sprite('sprites/margins.json');" + "w = s.space.width;" + "h = s.space.height;" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "w"); - ASSERT_EQ(2U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(2U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); duk_get_global_string(m_ctx, "h"); - ASSERT_EQ(3U, duk_to_uint(m_ctx, -1)); + ASSERT_EQ(3U, duk_to_uint(m_ctx, -1)); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestSprite, basic) { - try { - auto ret = duk_peval_string(m_ctx, - "w = new Malikania.Window();" - "s = new Malikania.Sprite('sprites/margins.json');" - "c = 0;" - ); + try { + auto ret = duk_peval_string(m_ctx, + "w = new Malikania.Window();" + "s = new Malikania.Sprite('sprites/margins.json');" + "c = 0;" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } - for (unsigned c = 0; c < 12; ++c) { - auto ret = duk_peval_string(m_ctx, - "w.setDrawingColor('lightskyblue');" - "w.clear();" - "s.draw(w, c++, { x: 320 - 16, y: 240 - 16 });" - "w.present();" - ); + for (unsigned c = 0; c < 12; ++c) { + auto ret = duk_peval_string(m_ctx, + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "s.draw(w, c++, { x: 320 - 16, y: 240 - 16 });" + "w.present();" + ); - if (ret != 0) { - throw dukx_exception(m_ctx, -1); - } + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(1s); - } - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + std::this_thread::sleep_for(1s); + } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } int main(int argc, char **argv)
--- a/tests/libclient/js-window/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/js-window/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -21,63 +21,65 @@ #include <gtest/gtest.h> -#include <malikania/js-window.hpp> +#include <malikania/js_window.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; class TestWindow : public testing::Test { protected: - UniqueContext m_ctx; + UniqueContext m_ctx; public: - TestWindow() - { + TestWindow() + { duk_push_object(m_ctx); - duk_put_global_string(m_ctx, "Malikania"); - dukx_load_window(m_ctx); - } + duk_put_global_string(m_ctx, "Malikania"); + mlk::dukx_load_window(m_ctx); + } }; TEST_F(TestWindow, basic) { - try { - auto ret = duk_peval_string(m_ctx, - "w = new Malikania.Window();" - "w.setDrawingColor('lightskyblue');" - "w.clear();" - "w.present();" - ); + try { + auto ret = duk_peval_string(m_ctx, + "w = new Malikania.Window();" + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "w.present();" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(3s); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + std::this_thread::sleep_for(3s); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestWindow, rect) { - try { - auto ret = duk_peval_string(m_ctx, - "w = new Malikania.Window();" - "w.setDrawingColor('lightskyblue');" - "w.clear();" - "w.setDrawingColor('white');" - "w.drawRectangle({ x: 10, y: 10, width: 10, height: 10 });" - "w.present();" - ); + try { + auto ret = duk_peval_string(m_ctx, + "w = new Malikania.Window();" + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "w.setDrawingColor('white');" + "w.drawRectangle({ x: 10, y: 10, width: 10, height: 10 });" + "w.present();" + ); - if (ret != 0) - throw dukx_exception(m_ctx, -1); + if (ret != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(3s); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + std::this_thread::sleep_for(3s); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } int main(int argc, char **argv)
--- a/tests/libclient/line/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/line/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Line + * main.cpp -- test mlk::line * * Copyright (c) 2013-2016 Malikania Authors * @@ -20,11 +20,11 @@ #include <malikania/line.hpp> -using namespace malikania; +namespace mlk = malikania; TEST(Basics, none) { - Line line; + mlk::line line; ASSERT_EQ(0, line.x1()); ASSERT_EQ(0, line.y1()); @@ -34,7 +34,7 @@ TEST(Basics, standard) { - Line line(10, 20, 30, 40); + mlk::line line(10, 20, 30, 40); ASSERT_EQ(10, line.x1()); ASSERT_EQ(20, line.y1()); @@ -44,25 +44,25 @@ TEST(Basics, operatorEq) { - Line line1, line2; + mlk::line line1, line2; ASSERT_EQ(line1, line2); } TEST(Basics, operatorEq1) { - Line line1(10, 20, 30, 40); - Line line2(10, 20, 30, 40); + mlk::line line1(10, 20, 30, 40); + mlk::line line2(10, 20, 30, 40); ASSERT_EQ(line1, line2); } TEST(Basics, operatorNeq) { - ASSERT_NE(Line(10), Line(20)); - ASSERT_NE(Line(10, 10), Line(10, 20)); - ASSERT_NE(Line(10, 10, 10), Line(10, 10, 20)); - ASSERT_NE(Line(10, 10, 10, 10), Line(10, 10, 10, 20)); + ASSERT_NE(mlk::line(10), mlk::line(20)); + ASSERT_NE(mlk::line(10, 10), mlk::line(10, 20)); + ASSERT_NE(mlk::line(10, 10, 10), mlk::line(10, 10, 20)); + ASSERT_NE(mlk::line(10, 10, 10, 10), mlk::line(10, 10, 10, 20)); } int main(int argc, char **argv)
--- a/tests/libclient/point/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/point/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Point + * main.cpp -- test mlk::point * * Copyright (c) 2013-2016 Malikania Authors * @@ -20,11 +20,11 @@ #include <malikania/point.hpp> -using namespace malikania; +namespace mlk = malikania; TEST(Basics, none) { - Point point; + mlk::point point; ASSERT_EQ(0, point.x()); ASSERT_EQ(0, point.y()); @@ -32,7 +32,7 @@ TEST(Basics, standard) { - Point point(10, 20); + mlk::point point(10, 20); ASSERT_EQ(10, point.x()); ASSERT_EQ(20, point.y()); @@ -40,23 +40,23 @@ TEST(Basics, operatorEq) { - Point point1, point2; + mlk::point point1, point2; ASSERT_EQ(point1, point2); } TEST(Basics, operatorEq1) { - Point point1(10, 20); - Point point2(10, 20); + mlk::point point1(10, 20); + mlk::point point2(10, 20); ASSERT_EQ(point1, point2); } TEST(Basics, operatorNeq) { - ASSERT_NE(Point(10), Point(20)); - ASSERT_NE(Point(10, 10), Point(10, 20)); + ASSERT_NE(mlk::point(10), mlk::point(20)); + ASSERT_NE(mlk::point(10, 10), mlk::point(10, 20)); } int main(int argc, char **argv)
--- a/tests/libclient/rectangle/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/rectangle/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Rectangle + * main.cpp -- test mlk::rectangle * * Copyright (c) 2013-2016 Malikania Authors * @@ -20,11 +20,11 @@ #include <malikania/rectangle.hpp> -using namespace malikania; +namespace mlk = malikania; TEST(Basics, none) { - Rectangle rectangle; + mlk::rectangle rectangle; ASSERT_EQ(0, rectangle.x()); ASSERT_EQ(0, rectangle.y()); @@ -34,15 +34,15 @@ TEST(Basics, null) { - ASSERT_TRUE(Rectangle().isNull()); - ASSERT_FALSE(Rectangle(0, 0, 10, 0).isNull()); - ASSERT_FALSE(Rectangle(0, 0, 0, 10).isNull()); - ASSERT_FALSE(Rectangle(0, 0, 10, 10).isNull()); + ASSERT_TRUE(mlk::rectangle().is_null()); + ASSERT_FALSE(mlk::rectangle(0, 0, 10, 0).is_null()); + ASSERT_FALSE(mlk::rectangle(0, 0, 0, 10).is_null()); + ASSERT_FALSE(mlk::rectangle(0, 0, 10, 10).is_null()); } TEST(Basics, standard) { - Rectangle rectangle(10, 20, 30, 40); + mlk::rectangle rectangle(10, 20, 30, 40); ASSERT_EQ(10, rectangle.x()); ASSERT_EQ(20, rectangle.y()); @@ -52,25 +52,25 @@ TEST(Basics, operatorEq) { - Rectangle rectangle1, rectangle2; + mlk::rectangle rectangle1, rectangle2; ASSERT_EQ(rectangle1, rectangle2); } TEST(Basics, operatorEq1) { - Rectangle rectangle1(10, 20, 30, 40); - Rectangle rectangle2(10, 20, 30, 40); + mlk::rectangle rectangle1(10, 20, 30, 40); + mlk::rectangle rectangle2(10, 20, 30, 40); ASSERT_EQ(rectangle1, rectangle2); } TEST(Basics, operatorNeq) { - ASSERT_NE(Rectangle(10), Rectangle(20)); - ASSERT_NE(Rectangle(10, 10), Rectangle(10, 20)); - ASSERT_NE(Rectangle(10, 10, 10), Rectangle(10, 10, 20)); - ASSERT_NE(Rectangle(10, 10, 10, 10), Rectangle(10, 10, 10, 20)); + ASSERT_NE(mlk::rectangle(10), mlk::rectangle(20)); + ASSERT_NE(mlk::rectangle(10, 10), mlk::rectangle(10, 20)); + ASSERT_NE(mlk::rectangle(10, 10, 10), mlk::rectangle(10, 10, 20)); + ASSERT_NE(mlk::rectangle(10, 10, 10, 10), mlk::rectangle(10, 10, 10, 20)); } int main(int argc, char **argv)
--- a/tests/libclient/size/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/size/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test Size + * main.cpp -- test mlk::size * * Copyright (c) 2013-2016 Malikania Authors * @@ -20,11 +20,11 @@ #include <malikania/size.hpp> -using namespace malikania; +namespace mlk = malikania; TEST(Basics, none) { - Size size; + mlk::size size; ASSERT_EQ(0U, size.width()); ASSERT_EQ(0U, size.height()); @@ -32,14 +32,14 @@ TEST(Basics, null) { - ASSERT_TRUE(Size().isNull()); - ASSERT_FALSE(Size(0, 10).isNull()); - ASSERT_FALSE(Size(10, 0).isNull()); + ASSERT_TRUE(mlk::size().is_null()); + ASSERT_FALSE(mlk::size(0, 10).is_null()); + ASSERT_FALSE(mlk::size(10, 0).is_null()); } TEST(Basics, standard) { - Size size(10, 20); + mlk::size size(10, 20); ASSERT_EQ(10U, size.width()); ASSERT_EQ(20U, size.height()); @@ -47,23 +47,23 @@ TEST(Basics, operatorEq) { - Size size1, size2; + mlk::size size1, size2; ASSERT_EQ(size1, size2); } TEST(Basics, operatorEq1) { - Size size1(10, 20); - Size size2(10, 20); + mlk::size size1(10, 20); + mlk::size size2(10, 20); ASSERT_EQ(size1, size2); } TEST(Basics, operatorNeq) { - ASSERT_NE(Size(10), Size(20)); - ASSERT_NE(Size(10, 10), Size(10, 20)); + ASSERT_NE(mlk::size(10), mlk::size(20)); + ASSERT_NE(mlk::size(10, 10), mlk::size(10, 20)); } int main(int argc, char **argv)
--- a/tests/libclient/sprite/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libclient/sprite/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -22,25 +22,25 @@ #include <gtest/gtest.h> -#include <malikania/client-resources-loader.hpp> -#include <malikania/resources-locator.hpp> +#include <malikania/client_resources_loader.hpp> +#include <malikania/resources_locator.hpp> #include <malikania/sprite.hpp> #include <malikania/window.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; namespace { -Window window(400, 400); +mlk::window window(400, 400); } // !namespace class TestSprite : public testing::Test { protected: - ResourcesLocatorDirectory m_locator; - ClientResourcesLoader m_loader; + mlk::directory_resources_locator m_locator; + mlk::client_resources_loader m_loader; public: TestSprite() @@ -58,7 +58,7 @@ TEST_F(TestSprite, missingPropertyImage) { try { - m_loader.loadSprite("sprites/no-property-image.json"); + m_loader.load_sprite("sprites/no-property-image.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -68,7 +68,7 @@ TEST_F(TestSprite, missingPropertyCell) { try { - m_loader.loadSprite("sprites/no-property-cell.json"); + m_loader.load_sprite("sprites/no-property-cell.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -83,7 +83,7 @@ TEST_F(TestSprite, imageNotString) { try { - m_loader.loadSprite("sprites/property-image-not-string.json"); + m_loader.load_sprite("sprites/property-image-not-string.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -93,7 +93,7 @@ TEST_F(TestSprite, cellNotArray) { try { - m_loader.loadSprite("sprites/property-cell-not-array.json"); + m_loader.load_sprite("sprites/property-cell-not-array.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -103,7 +103,7 @@ TEST_F(TestSprite, cellNotArray2) { try { - m_loader.loadSprite("sprites/property-cell-not-array2.json"); + m_loader.load_sprite("sprites/property-cell-not-array2.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -118,7 +118,7 @@ TEST_F(TestSprite, imageNotFound) { try { - m_loader.loadSprite("sprites/image-not-found.json"); + m_loader.load_sprite("sprites/image-not-found.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -128,7 +128,7 @@ TEST_F(TestSprite, notObject) { try { - m_loader.loadSprite("sprites/not-object.json"); + m_loader.load_sprite("sprites/not-object.json"); FAIL() << "exception expected"; } catch (const std::exception &) { @@ -143,7 +143,7 @@ TEST_F(TestSprite, standard) { try { - Sprite sprite = m_loader.loadSprite("sprites/simple.json"); + auto sprite = m_loader.load_sprite("sprites/simple.json"); ASSERT_EQ(300U, sprite.cell().width()); ASSERT_EQ(300U, sprite.cell().height()); @@ -155,7 +155,7 @@ TEST_F(TestSprite, margins) { try { - Sprite sprite = m_loader.loadSprite("sprites/margins.json"); + auto sprite = m_loader.load_sprite("sprites/margins.json"); ASSERT_EQ(3U, sprite.rows()); ASSERT_EQ(4U, sprite.columns()); @@ -167,16 +167,15 @@ TEST_F(TestSprite, draw) { try { - Sprite sprite = m_loader.loadSprite("sprites/margins.json"); + auto sprite = m_loader.load_sprite("sprites/margins.json"); - unsigned total = sprite.rows() * sprite.columns(); - + auto total = sprite.rows() * sprite.columns(); auto x = (400 / 2) - (sprite.cell().width() / 2); auto y = (400 / 2) - (sprite.cell().height() / 2); for (unsigned c = 0; c < total; ++c) { window.clear(); - sprite.draw(window, c, Point(x, y)); + sprite.draw(window, c, mlk::point(x, y)); window.present(); std::this_thread::sleep_for(1s);
--- a/tests/libcommon/js-elapsed-timer/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libcommon/js-elapsed-timer/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -20,9 +20,9 @@ #include <thread> -#include <malikania/js-elapsed-timer.hpp> +#include <malikania/js_elapsed_timer.hpp> -using namespace malikania; +namespace mlk = malikania; using namespace std::chrono_literals; @@ -33,119 +33,131 @@ class TestElapsedTimer : public testing::Test { protected: - UniqueContext m_ctx; + UniqueContext m_ctx; - TestElapsedTimer() - { + TestElapsedTimer() + { duk_push_object(m_ctx); duk_put_global_string(m_ctx, "Malikania"); - dukx_load_elapsedtimer(m_ctx); - } + mlk::dukx_load_elapsedtimer(m_ctx); + } - inline void assertRange(int value, int expected) const noexcept - { - if (value < (expected - margin) || value > (expected + margin)) - FAIL() << value << " is bigger than [" << (expected - margin) << ", " << (expected + margin) << "]"; - } + inline void assertRange(int value, int expected) const noexcept + { + if (value < (expected - margin) || value > (expected + margin)) { + FAIL() << value << " is bigger than [" << (expected - margin) << ", " << (expected + margin) << "]"; + } + } }; TEST_F(TestElapsedTimer, standard) { - try { - if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) - throw dukx_exception(m_ctx, -1); + try { + if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(300ms); + std::this_thread::sleep_for(300ms); - if (duk_peval_string(m_ctx, "result = timer.elapsed();") != 0) - throw dukx_exception(m_ctx, -1); + if (duk_peval_string(m_ctx, "result = timer.elapsed();") != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "result"); - assertRange(duk_to_int(m_ctx, -1), 300); + assertRange(duk_to_int(m_ctx, -1), 300); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestElapsedTimer, reset) { - try { - if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) - throw dukx_exception(m_ctx, -1); + try { + if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(300ms); + std::this_thread::sleep_for(300ms); - if (duk_peval_string(m_ctx, "timer.reset(); result = timer.elapsed();") != 0) - throw dukx_exception(m_ctx, -1); + if (duk_peval_string(m_ctx, "timer.reset(); result = timer.elapsed();") != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "result"); - assertRange(duk_to_int(m_ctx, -1), 0); + assertRange(duk_to_int(m_ctx, -1), 0); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestElapsedTimer, pause) { - try { - if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) - throw dukx_exception(m_ctx, -1); + try { + if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) { + throw dukx_exception(m_ctx, -1); + } + + /* + * Simulate a pause in the game like this: + * + * start pause restart elapsed + * | 10ms |.5ms.| 6ms | + * + * Since the game was paused, the 5ms must not be totalized. + */ + std::this_thread::sleep_for(10ms); - /* - * Simulate a pause in the game like this: - * - * start pause restart elapsed - * | 10ms |.5ms.| 6ms | - * - * Since the game was paused, the 5ms must not be totalized. - */ - std::this_thread::sleep_for(10ms); + if (duk_peval_string(m_ctx, "timer.pause();") != 0) { + throw dukx_exception(m_ctx, -1); + } + + std::this_thread::sleep_for(5ms); - if (duk_peval_string(m_ctx, "timer.pause();") != 0) - throw dukx_exception(m_ctx, -1); - - std::this_thread::sleep_for(5ms); + if (duk_peval_string(m_ctx, "timer.restart();") != 0) { + throw dukx_exception(m_ctx, -1); + } - if (duk_peval_string(m_ctx, "timer.restart();") != 0) - throw dukx_exception(m_ctx, -1); + std::this_thread::sleep_for(6ms); - std::this_thread::sleep_for(6ms); - - if (duk_peval_string(m_ctx, "result = timer.elapsed()") != 0) - throw dukx_exception(m_ctx, -1); + if (duk_peval_string(m_ctx, "result = timer.elapsed()") != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "result"); - assertRange(duk_to_int(m_ctx, -1), 16); + assertRange(duk_to_int(m_ctx, -1), 16); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } TEST_F(TestElapsedTimer, doublecheck) { - try { - if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) - throw dukx_exception(m_ctx, -1); + try { + if (duk_peval_string(m_ctx, "timer = new Malikania.ElapsedTimer();") != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(50ms); + std::this_thread::sleep_for(50ms); - if (duk_peval_string(m_ctx, "result = timer.elapsed()") != 0) - throw dukx_exception(m_ctx, -1); + if (duk_peval_string(m_ctx, "result = timer.elapsed()") != 0) { + throw dukx_exception(m_ctx, -1); + } - std::this_thread::sleep_for(50ms); + std::this_thread::sleep_for(50ms); - if (duk_peval_string(m_ctx, "result = timer.elapsed()") != 0) - throw dukx_exception(m_ctx, -1); + if (duk_peval_string(m_ctx, "result = timer.elapsed()") != 0) { + throw dukx_exception(m_ctx, -1); + } duk_get_global_string(m_ctx, "result"); - assertRange(duk_to_int(m_ctx, -1), 100); + assertRange(duk_to_int(m_ctx, -1), 100); duk_pop(m_ctx); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } } int main(int argc, char **argv)
--- a/tests/libserver/dao-account/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libserver/dao-account/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -23,10 +23,10 @@ #include <sysconfig-tests.h> #include <malikania/account.hpp> -#include <malikania/dao-account.hpp> +#include <malikania/account_dao.hpp> #include <malikania/database.hpp> -using namespace malikania; +namespace mlk = malikania; #include "test-sqlite.hpp"
--- a/tests/libserver/dao-account/test.hpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libserver/dao-account/test.hpp Tue Nov 29 21:21:36 2016 +0100 @@ -1,7 +1,7 @@ class @TEST_CLASS_NAME@ : public testing::Test { protected: - Database m_database; - AccountDao m_dao; + mlk::database m_database; + mlk::account_dao m_dao; std::string kind() { @@ -46,13 +46,13 @@ TEST_F(@TEST_CLASS_NAME@, create) { try { - Account ac; + mlk::account ac; - ac.setName("jean"); - ac.setEmail("jean@christophe.fr"); - ac.setFirstName("Jean"); - ac.setLastName("Christophe"); - ac.setPassword("raw"); + ac.name = "jean"; + ac.email = "jean@christophe.fr"; + ac.first_name = "Jean"; + ac.last_name = "Christophe"; + ac.password = "raw"; m_dao.create(ac); @@ -66,26 +66,26 @@ TEST_F(@TEST_CLASS_NAME@, update) { try { - Account ac; + mlk::account ac; - ac.setName("jean"); - ac.setEmail("jean@christophe.fr"); - ac.setFirstName("Jean"); - ac.setLastName("Christophe"); - ac.setPassword("raw"); + ac.name = "jean"; + ac.email = "jean@christophe.fr"; + ac.first_name = "Jean"; + ac.last_name = "Christophe"; + ac.password = "raw"; m_dao.create(ac); - ac.setEmail("benoit@christophe.fr"); - ac.setFirstName("Benoit"); + ac.email = "benoit@christophe.fr"; + ac.first_name = "Benoit"; m_dao.update(ac); - Account ac2 = m_dao.get(ac.id()); + mlk::account ac2 = m_dao.get(ac.id); - ASSERT_EQ("jean", ac2.name()); - ASSERT_EQ("benoit@christophe.fr", ac2.email()); - ASSERT_EQ("Benoit", ac2.firstName()); + ASSERT_EQ("jean", ac2.name); + ASSERT_EQ("benoit@christophe.fr", ac2.email); + ASSERT_EQ("Benoit", ac2.first_name); } catch (const std::exception &ex) { FAIL() << ex.what(); }
--- a/tests/libserver/id/main.cpp Sun Nov 27 20:50:38 2016 +0100 +++ b/tests/libserver/id/main.cpp Tue Nov 29 21:21:36 2016 +0100 @@ -25,64 +25,55 @@ using namespace malikania; -/* -------------------------------------------------------- - * Basic use case - * -------------------------------------------------------- */ +/* + * Basic use case. + * ------------------------------------------------------------------ + */ -class TestId : public testing::Test { +class test_id : public testing::Test { protected: - IdGen<unsigned> m_idgen; - -public: - ~TestId() - { - m_idgen.reset(); - } + id_generator<unsigned> m_idgen; }; -TEST_F(TestId, simple) +TEST_F(test_id, simple) { - ASSERT_EQ(0U, m_idgen.next()); - ASSERT_EQ(1U, m_idgen.next()); - ASSERT_EQ(2U, m_idgen.next()); - ASSERT_EQ(3U, m_idgen.next()); - ASSERT_EQ(4U, m_idgen.next()); + auto i0 = m_idgen.next(); + auto i1 = m_idgen.next(); + auto i2 = m_idgen.next(); + + ASSERT_EQ(0U, i0->value()); + ASSERT_EQ(1U, i1->value()); + ASSERT_EQ(2U, i2->value()); } -TEST_F(TestId, reset) +TEST_F(test_id, release1) { - m_idgen.next(); - m_idgen.next(); - m_idgen.next(); - - m_idgen.reset(); + auto i0 = m_idgen.next(); // 0 + auto i1 = m_idgen.next(); // 1 + auto i2 = m_idgen.next(); // 2 - ASSERT_EQ(0U, m_idgen.next()); -} + i1 = nullptr; -TEST_F(TestId, release1) -{ - m_idgen.next(); // 0 - m_idgen.next(); // 1 - m_idgen.next(); // 2 - m_idgen.release(1); + auto n1 = m_idgen.next(); + auto n2 = m_idgen.next(); /* * 0 and 2 are currently in use. * * The next id must be 1 and then 3. */ - ASSERT_EQ(1U, m_idgen.next()); - ASSERT_EQ(3U, m_idgen.next()); + ASSERT_EQ(1U, n1->value()); + ASSERT_EQ(3U, n2->value()); } -TEST_F(TestId, release2) +TEST_F(test_id, release2) { - m_idgen.next(); // 0 - m_idgen.next(); // 1 - m_idgen.next(); // 2 - m_idgen.release(1); - m_idgen.release(0); + auto i0 = m_idgen.next(); // 0 + auto i1 = m_idgen.next(); // 1 + auto i2 = m_idgen.next(); // 2 + + i1 = nullptr; + i0 = nullptr; /* * Only 2 is in use, next id must be: @@ -91,76 +82,50 @@ * - 0 * - 3 */ - ASSERT_EQ(1U, m_idgen.next()); - ASSERT_EQ(0U, m_idgen.next()); - ASSERT_EQ(3U, m_idgen.next()); -} + auto n1 = m_idgen.next(); + auto n2 = m_idgen.next(); + auto n3 = m_idgen.next(); -/* -------------------------------------------------------- - * Id RAII class - * -------------------------------------------------------- */ - -TEST(IdLocker, basic) -{ - IdGen<int8_t> gen; - Id<int8_t> id(gen); - - ASSERT_EQ(0, id); + ASSERT_EQ(1U, n1->value()); + ASSERT_EQ(0U, n2->value()); + ASSERT_EQ(3U, n3->value()); } -TEST(IdLocker, two) -{ - IdGen<int8_t> gen; - Id<int8_t> id(gen); - Id<int8_t> id2(gen); - - ASSERT_EQ(0, id); - ASSERT_EQ(1, id2); -} - -TEST(IdLocker, already) -{ - IdGen<int8_t> gen; - Id<int8_t> id(gen, gen.next()); - - ASSERT_EQ(0, id); -} - -/* -------------------------------------------------------- - * Limit test - * -------------------------------------------------------- */ +/* + * Limit test. + * ------------------------------------------------------------------ + */ TEST(Limits, max) { - IdGen<int8_t> idgen; - int8_t last; + id_generator<std::int8_t> idgen; + std::vector<std::unique_ptr<id<std::int8_t>>> ids; try { for (int i = 0; i < 127; ++i) { - last = idgen.next(); + ids.push_back(idgen.next()); } } catch (const std::exception &ex) { FAIL() << ex.what(); } - ASSERT_EQ(126, last); + ASSERT_EQ(127U, ids.size()); + ASSERT_EQ(126, ids[126]->value()); } TEST(Limits, fail) { - IdGen<int8_t> idgen; - int8_t last; + id_generator<std::int8_t> idgen; + std::vector<std::unique_ptr<id<std::int8_t>>> ids; - try { + ASSERT_ANY_THROW( for (int i = 0; i < 200; ++i) { - last = idgen.next(); + ids.push_back(idgen.next()); } + ); - FAIL() << "Exception expected"; - } catch (const std::exception &ex) { - } - - ASSERT_EQ(126, last); + ASSERT_EQ(127U, ids.size()); + ASSERT_EQ(126, ids[126]->value()); } int main(int argc, char **argv)