Fixed some includes, made a basic implementation for forwarding an uberclient
This commit is contained in:
parent
d3dcc616f8
commit
85af1c09a2
5 changed files with 114 additions and 50 deletions
|
@ -4,9 +4,9 @@
|
|||
#include <boost/fusion/include/define_struct.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/Beat.h"
|
||||
#include "simulation/Math.h"
|
||||
#include "../simulation/Simulation.h"
|
||||
#include "../simulation/Beat.h"
|
||||
#include "../simulation/Math.h"
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
::math::Vec2,
|
||||
|
@ -28,4 +28,4 @@ BOOST_FUSION_ADAPT_TPL_STRUCT(
|
|||
(::math::Vec2, starting_point)
|
||||
(::math::Vec2, end_point)
|
||||
(simulation::LineKind, line_kind)
|
||||
)
|
||||
)
|
||||
|
|
75
src/app.h
75
src/app.h
|
@ -7,33 +7,54 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <lib/libwebsockets.h>
|
||||
#include "websockets.h"
|
||||
|
||||
#include "app_common.h"
|
||||
|
||||
struct libwebsocket;
|
||||
using namespace websockets;
|
||||
|
||||
struct App{
|
||||
std::vector<User*> people_online;
|
||||
libwebsocket * uberclient{nullptr};
|
||||
|
||||
std::vector<AbstractLine> lines;
|
||||
|
||||
simu_type sim;
|
||||
beat_type beat;
|
||||
|
||||
const float iframerate = 1.0/60.0;
|
||||
int peopleuid{0};
|
||||
int balluid{0};
|
||||
int lineuid{0};
|
||||
|
||||
struct OfflineSim {
|
||||
std::vector<cheap_line_type> lines;
|
||||
std::vector<cheap_ball_type> balls;
|
||||
} offline_sim;
|
||||
|
||||
struct OnlineSim {
|
||||
const float iframerate = 1.0/60.0;
|
||||
std::vector<AbstractLine> lines;
|
||||
simu_type sim;
|
||||
beat_type beat;
|
||||
} online_sim;
|
||||
|
||||
App(){
|
||||
beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f});
|
||||
online_sim.beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f});
|
||||
|
||||
AbstractLine line(Vec2{50.0f, 100.0f}, Vec2{150.0f, 200.0f}, simulation::kOneWay);
|
||||
add_line(line);
|
||||
}
|
||||
|
||||
void add_line(cheap_line_type const & line){
|
||||
if(uberclient){
|
||||
// write
|
||||
} else {
|
||||
add_line(AbstractLine{
|
||||
to_FloatVec2(line.starting_point),
|
||||
to_FloatVec2(line.end_point),
|
||||
line.line_kind});
|
||||
}
|
||||
}
|
||||
|
||||
void add_line(AbstractLine const & line){
|
||||
lines.push_back(line);
|
||||
online_sim.lines.push_back(line);
|
||||
for(auto & l : line.calculate_lines()){
|
||||
sim.lines.push_back(l);
|
||||
online_sim.sim.lines.push_back(l);
|
||||
}
|
||||
for(auto & u : people_online){
|
||||
u->update_lines = true;
|
||||
|
@ -50,11 +71,33 @@ struct App{
|
|||
}
|
||||
|
||||
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++);
|
||||
if(!uberclient){
|
||||
float dt = online_sim.iframerate;
|
||||
online_sim.sim.update(dt);
|
||||
|
||||
for(auto n : online_sim.beat.update(dt)){
|
||||
online_sim.sim.balls.emplace_back(n.x, n.y, 0, 0, balluid++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uberclient_connected(basic_websocket_info binfo){
|
||||
if(uberclient) throw websockets::runtime_error("Warning: another uberclient connection\n");
|
||||
uberclient = binfo.wsi;
|
||||
|
||||
online_sim.lines.clear();
|
||||
online_sim.sim.lines.clear();
|
||||
online_sim.sim.balls.clear();
|
||||
}
|
||||
|
||||
void uberclient_disconnected(basic_websocket_info binfo){
|
||||
if(uberclient != binfo.wsi) throw websockets::runtime_error("Warning: non-uberclient disconnected");
|
||||
uberclient = nullptr;
|
||||
|
||||
for(auto l : offline_sim.lines){
|
||||
add_line(l);
|
||||
}
|
||||
offline_sim.lines.clear();
|
||||
offline_sim.balls.clear();
|
||||
}
|
||||
};
|
|
@ -3,8 +3,8 @@
|
|||
#include "basics.h"
|
||||
#include "adaptions.h"
|
||||
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/Beat.h"
|
||||
#include "../simulation/Simulation.h"
|
||||
#include "../simulation/Beat.h"
|
||||
|
||||
using Vec2 = math::Vec2;
|
||||
using LineKind = simulation::LineKind;
|
||||
|
@ -70,10 +70,15 @@ BOOST_FUSION_DEFINE_STRUCT(
|
|||
(int, y)
|
||||
)
|
||||
|
||||
inline math::Vec2 to_FloatVec2(IntVec2 v){
|
||||
return {static_cast<float>(v.x), static_cast<float>(v.y)};
|
||||
}
|
||||
|
||||
struct cheap_ball_type {
|
||||
IntVec2 position;
|
||||
ball_info information;
|
||||
|
||||
cheap_ball_type() = default;
|
||||
cheap_ball_type(ball_type const & b)
|
||||
: position(b.position)
|
||||
, information(b.information)
|
||||
|
@ -91,6 +96,7 @@ struct cheap_line_type {
|
|||
IntVec2 end_point;
|
||||
int line_kind;
|
||||
|
||||
cheap_line_type() = default;
|
||||
cheap_line_type(AbstractLine const & l)
|
||||
: starting_point(l.starting_point)
|
||||
, end_point(l.end_point)
|
||||
|
|
64
src/main.cpp
64
src/main.cpp
|
@ -31,24 +31,35 @@ websockets::TestProtocol<User> default_protocol{
|
|||
[](User& user, basic_websocket_info) -> std::string{
|
||||
js::Object ret;
|
||||
if(user.update_lines){
|
||||
ret["lines"] = vector_to_json(app->lines, [](AbstractLine const & l){return cheap_line_type(l);});
|
||||
if(app->uberclient){
|
||||
ret["lines"] = vector_to_json(app->offline_sim.lines);
|
||||
} else {
|
||||
ret["lines"] = vector_to_json(app->online_sim.lines, [](AbstractLine const & l){return cheap_line_type(l);});
|
||||
}
|
||||
user.update_lines = false;
|
||||
} else {
|
||||
ret["balls"] = vector_to_json(app->sim.balls, [](ball_type const & b){return cheap_ball_type(b);});
|
||||
if(app->uberclient){
|
||||
ret["balls"] = vector_to_json(app->offline_sim.balls);
|
||||
} else {
|
||||
ret["balls"] = vector_to_json(app->online_sim.sim.balls, [](ball_type const & b){return cheap_ball_type(b);});
|
||||
}
|
||||
}
|
||||
return write_json(ret);
|
||||
},
|
||||
// receive
|
||||
[](User& user, std::string in, basic_websocket_info){
|
||||
[](User& user, std::string in, basic_websocket_info binfo){
|
||||
try{
|
||||
auto object = parse_json(in).getObject();
|
||||
auto command = object["command"];
|
||||
if(command == "add line"){
|
||||
app->add_line(from_json<AbstractLine>(object["data"]));
|
||||
app->add_line(from_json<cheap_line_type>(object["data"]));
|
||||
std::cout << "Line from: " << &user << ": " << user.name << std::endl;
|
||||
request_write(binfo);
|
||||
} else if (command == "update user") {
|
||||
user = from_json<IncomingPacket>(object["data"]);
|
||||
std::cout << "Updated user: " << &user << ": " << user.name << std::endl;
|
||||
} else if (command == "poll") {
|
||||
request_write(binfo);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
throw websockets::runtime_error(e.what());
|
||||
|
@ -56,32 +67,16 @@ websockets::TestProtocol<User> default_protocol{
|
|||
}
|
||||
};
|
||||
|
||||
websockets::TestProtocol<Empty> observer_protocol{
|
||||
// connection established
|
||||
[](Empty& user, basic_websocket_info){},
|
||||
// connection closed
|
||||
[](Empty& user, basic_websocket_info){},
|
||||
// write (will always come after receive)
|
||||
[](Empty& user, basic_websocket_info) -> std::string{
|
||||
js::Object ret;
|
||||
ret["people"] = vector_to_json(app->people_online, [](User* u){return *u;});
|
||||
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<Empty> 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;
|
||||
std::cout << "uberclient connected!\n";
|
||||
app->uberclient_connected(binfo);
|
||||
},
|
||||
// connection closed
|
||||
[](Empty& user, basic_websocket_info){
|
||||
app->uberclient = nullptr;
|
||||
[](Empty& user, basic_websocket_info binfo){
|
||||
std::cout << "uberclient left!\n";
|
||||
app->uberclient_disconnected(binfo);
|
||||
},
|
||||
// write (will always come after receive)
|
||||
[](Empty& user, basic_websocket_info) -> std::string{
|
||||
|
@ -89,7 +84,23 @@ websockets::TestProtocol<Empty> uberclient_protocol{
|
|||
return std::to_string(i++);
|
||||
},
|
||||
// receive
|
||||
[](Empty& user, std::string in, basic_websocket_info){}
|
||||
[](Empty& user, std::string in, basic_websocket_info){
|
||||
auto object = parse_json(in).getObject();
|
||||
if(object.count("lines")){
|
||||
app->offline_sim.lines.clear();
|
||||
auto lines = object["lines"];
|
||||
for(auto&& js : lines.getArray()){
|
||||
app->offline_sim.lines.push_back(from_json<cheap_line_type>(js));
|
||||
}
|
||||
}
|
||||
if(object.count("balls")){
|
||||
app->offline_sim.balls.clear();
|
||||
auto balls = object["balls"];
|
||||
for(auto&& js : balls.getArray()){
|
||||
app->offline_sim.balls.push_back(from_json<cheap_ball_type>(js));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
@ -97,7 +108,6 @@ 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
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
@ -97,6 +99,10 @@ namespace websockets {
|
|||
{}
|
||||
};
|
||||
|
||||
inline void request_write(basic_websocket_info const & binfo){
|
||||
libwebsocket_callback_on_writable(binfo.context, binfo.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)
|
||||
|
@ -146,7 +152,6 @@ namespace websockets {
|
|||
}
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
receive_func(user, std::string((char*)in, len), binfo);
|
||||
libwebsocket_callback_on_writable(context, wsi);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Reference in a new issue