diff --git a/simulation b/simulation index 018cb17..61c889b 160000 --- a/simulation +++ b/simulation @@ -1 +1 @@ -Subproject commit 018cb176c4b3970cd2a6ecae8a63520183c5ddd3 +Subproject commit 61c889b0c697f522a66a7bfaf002cd143d018060 diff --git a/src/app.h b/src/app.h index 73e025f..f777eb5 100644 --- a/src/app.h +++ b/src/app.h @@ -1,42 +1,102 @@ #pragma once +#include +#include #include #include #include #include #include "basics.h" +#include "adaptions.h" +#include "simulation/Simulation.h" +#include "simulation/Beat.h" + +using Vec2 = math::Vec2; +using LineKind = simulation::LineKind; + +using ball_info = int; +using line_info = void; +using ball_type = simulation::Ball; +using line_type = simulation::Line; +using simu_type = simulation::Simulation; + +using note_info = Vec2; +using note_type = Note; +using beat_type = Beat; + +struct AbstractLine { + math::Vec2 starting_point; + math::Vec2 end_point; + LineKind line_kind; + + const float hsize = 5.0f; + + AbstractLine(math::Vec2 starting_point, math::Vec2 end_point, LineKind line_kind) + : starting_point(starting_point) + , end_point(end_point) + , line_kind(line_kind) + {} + + // create 6 lines, to emulate width, and rounded edges + std::vector calculate_lines() const { + auto dir = normalize(end_point - starting_point); + auto normal = rotate_ccw(dir); + + if(line_kind == simulation::kOneWay){ + std::vector ret; + ret.emplace_back(starting_point + hsize*normal, end_point + hsize*normal, line_kind); + ret.emplace_back(end_point + hsize*normal, end_point + hsize*dir, line_kind); + ret.emplace_back(end_point + hsize*dir, end_point - hsize*normal, line_kind); + ret.emplace_back(end_point - hsize*normal, starting_point - hsize*normal, line_kind); + ret.emplace_back(starting_point - hsize*normal, starting_point - hsize*dir, line_kind); + ret.emplace_back(starting_point - hsize*dir, starting_point + hsize*normal, line_kind); + return ret; + } else { + std::vector ret; + ret.emplace_back(starting_point, end_point, line_kind); + return ret; + } + } +}; + +struct libwebsocket; struct App{ std::vector people_online; - int uid{0}; + libwebsocket * uberclient{nullptr}; - void update_positions(){ - const float speed = 0.4; + simu_type sim; + beat_type beat; - typedef std::chrono::duration> fseconds; - static auto start = std::chrono::steady_clock::now(); - auto end = std::chrono::steady_clock::now(); - double time = std::chrono::duration_cast(end-start).count(); + const float iframerate = 1.0/60.0; + int peopleuid{0}; + int balluid{0}; - //std::cout << time << std::endl; - auto n = people_online.size(); - for(int i = 0; i < n; ++i){ - User& user = *people_online[i]; - double x = cos(speed * time + 2*M_PI*i/double(n)); - double y = sin(speed * time + 2*M_PI*i/double(n)); + App(){ + beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f}); - user.position.x = 200 + 200*x; - user.position.y = 200 + 200*y; + AbstractLine line(Vec2{50.0f, 100.0f}, Vec2{150.0f, 200.0f}, simulation::kOneWay); + for(auto & l : line.calculate_lines()){ + sim.lines.push_back(l); } } void login(User& user){ - user.index = uid++; + user.index = peopleuid++; people_online.push_back(&user); } void logout(User& user){ people_online.erase(std::remove(people_online.begin(), people_online.end(), &user), people_online.end()); } + + void update(){ + float dt = iframerate; + sim.update(dt); + + for(auto n : beat.update(dt)){ + sim.balls.emplace_back(n.x, n.y, 0, 0, balluid++); + } + } }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index bf62171..0a077e1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,9 +26,12 @@ websockets::TestProtocol default_protocol{ app->logout(user); }, // write (will always come after receive) - app->update_positions(); - return write_json(ptrvector_to_json(app->people_online)); [](User& user, basic_websocket_info) -> std::string{ + js::Object ret; + ret["people"] = ptrvector_to_json(app->people_online); + ret["balls"] = vector_to_json(app->sim.balls); + ret["lines"] = vector_to_json(app->sim.lines); + return write_json(ret); }, // receive [](User& user, std::string in, basic_websocket_info){ @@ -46,9 +49,31 @@ websockets::TestProtocol observer_protocol{ // connection closed [](Empty& user, basic_websocket_info){}, // write (will always come after receive) - app->update_positions(); - return write_json(ptrvector_to_json(app->people_online)); [](Empty& user, basic_websocket_info) -> std::string{ + js::Object ret; + ret["people"] = ptrvector_to_json(app->people_online); + ret["balls"] = vector_to_json(app->sim.balls); + ret["lines"] = vector_to_json(app->sim.lines); + return write_json(ret); + }, + // receive + [](Empty& user, std::string in, basic_websocket_info){} +}; + +websockets::TestProtocol uberclient_protocol{ + // connection established + [](Empty& user, basic_websocket_info binfo){ + if(app->uberclient) throw websockets::runtime_error("Warning: another uberclient connection\n"); + app->uberclient = binfo.wsi; + }, + // connection closed + [](Empty& user, basic_websocket_info){ + app->uberclient = nullptr; + }, + // write (will always come after receive) + [](Empty& user, basic_websocket_info) -> std::string{ + static int i = 0; + return std::to_string(i++); }, // receive [](Empty& user, std::string in, basic_websocket_info){} @@ -60,8 +85,9 @@ int main(int argc, char **argv){ libwebsocket_protocols protocols[] = { WSstandard_protocol("default", default_protocol), WSstandard_protocol("observer", observer_protocol), + WSstandard_protocol("uberclient", uberclient_protocol), { NULL, NULL, 0 } // end of list }; - return websockets::default_main(argc, argv, protocols); + return websockets::default_main(argc, argv, protocols, []{app->update();}); }