diff --git a/.gitmodules b/.gitmodules index 18b48dd..8a1aeb6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "contrib/json-spirit"] path = contrib/json-spirit url = git://github.com/sirikata/json-spirit.git +[submodule "simulation"] + path = simulation + url = git@github.com:Jaxan/beats-sim.git diff --git a/simulation b/simulation new file mode 160000 index 0000000..018cb17 --- /dev/null +++ b/simulation @@ -0,0 +1 @@ +Subproject commit 018cb176c4b3970cd2a6ecae8a63520183c5ddd3 diff --git a/src/adaptions.h b/src/adaptions.h new file mode 100644 index 0000000..d5bc633 --- /dev/null +++ b/src/adaptions.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +#include "simulation/Simulation.h" +#include "simulation/Beat.h" +#include "simulation/math.h" + +BOOST_FUSION_ADAPT_STRUCT( + ::math::Vec2, + (float, x) + (float, y) +) + +BOOST_FUSION_ADAPT_TPL_STRUCT( + (BallInfo), + (simulation::Ball) (BallInfo), + (BallInfo, information) + (::math::Vec2, position) + (::math::Vec2, speed) +) + +BOOST_FUSION_ADAPT_TPL_STRUCT( + (LineInfo), + (simulation::Line) (LineInfo), + (::math::Vec2, starting_point) + (::math::Vec2, end_point) + (simulation::LineKind, line_kind) +) \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 5af8427..bf62171 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,22 +14,24 @@ std::unique_ptr app; +using namespace websockets; + websockets::TestProtocol default_protocol{ // connection established - [](User& user){ + [](User& user, basic_websocket_info){ app->login(user); }, // connection closed - [](User& user){ + [](User& user, basic_websocket_info){ app->logout(user); }, // write (will always come after receive) - [](User& user) -> std::string{ app->update_positions(); return write_json(ptrvector_to_json(app->people_online)); + [](User& user, basic_websocket_info) -> std::string{ }, // receive - [](User& user, std::string in){ + [](User& user, std::string in, basic_websocket_info){ try{ user = from_json(parse_json(in)); } catch(std::exception& e) { @@ -40,16 +42,16 @@ websockets::TestProtocol default_protocol{ websockets::TestProtocol observer_protocol{ // connection established - [](Empty& user){}, + [](Empty& user, basic_websocket_info){}, // connection closed - [](Empty& user){}, + [](Empty& user, basic_websocket_info){}, // write (will always come after receive) - [](Empty& user) -> std::string{ app->update_positions(); return write_json(ptrvector_to_json(app->people_online)); + [](Empty& user, basic_websocket_info) -> std::string{ }, // receive - [](Empty& user, std::string in){} + [](Empty& user, std::string in, basic_websocket_info){} }; int main(int argc, char **argv){ diff --git a/src/websockets.cpp b/src/websockets.cpp index e06f6fa..1191e14 100644 --- a/src/websockets.cpp +++ b/src/websockets.cpp @@ -1,6 +1,9 @@ #include "websockets.h" +#include +#include + namespace websockets { option options[] = { @@ -11,7 +14,7 @@ namespace websockets { { NULL, 0, 0, 0 } }; - int default_main(int argc, char **argv, libwebsocket_protocols* protocols){ + int default_main(int argc, char **argv, libwebsocket_protocols* protocols, std::function runloop_callback){ int port = 7681; int use_ssl = 0; char interface_name[128] = ""; @@ -63,9 +66,21 @@ namespace websockets { static bool force_exit = false; signal(SIGINT, [](int){ force_exit = true; }); + + using clock = std::chrono::steady_clock; + using duration = std::chrono::duration; while (!force_exit) { + auto begin = clock::now(); auto ret = libwebsocket_service(context.get_raw(), 10); if(ret < 0) break; + + if(runloop_callback) runloop_callback(); + + auto end = clock::now(); + duration dur = (end - begin); + dur = duration(1.0/60.0) - dur; + + std::this_thread::sleep_for(dur); } } diff --git a/src/websockets.h b/src/websockets.h index 247eb55..95c9da9 100644 --- a/src/websockets.h +++ b/src/websockets.h @@ -88,6 +88,15 @@ namespace websockets { }; }; + struct basic_websocket_info{ + libwebsocket_context* context{nullptr}; + libwebsocket* wsi{nullptr}; + basic_websocket_info(libwebsocket_context* context, libwebsocket* wsi) + : context(context) + , wsi(wsi) + {} + }; + // 4-function Protocol, provide functions to handle establishment, closing, receiving and writing (follows receiving) // To let the callback return something non-zero (in case of error), use websockets::runtime_error // Only types with no-arg ctor are allowed (uses placement new, because libwebsockets allocates for us) @@ -95,10 +104,10 @@ namespace websockets { struct TestProtocol { typedef T user_type; - std::function establish_func; - std::function close_func; - std::function write_func; - std::function receive_func; + std::function establish_func; + std::function close_func; + std::function write_func; + std::function receive_func; bool verbose{false}; @@ -111,20 +120,21 @@ namespace websockets { int callback(libwebsocket_context* context, libwebsocket* wsi, libwebsocket_callback_reasons reason, void* user_ptr, void *in, size_t len){ user_type& user = *static_cast(user_ptr); + basic_websocket_info binfo{context, wsi}; try{ switch (reason) { case LWS_CALLBACK_ESTABLISHED: lwsl_notice("Connection established (%p, %p)\n", this, user_ptr); new (user_ptr) user_type(); - establish_func(user); + establish_func(user, binfo); break; case LWS_CALLBACK_CLOSED: lwsl_notice("Connection closed (%p, %p)\n", this, user_ptr); user.~user_type(); - close_func(user); + close_func(user, binfo); break; case LWS_CALLBACK_SERVER_WRITEABLE:{ - std::string string_to_send = write_func(user); + std::string string_to_send = write_func(user, binfo); if(verbose) std::cout << string_to_send << std::endl; // we need the extra bytes padding on both sides :( unsigned char * buf = new unsigned char [LWS_SEND_BUFFER_PRE_PADDING + string_to_send.size() + LWS_SEND_BUFFER_POST_PADDING]; @@ -135,7 +145,7 @@ namespace websockets { break; } case LWS_CALLBACK_RECEIVE: - receive_func(user, std::string((char*)in, len)); + receive_func(user, std::string((char*)in, len), binfo); libwebsocket_callback_on_writable(context, wsi); break; default: @@ -158,6 +168,6 @@ namespace websockets { #define WSstandard_protocol(name, protocol)\ { name, WSprotocol_callback(protocol), sizeof(decltype(protocol)::user_type) } - int default_main(int argc, char **argv, libwebsocket_protocols* protocols); + int default_main(int argc, char **argv, libwebsocket_protocols* protocols, std::function runloop_callback = nullptr); } // namespace websockets