Mercurial > malikania
diff 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 diff
--- a/client/main.cpp Wed Apr 06 13:33:30 2016 +0200 +++ b/client/main.cpp Fri Apr 08 14:16:47 2016 +0200 @@ -1,7 +1,7 @@ /* - * main.cpp -- main client files + * main.cpp -- main client file * - * Copyright (c) 2014 David Demelier <markand@malikania.fr> + * 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 @@ -16,225 +16,178 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if 0 - +#include <chrono> #include <iostream> -#include <chrono> #include <thread> -#include <map> -#include <malikania/Json.h> -#include <malikania/Window.h> -#include <malikania/Size.h> -#include <malikania/Sprite.h> -#include <malikania/Image.h> -#include <malikania/Point.h> -#include <malikania/Label.h> -#include <malikania/Animation.h> -#include <malikania/Animator.h> + +#include <malikania/client-resources-loader.h> +#include <malikania/resources-locator.h> -using namespace std::literals::chrono_literals; +#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> -// TODO delete this... just for fun -bool goRight = true; -bool goDown = true; -const int mokoSize = 300; +using namespace malikania; + +namespace { + +int usage() +{ + std::cerr << "usage: mlk-client directory\n"; + + return 1; +} -void bounce(malikania::Window& window, int &x, int &y) { - malikania::Size resolution = window.getWindowResolution(); - int width = resolution.width; - int height = resolution.height; - if (y < 10) { - goDown = true; - y += 1; - } - if (goDown && y < height - mokoSize) { - // Moko falls - y += 0.2 * y; +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 { - // Moko will bounce!!! - goDown = false; - } - if (!goDown && y > 0) { - y -= 0.1 * y; - } else { - goDown = true; - } - - if (goRight && x < width - mokoSize) { - x += 4; - } else { - goRight = false; - } - if (!goRight && x > 0) { - x -= 4; - } else { - goRight = true; + duk::pop(ctx); } } -// End TODO +void update(duk::Context &ctx) +{ + duk::getGlobal<void>(ctx, "update"); -int main(void) -{ - malikania::Window mainWindow; + if (duk::is<duk::Function>(ctx, -1)) { + duk::pcall(ctx, 0); + duk::pop(ctx); + } else { + duk::pop(ctx); + } +} - bool isBouncing = false; +void draw(duk::Context &ctx) +{ + duk::getGlobal<void>(ctx, "draw"); - int mokoPositionX = 0; - int mokoPositionY = 0; + 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); + } +} - std::map<int, bool> keyPressed = { {SDLK_UP, false}, {SDLK_DOWN, false}, {SDLK_RIGHT, false}, {SDLK_LEFT, false} }; +int run(duk::Context &ctx) +{ + bool running = true; - mainWindow.setOnKeyDown([&mainWindow, &mokoPositionX, &mokoPositionY, &isBouncing, &keyPressed](int sdlKey) { - switch (sdlKey) { - case SDLK_ESCAPE: - mainWindow.close(); - break; - case SDLK_UP: - keyPressed[SDLK_UP] = true; - break; - case SDLK_DOWN: - keyPressed[SDLK_DOWN] = true; - break; - case SDLK_RIGHT: - keyPressed[SDLK_RIGHT] = true; - break; - case SDLK_LEFT: - keyPressed[SDLK_LEFT] = true; - break; - case SDLK_m: - isBouncing = !isBouncing; - break; + /* 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); } }); - mainWindow.setOnKeyUp([&keyPressed](int sdlKey) { - switch (sdlKey) { - case SDLK_UP: - keyPressed[SDLK_UP] = false; - break; - case SDLK_DOWN: - keyPressed[SDLK_DOWN] = false; - break; - case SDLK_RIGHT: - keyPressed[SDLK_RIGHT] = false; - break; - case SDLK_LEFT: - keyPressed[SDLK_LEFT] = false; - break; - } - }); + start(ctx); - int animationStep = 1; - mainWindow.setOnRefresh([&mainWindow, &keyPressed, &animationStep](){ - if (keyPressed[SDLK_LEFT]) { - std::string animationState = "left" + std::to_string(animationStep > 4 ? 4 : animationStep++); - } else if (keyPressed[SDLK_RIGHT]) { - std::string animationState = "right" + std::to_string(animationStep > 4 ? 4 : animationStep++); - } else if (keyPressed[SDLK_DOWN]) { - std::string animationState = "down" + std::to_string(animationStep > 4 ? 4 : animationStep++); - } else { - animationStep = 1; - } - }); - - malikania::Sprite testSprite = malikania::Sprite::fromJson(mainWindow, malikania::JsonDocument( - "{\"image\": \"resources/images/mokodemo.png\", \"alias\": \"testSprite\", \"cell\": [300, 300], \"size\": [1200, 900]}" - ).toObject()); - - std::shared_ptr<malikania::Font> font = std::make_shared<malikania::Font>("resources/fonts/DejaVuSans.ttf", 48); - malikania::Label testLabel("Malikania !!! Youpi !", font, {0, 0, 100, 50}); - - std::shared_ptr<malikania::Animation> testAnimation = std::make_shared<malikania::Animation>(malikania::Animation::fromJson(mainWindow, malikania::JsonDocument( - std::string("{\"sprite\": \"no-working-yet.json\", \"alias\": \"testAnimation\", \"frames\": [") - + "{ \"delay\": 200, \"cell\": 0 }, { \"delay\": 10, \"cell\": 1 }," - + "{ \"delay\": 10, \"cell\": 2 }, { \"delay\": 200, \"cell\": 3 }," - + "{ \"delay\": 10, \"cell\": 1 }, { \"delay\": 10, \"cell\": 1 }," - + "{ \"delay\": 200, \"cell\": 4 }, { \"delay\": 10, \"cell\": 5 }," - + "{ \"delay\": 10, \"cell\": 6 }, { \"delay\": 200, \"cell\": 7 }," - + "{ \"delay\": 10, \"cell\": 6 }, { \"delay\": 10, \"cell\": 5 }," - + "{ \"delay\": 200, \"cell\": 8 }, { \"delay\": 10, \"cell\": 9 }," - + "{ \"delay\": 10, \"cell\": 10 }, { \"delay\": 200, \"cell\": 11 }," - + "{ \"delay\": 10, \"cell\": 10 }, { \"delay\": 10, \"cell\": 9 }" - + "]}" - ).toObject())); - - std::shared_ptr<malikania::Animation> testAnimation2 = std::make_shared<malikania::Animation>(malikania::Animation::fromJson(mainWindow, malikania::JsonDocument( - std::string("{\"sprite\": \"no-working-yet.json\", \"alias\": \"testAnimation\", \"frames\": [") - + "{ \"delay\": 2000, \"cell\": 0 }, { \"delay\": 10, \"cell\": 1 }," - + "{ \"delay\": 10, \"cell\": 2 }, { \"delay\": 2000, \"cell\": 3 }," - + "{ \"delay\": 10, \"cell\": 1 }, { \"delay\": 10, \"cell\": 1 }" - + "]}" - ).toObject())); + while (running) { + window->poll(); - malikania::Animator testAnimator1 = malikania::Animator(testAnimation); - malikania::Animator testAnimator2 = malikania::Animator(std::move(testAnimation)); - malikania::Animator testAnimator3 = malikania::Animator(std::move(testAnimation2)); - - while (mainWindow.isOpen()) { - - // TODO delete this, just for fun... - if (isBouncing) { - bounce(mainWindow, mokoPositionX, mokoPositionY); - } - - mainWindow.processEvent(); - mainWindow.setDrawingColor({255, 255, 255, 255}); - mainWindow.clear(); - mainWindow.update(); - - testSprite.draw(mainWindow, 0, {0, 0, 300, 300}); - testSprite.draw(mainWindow, 1, {200, 200, 300, 300}); - testSprite.draw(mainWindow, 2, {400, 400, 300, 300}); - testSprite.draw(mainWindow, 11, {600, 400, 300, 300}); - - malikania::Color c{255, 50, 40, 255}; - mainWindow.setDrawingColor(c); - mainWindow.drawLine({0, 0, 300, 300}); - - std::vector<malikania::Point> points{{20, 20}, {30, 50}, {100, 200}, {30, 60}, {20, 300}, {100, 20}}; - mainWindow.drawLines(points); + update(ctx); + draw(ctx); - mainWindow.setDrawingColor({200, 50, 200, 255}); - mainWindow.drawPoint({400, 400}); - mainWindow.drawPoint({400, 402}); - mainWindow.drawPoint({400, 405}); - mainWindow.drawPoint({400, 407}); - mainWindow.drawPoint({400, 410}); - - mainWindow.setDrawingColor({0, 0, 0, 255}); - mainWindow.drawPoints(points); - - mainWindow.setDrawingColor({30, 30, 30, 255}); - mainWindow.drawRectangle({500, 500, 200, 100}); - - mainWindow.setDrawingColor({130, 30, 30, 255}); - mainWindow.drawRectangles({{800, 800, 200, 100}, {700, 700, 200, 100}, {750, 750, 200, 100}}); - - mainWindow.drawRectangle({600, 200, 200, 100}, true, {0, 255, 0, 255}); - - mainWindow.drawRectangles( - {{800, 400, 200, 100}, {700, 450, 200, 100}, {750, 500, 200, 100}}, - true, - {{255,0,0,255},{0,255,0,255},{0,0,255,255}} - ); - - testLabel.draw(mainWindow, {300, 300, 200, 50}); - - testAnimator1.draw(mainWindow, {1000, 0, 300, 300}); - testAnimator2.draw(mainWindow, {100, 600, 300, 300}); - testAnimator3.draw(mainWindow, {400, 600, 300, 300}); - - mainWindow.present(); - - std::this_thread::sleep_for(5ms); + // TODO: remove this with an appropriate FPS calculation. + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } - //malikania::Window::quit(); - return 0; } -#endif +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; -int main() { return 0; } + return 1; + } + + return run(ctx); +} + +} // !namespace + +int main(int argc, char **argv) +{ + -- argc; + ++ argv; + + if (argc < 1) { + return usage(); + } + + return boot(argv[0]); +}