Mercurial > malikania
view client/main.cpp @ 26:56cc058200b5
Client: add basic mlk-client code with an example, #472
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 08 Apr 2016 14:16:47 +0200 |
parents | e33b246ac2d3 |
children | 0a1adf7dcca0 |
line wrap: on
line source
/* * main.cpp -- main client file * * 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 <chrono> #include <iostream> #include <thread> #include <malikania/client-resources-loader.h> #include <malikania/resources-locator.h> #include <malikania/js-animation.h> #include <malikania/js-animator.h> #include <malikania/js-color.h> #include <malikania/js-font.h> #include <malikania/js-image.h> #include <malikania/js-line.h> #include <malikania/js-point.h> #include <malikania/js-rectangle.h> #include <malikania/js-size.h> #include <malikania/js-sprite.h> #include <malikania/js-window.h> using namespace malikania; namespace { int usage() { std::cerr << "usage: mlk-client directory\n"; return 1; } duk::Context init() { 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); return ctx; } void start(duk::Context &ctx) { duk::getGlobal<void>(ctx, "start"); if (duk::is<duk::Function>(ctx, -1)) { duk::getGlobal<void>(ctx, "\xff""\xff""window"); duk::pcall(ctx, 1); duk::pop(ctx); } else { duk::pop(ctx); } } void update(duk::Context &ctx) { duk::getGlobal<void>(ctx, "update"); if (duk::is<duk::Function>(ctx, -1)) { duk::pcall(ctx, 0); duk::pop(ctx); } else { duk::pop(ctx); } } void draw(duk::Context &ctx) { duk::getGlobal<void>(ctx, "draw"); if (duk::is<duk::Function>(ctx, -1)) { duk::getGlobal<void>(ctx, "\xff""\xff""window"); duk::pcall(ctx, 1); duk::pop(ctx); } else { duk::pop(ctx); } } int run(duk::Context &ctx) { bool running = true; /* js-window use duk::Pointer at the moment so store it from there temporarily */ duk::putGlobal(ctx, "\xff""\xff""window", duk::Pointer<Window>{new Window}); Window *window = duk::getGlobal<duk::Pointer<Window>>(ctx, "\xff""\xff""window"); window->setOnQuit([&] () { running = false; }); window->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); } }); window->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); while (running) { window->poll(); update(ctx); draw(ctx); // 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", duk::RawPointer<ClientResourcesLoader>{&loader}); if (duk::pevalFile(ctx, path) != 0) { duk::ErrorInfo info = duk::error(ctx, -1); std::cerr << info.fileName << ":" << info.lineNumber << ": " << info.stack << std::endl; return 1; } return run(ctx); } } // !namespace int main(int argc, char **argv) { -- argc; ++ argv; if (argc < 1) { return usage(); } return boot(argv[0]); }