comparison 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
comparison
equal deleted inserted replaced
25:dc47ce56ce36 26:56cc058200b5
1 /* 1 /*
2 * main.cpp -- main client files 2 * main.cpp -- main client file
3 * 3 *
4 * Copyright (c) 2014 David Demelier <markand@malikania.fr> 4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
5 * 5 *
6 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies. 8 * copyright notice and this permission notice appear in all copies.
9 * 9 *
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19 #if 0 19 #include <chrono>
20 #include <iostream>
21 #include <thread>
20 22
21 #include <iostream> 23 #include <malikania/client-resources-loader.h>
22 #include <chrono> 24 #include <malikania/resources-locator.h>
23 #include <thread>
24 #include <map>
25 #include <malikania/Json.h>
26 #include <malikania/Window.h>
27 #include <malikania/Size.h>
28 #include <malikania/Sprite.h>
29 #include <malikania/Image.h>
30 #include <malikania/Point.h>
31 #include <malikania/Label.h>
32 #include <malikania/Animation.h>
33 #include <malikania/Animator.h>
34 25
35 using namespace std::literals::chrono_literals; 26 #include <malikania/js-animation.h>
27 #include <malikania/js-animator.h>
28 #include <malikania/js-color.h>
29 #include <malikania/js-font.h>
30 #include <malikania/js-image.h>
31 #include <malikania/js-line.h>
32 #include <malikania/js-point.h>
33 #include <malikania/js-rectangle.h>
34 #include <malikania/js-size.h>
35 #include <malikania/js-sprite.h>
36 #include <malikania/js-window.h>
36 37
37 // TODO delete this... just for fun 38 using namespace malikania;
38 bool goRight = true;
39 bool goDown = true;
40 const int mokoSize = 300;
41 39
42 void bounce(malikania::Window& window, int &x, int &y) { 40 namespace {
43 malikania::Size resolution = window.getWindowResolution(); 41
44 int width = resolution.width; 42 int usage()
45 int height = resolution.height; 43 {
46 if (y < 10) { 44 std::cerr << "usage: mlk-client directory\n";
47 goDown = true; 45
48 y += 1; 46 return 1;
49 } 47 }
50 if (goDown && y < height - mokoSize) { 48
51 // Moko falls 49 duk::Context init()
52 y += 0.2 * y; 50 {
51 duk::Context ctx;
52
53 /* TODO: Put Malikania global somewhere else */
54 duk::putGlobal(ctx, "Malikania", duk::Object());
55
56 loadMalikaniaAnimation(ctx);
57 loadMalikaniaAnimator(ctx);
58 loadMalikaniaColor(ctx);
59 loadMalikaniaFont(ctx);
60 loadMalikaniaImage(ctx);
61 loadMalikaniaLine(ctx);
62 loadMalikaniaPoint(ctx);
63 loadMalikaniaRectangle(ctx);
64 loadMalikaniaSize(ctx);
65 loadMalikaniaSprite(ctx);
66 loadMalikaniaWindow(ctx);
67
68 return ctx;
69 }
70
71 void start(duk::Context &ctx)
72 {
73 duk::getGlobal<void>(ctx, "start");
74
75 if (duk::is<duk::Function>(ctx, -1)) {
76 duk::getGlobal<void>(ctx, "\xff""\xff""window");
77 duk::pcall(ctx, 1);
78 duk::pop(ctx);
53 } else { 79 } else {
54 // Moko will bounce!!! 80 duk::pop(ctx);
55 goDown = false;
56 }
57 if (!goDown && y > 0) {
58 y -= 0.1 * y;
59 } else {
60 goDown = true;
61 }
62
63 if (goRight && x < width - mokoSize) {
64 x += 4;
65 } else {
66 goRight = false;
67 }
68 if (!goRight && x > 0) {
69 x -= 4;
70 } else {
71 goRight = true;
72 } 81 }
73 } 82 }
74 83
75 // End TODO 84 void update(duk::Context &ctx)
85 {
86 duk::getGlobal<void>(ctx, "update");
76 87
77 int main(void) 88 if (duk::is<duk::Function>(ctx, -1)) {
89 duk::pcall(ctx, 0);
90 duk::pop(ctx);
91 } else {
92 duk::pop(ctx);
93 }
94 }
95
96 void draw(duk::Context &ctx)
78 { 97 {
79 malikania::Window mainWindow; 98 duk::getGlobal<void>(ctx, "draw");
80 99
81 bool isBouncing = false; 100 if (duk::is<duk::Function>(ctx, -1)) {
101 duk::getGlobal<void>(ctx, "\xff""\xff""window");
102 duk::pcall(ctx, 1);
103 duk::pop(ctx);
104 } else {
105 duk::pop(ctx);
106 }
107 }
82 108
83 int mokoPositionX = 0; 109 int run(duk::Context &ctx)
84 int mokoPositionY = 0; 110 {
111 bool running = true;
85 112
86 std::map<int, bool> keyPressed = { {SDLK_UP, false}, {SDLK_DOWN, false}, {SDLK_RIGHT, false}, {SDLK_LEFT, false} }; 113 /* js-window use duk::Pointer at the moment so store it from there temporarily */
114 duk::putGlobal(ctx, "\xff""\xff""window", duk::Pointer<Window>{new Window});
87 115
88 mainWindow.setOnKeyDown([&mainWindow, &mokoPositionX, &mokoPositionY, &isBouncing, &keyPressed](int sdlKey) { 116 Window *window = duk::getGlobal<duk::Pointer<Window>>(ctx, "\xff""\xff""window");
89 switch (sdlKey) { 117
90 case SDLK_ESCAPE: 118 window->setOnQuit([&] () {
91 mainWindow.close(); 119 running = false;
92 break; 120 });
93 case SDLK_UP: 121 window->setOnKeyDown([&] (unsigned key) {
94 keyPressed[SDLK_UP] = true; 122 duk::getGlobal<void>(ctx, "keyDown");
95 break; 123
96 case SDLK_DOWN: 124 if (duk::is<duk::Function>(ctx, -1)) {
97 keyPressed[SDLK_DOWN] = true; 125 duk::push(ctx, static_cast<int>(key));
98 break; 126 duk::pcall(ctx, 1);
99 case SDLK_RIGHT: 127 duk::pop(ctx);
100 keyPressed[SDLK_RIGHT] = true; 128 } else {
101 break; 129 duk::pop(ctx);
102 case SDLK_LEFT: 130 }
103 keyPressed[SDLK_LEFT] = true; 131 });
104 break; 132 window->setOnKeyDown([&] (unsigned key) {
105 case SDLK_m: 133 duk::getGlobal<void>(ctx, "keyUp");
106 isBouncing = !isBouncing; 134
107 break; 135 if (duk::is<duk::Function>(ctx, -1)) {
136 duk::push(ctx, static_cast<int>(key));
137 duk::pcall(ctx, 1);
138 duk::pop(ctx);
139 } else {
140 duk::pop(ctx);
108 } 141 }
109 }); 142 });
110 143
111 mainWindow.setOnKeyUp([&keyPressed](int sdlKey) { 144 start(ctx);
112 switch (sdlKey) {
113 case SDLK_UP:
114 keyPressed[SDLK_UP] = false;
115 break;
116 case SDLK_DOWN:
117 keyPressed[SDLK_DOWN] = false;
118 break;
119 case SDLK_RIGHT:
120 keyPressed[SDLK_RIGHT] = false;
121 break;
122 case SDLK_LEFT:
123 keyPressed[SDLK_LEFT] = false;
124 break;
125 }
126 });
127 145
128 int animationStep = 1; 146 while (running) {
129 mainWindow.setOnRefresh([&mainWindow, &keyPressed, &animationStep](){ 147 window->poll();
130 if (keyPressed[SDLK_LEFT]) {
131 std::string animationState = "left" + std::to_string(animationStep > 4 ? 4 : animationStep++);
132 } else if (keyPressed[SDLK_RIGHT]) {
133 std::string animationState = "right" + std::to_string(animationStep > 4 ? 4 : animationStep++);
134 } else if (keyPressed[SDLK_DOWN]) {
135 std::string animationState = "down" + std::to_string(animationStep > 4 ? 4 : animationStep++);
136 } else {
137 animationStep = 1;
138 }
139 });
140 148
141 malikania::Sprite testSprite = malikania::Sprite::fromJson(mainWindow, malikania::JsonDocument( 149 update(ctx);
142 "{\"image\": \"resources/images/mokodemo.png\", \"alias\": \"testSprite\", \"cell\": [300, 300], \"size\": [1200, 900]}" 150 draw(ctx);
143 ).toObject());
144 151
145 std::shared_ptr<malikania::Font> font = std::make_shared<malikania::Font>("resources/fonts/DejaVuSans.ttf", 48); 152 // TODO: remove this with an appropriate FPS calculation.
146 malikania::Label testLabel("Malikania !!! Youpi !", font, {0, 0, 100, 50}); 153 std::this_thread::sleep_for(std::chrono::milliseconds(50));
147
148 std::shared_ptr<malikania::Animation> testAnimation = std::make_shared<malikania::Animation>(malikania::Animation::fromJson(mainWindow, malikania::JsonDocument(
149 std::string("{\"sprite\": \"no-working-yet.json\", \"alias\": \"testAnimation\", \"frames\": [")
150 + "{ \"delay\": 200, \"cell\": 0 }, { \"delay\": 10, \"cell\": 1 },"
151 + "{ \"delay\": 10, \"cell\": 2 }, { \"delay\": 200, \"cell\": 3 },"
152 + "{ \"delay\": 10, \"cell\": 1 }, { \"delay\": 10, \"cell\": 1 },"
153 + "{ \"delay\": 200, \"cell\": 4 }, { \"delay\": 10, \"cell\": 5 },"
154 + "{ \"delay\": 10, \"cell\": 6 }, { \"delay\": 200, \"cell\": 7 },"
155 + "{ \"delay\": 10, \"cell\": 6 }, { \"delay\": 10, \"cell\": 5 },"
156 + "{ \"delay\": 200, \"cell\": 8 }, { \"delay\": 10, \"cell\": 9 },"
157 + "{ \"delay\": 10, \"cell\": 10 }, { \"delay\": 200, \"cell\": 11 },"
158 + "{ \"delay\": 10, \"cell\": 10 }, { \"delay\": 10, \"cell\": 9 }"
159 + "]}"
160 ).toObject()));
161
162 std::shared_ptr<malikania::Animation> testAnimation2 = std::make_shared<malikania::Animation>(malikania::Animation::fromJson(mainWindow, malikania::JsonDocument(
163 std::string("{\"sprite\": \"no-working-yet.json\", \"alias\": \"testAnimation\", \"frames\": [")
164 + "{ \"delay\": 2000, \"cell\": 0 }, { \"delay\": 10, \"cell\": 1 },"
165 + "{ \"delay\": 10, \"cell\": 2 }, { \"delay\": 2000, \"cell\": 3 },"
166 + "{ \"delay\": 10, \"cell\": 1 }, { \"delay\": 10, \"cell\": 1 }"
167 + "]}"
168 ).toObject()));
169
170 malikania::Animator testAnimator1 = malikania::Animator(testAnimation);
171 malikania::Animator testAnimator2 = malikania::Animator(std::move(testAnimation));
172 malikania::Animator testAnimator3 = malikania::Animator(std::move(testAnimation2));
173
174 while (mainWindow.isOpen()) {
175
176 // TODO delete this, just for fun...
177 if (isBouncing) {
178 bounce(mainWindow, mokoPositionX, mokoPositionY);
179 }
180
181 mainWindow.processEvent();
182 mainWindow.setDrawingColor({255, 255, 255, 255});
183 mainWindow.clear();
184 mainWindow.update();
185
186 testSprite.draw(mainWindow, 0, {0, 0, 300, 300});
187 testSprite.draw(mainWindow, 1, {200, 200, 300, 300});
188 testSprite.draw(mainWindow, 2, {400, 400, 300, 300});
189 testSprite.draw(mainWindow, 11, {600, 400, 300, 300});
190
191 malikania::Color c{255, 50, 40, 255};
192 mainWindow.setDrawingColor(c);
193 mainWindow.drawLine({0, 0, 300, 300});
194
195 std::vector<malikania::Point> points{{20, 20}, {30, 50}, {100, 200}, {30, 60}, {20, 300}, {100, 20}};
196 mainWindow.drawLines(points);
197
198 mainWindow.setDrawingColor({200, 50, 200, 255});
199 mainWindow.drawPoint({400, 400});
200 mainWindow.drawPoint({400, 402});
201 mainWindow.drawPoint({400, 405});
202 mainWindow.drawPoint({400, 407});
203 mainWindow.drawPoint({400, 410});
204
205 mainWindow.setDrawingColor({0, 0, 0, 255});
206 mainWindow.drawPoints(points);
207
208 mainWindow.setDrawingColor({30, 30, 30, 255});
209 mainWindow.drawRectangle({500, 500, 200, 100});
210
211 mainWindow.setDrawingColor({130, 30, 30, 255});
212 mainWindow.drawRectangles({{800, 800, 200, 100}, {700, 700, 200, 100}, {750, 750, 200, 100}});
213
214 mainWindow.drawRectangle({600, 200, 200, 100}, true, {0, 255, 0, 255});
215
216 mainWindow.drawRectangles(
217 {{800, 400, 200, 100}, {700, 450, 200, 100}, {750, 500, 200, 100}},
218 true,
219 {{255,0,0,255},{0,255,0,255},{0,0,255,255}}
220 );
221
222 testLabel.draw(mainWindow, {300, 300, 200, 50});
223
224 testAnimator1.draw(mainWindow, {1000, 0, 300, 300});
225 testAnimator2.draw(mainWindow, {100, 600, 300, 300});
226 testAnimator3.draw(mainWindow, {400, 600, 300, 300});
227
228 mainWindow.present();
229
230 std::this_thread::sleep_for(5ms);
231 } 154 }
232
233 //malikania::Window::quit();
234 155
235 return 0; 156 return 0;
236 } 157 }
237 158
238 #endif 159 int boot(const std::string &directory)
160 {
161 std::string path = directory + "/client.js";
162 duk::Context ctx = init();
239 163
240 int main() { return 0; } 164 /* Store the loader */
165 ResourcesLocatorDirectory locator(directory);
166 ClientResourcesLoader loader(locator);
167
168 duk::putGlobal(ctx, "\xff""\xff""loader", duk::RawPointer<ClientResourcesLoader>{&loader});
169
170 if (duk::pevalFile(ctx, path) != 0) {
171 duk::ErrorInfo info = duk::error(ctx, -1);
172
173 std::cerr << info.fileName << ":" << info.lineNumber << ": " << info.stack << std::endl;
174
175 return 1;
176 }
177
178 return run(ctx);
179 }
180
181 } // !namespace
182
183 int main(int argc, char **argv)
184 {
185 -- argc;
186 ++ argv;
187
188 if (argc < 1) {
189 return usage();
190 }
191
192 return boot(argv[0]);
193 }