view client/main.cpp @ 41:3645200f46bf

Misc: switch to Boost.Timer, closes #586
author David Demelier <markand@malikania.fr>
date Sun, 27 Nov 2016 20:50:38 +0100
parents 9af360f34c7d
children a47a4477f347
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.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()
{
    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() {}