diff --git a/.gitmodules b/.gitmodules index a4e2a7c..18b48dd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "contrib/libwebsockets"] path = contrib/libwebsockets url = git://github.com/warmcat/libwebsockets.git +[submodule "contrib/json-spirit"] + path = contrib/json-spirit + url = git://github.com/sirikata/json-spirit.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cb837a..5044c97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,4 +49,11 @@ set(WITHOUT_TESTAPPS ON CACHE INTERNAL "" FORCE) add_subdirectory(${PROJECT_SOURCE_DIR}/contrib/libwebsockets/) include_directories(SYSTEM "${PROJECT_SOURCE_DIR}/contrib/libwebsockets/") +# JSON lib +set(JSON_SPIRIT_BUILD_DEMOS OFF CACHE INTERNAL "" FORCE) +set(JSON_SPIRIT_BUILD_TESTS OFF CACHE INTERNAL "" FORCE) +set(JSON_SPIRIT_LIBRARY_TYPE "STATIC" CACHE INTERNAL "" FORCE) +add_subdirectory(${PROJECT_SOURCE_DIR}/contrib/json-spirit/build ${CMAKE_CURRENT_BINARY_DIR}/json-spirit) +include_directories(SYSTEM "${PROJECT_SOURCE_DIR}/contrib/json-spirit/include/") + add_subdirectory("src") diff --git a/contrib/json-spirit b/contrib/json-spirit new file mode 160000 index 0000000..b585cf7 --- /dev/null +++ b/contrib/json-spirit @@ -0,0 +1 @@ +Subproject commit b585cf771ca10de706f96ddbd6d853dde72c6bbd diff --git a/sdlgame.sublime-project b/sdlgame.sublime-project index c7fe87f..7589ae6 100644 --- a/sdlgame.sublime-project +++ b/sdlgame.sublime-project @@ -39,6 +39,7 @@ "-I${folder:${project_path:sdlgame.sublime-project}}", "-I${folder:${project_path:sdlgame.sublime-project}}/motor", "-isystem${folder:${project_path:sdlgame.sublime-project}}/contrib/libwebsockets/", + "-isystem${folder:${project_path:sdlgame.sublime-project}}/contrib/json-spirit/include", "-isystem${folder:${project_path:sdlgame.sublime-project}}/motor/contrib/assimp-3.0.1270/include", "-isystem${folder:${project_path:sdlgame.sublime-project}}/motor/contrib/soil", "-isystem${folder:${project_path:sdlgame.sublime-project}}/motor/contrib/bullet/src", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a935f59..c25191d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,4 +60,4 @@ set(all_friggin_libraries onegame_common ${boost} ${motor} ${moggle} ${assimp} $ file(GLOB client_sources "client/*.cpp") add_executable(client client_main.cpp ${client_sources}) -target_link_libraries(client ${all_friggin_libraries} websockets) +target_link_libraries(client ${all_friggin_libraries} websockets json_spirit) diff --git a/src/client/client.cpp b/src/client/client.cpp index 7536316..05fae08 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -3,7 +3,12 @@ #include #include +#include "../../../beats-server/src/json.h" +#include "../../../beats-server/src/json_ext.h" + namespace games { + static Client * current_client{nullptr}; + int callback_func(libwebsocket_context * context, libwebsocket * wsi, libwebsocket_callback_reasons reason, void * user, void * in, size_t len){ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + LWS_SEND_BUFFER_POST_PADDING]; buf[LWS_SEND_BUFFER_PRE_PADDING] = 'a'; @@ -13,11 +18,25 @@ namespace games { libwebsocket_callback_on_writable(context, wsi); break; case LWS_CALLBACK_CLIENT_RECEIVE: - std::cout << std::string(static_cast(in), len) << std::endl; + // std::cout << std::string(static_cast(in), len) << std::endl; break; - case LWS_CALLBACK_CLIENT_WRITEABLE: - libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 1, LWS_WRITE_TEXT); + case LWS_CALLBACK_CLIENT_WRITEABLE:{ + js::Object ret; + if(current_client->lines_changed){ + ret["lines"] = vector_to_json(current_client->lines, [](std::shared_ptr const & i){return cheap_line_type(*i);}); + current_client->lines_changed = false; + } else { + ret["balls"] = vector_to_json(current_client->sim.balls, [](ball_type const & b){return cheap_ball_type(b);}); + } + std::string string_to_send = write_json(ret); + + unsigned char * buf = new unsigned char [LWS_SEND_BUFFER_PRE_PADDING + string_to_send.size() + LWS_SEND_BUFFER_POST_PADDING]; + memcpy(&buf[LWS_SEND_BUFFER_PRE_PADDING], string_to_send.c_str(), string_to_send.size()); + int n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], string_to_send.size(), LWS_WRITE_TEXT); + if (n < 0) return 1; + if (n < string_to_send.size()) return -1; break; + } default: break; } return 0; @@ -36,6 +55,8 @@ namespace games { for(auto & l : line->calculate_lines()){ sim.lines.push_back(l); } + + lines_changed = true; } bool Client::has_ended(){ @@ -52,6 +73,11 @@ namespace games { Client::Client(int window_width_, int window_height_, std::shared_ptr& active_base_) : Base(window_width_, window_height_, active_base_) { + if(current_client){ + CERR << "Warning: global client already defined\n"; + } + current_client = this; + // simulation beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f}); cheap_line_type line{{{50.0f, 100.0f}, {150.0f, 200.0f}, simulation::kOneWay}}; @@ -131,20 +157,21 @@ namespace games { } // websockets - const float poll_interval = 5.0; - poll_time += dt; + const float push_interval = 0.05; + push_time += dt; int ret = libwebsocket_service(context, 10); if(ret < 0) { CERR << "ERROR: libwebsocket returns < 0\n"; } - if(poll_time >= poll_interval){ + if(push_time >= push_interval){ libwebsocket_callback_on_writable(context, wsi); - poll_time -= poll_interval; + push_time -= push_interval; } } Client::~Client(){ libwebsocket_context_destroy(context); + current_client = nullptr; } } diff --git a/src/client/client.hpp b/src/client/client.hpp index c35ef69..865e752 100644 --- a/src/client/client.hpp +++ b/src/client/client.hpp @@ -22,7 +22,8 @@ namespace games { // websocket part libwebsocket_context * context{nullptr}; libwebsocket * wsi{nullptr}; - float poll_time{0.0}; + float push_time{0.0}; + bool lines_changed{true}; // simulation part int balluid{0};