Browse Source

Split main into more headers

master
Joshua Moerman 12 years ago
parent
commit
ad010c5ab4
  1. 42
      src/app.h
  2. 47
      src/basics.h
  3. 12
      src/json_ext.h
  4. 103
      src/main.cpp

42
src/app.h

@ -0,0 +1,42 @@
#pragma once
#include <chrono>
#include <cmath>
#include <vector>
#include <algorithm>
#include "basics.h"
struct App{
std::vector<User*> people_online;
int uid{0};
void update_positions(){
const float speed = 0.4;
typedef std::chrono::duration<double, std::ratio<1,1>> fseconds;
static auto start = std::chrono::steady_clock::now();
auto end = std::chrono::steady_clock::now();
double time = std::chrono::duration_cast<fseconds>(end-start).count();
//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));
user.position.x = 200 + 200*x;
user.position.y = 200 + 200*y;
}
}
void login(User& user){
user.index = uid++;
people_online.push_back(&user);
}
void logout(User& user){
people_online.erase(std::remove(people_online.begin(), people_online.end(), &user), people_online.end());
}
};

47
src/basics.h

@ -0,0 +1,47 @@
#pragma once
#include <string>
#include <boost/fusion/include/define_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
struct Empty{};
BOOST_FUSION_DEFINE_STRUCT(
, Size,
(int, width)
(int, height)
)
BOOST_FUSION_DEFINE_STRUCT(
, Position,
(int, x)
(int, y)
)
BOOST_FUSION_DEFINE_STRUCT(
, IncomingPacket,
(std::string, name)
(Size, size)
)
struct User {
unsigned int index{0};
std::string name{"Unknown guest"};
Size size{0,0};
Position position{0,0};
User& operator=(IncomingPacket const & p){
name = p.name;
size = p.size;
return *this;
}
};
BOOST_FUSION_ADAPT_STRUCT(
User,
(unsigned int, index)
(std::string, name)
(Size, size)
(Position, position)
)

12
src/json_ext.h

@ -0,0 +1,12 @@
#pragma once
#include "json.h"
template <typename C>
inline js::Value ptrvector_to_json(C const & container){
js::Array array;
for(auto x : container){
array.push_back(to_json(*x));
}
return array;
}

103
src/main.cpp

@ -1,105 +1,32 @@
#include <memory>
#include <string> #include <string>
#include <vector> #include <stdexcept>
#include <algorithm>
#include <chrono>
#include <cmath>
#include <lib/libwebsockets.h> #include <lib/libwebsockets.h>
#include "json.h"
#include "websockets.h" #include "websockets.h"
template <typename C> #include "json.h"
inline js::Value ptrvector_to_json(C const & container){ #include "json_ext.h"
js::Array array;
for(auto x : container){
array.push_back(to_json(*x));
}
return array;
}
BOOST_FUSION_DEFINE_STRUCT(
, Size,
(int, width)
(int, height)
)
BOOST_FUSION_DEFINE_STRUCT(
, Position,
(int, x)
(int, y)
)
BOOST_FUSION_DEFINE_STRUCT(
, IncomingPacket,
(std::string, name)
(Size, size)
)
int uid = 0;
struct User {
unsigned int index{0};
std::string name{"Unknown guest"};
Size size{0,0};
Position position{0,0};
User()
: index(uid++)
{}
User& operator=(IncomingPacket const & p){
name = p.name;
size = p.size;
return *this;
}
};
BOOST_FUSION_ADAPT_STRUCT(
User,
(unsigned int, index)
(std::string, name)
(Size, size)
(Position, position)
)
// unfortunately libwebsockets owns the user thingy
std::vector<User*> people_online;
inline void update_positions(){
const float speed = 0.4;
typedef std::chrono::duration<double, std::ratio<1,1>> fseconds;
static auto start = std::chrono::steady_clock::now();
auto end = std::chrono::steady_clock::now();
double time = std::chrono::duration_cast<fseconds>(end-start).count();
//std::cout << time << std::endl; #include "basics.h"
auto n = people_online.size(); #include "app.h"
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));
user.position.x = 200 + 200*x;
user.position.y = 200 + 200*y;
}
}
std::unique_ptr<App> app;
websockets::TestProtocol<User> default_protocol{ websockets::TestProtocol<User> default_protocol{
// connection established // connection established
[](User& user){ [](User& user){
people_online.push_back(&user); app->login(user);
}, },
// connection closed // connection closed
[](User& user){ [](User& user){
people_online.erase(std::remove(people_online.begin(), people_online.end(), &user), people_online.end()); app->logout(user);
}, },
// write (will always come after receive) // write (will always come after receive)
[](User& user) -> std::string{ [](User& user) -> std::string{
update_positions(); app->update_positions();
return write_json(ptrvector_to_json(people_online)); return write_json(ptrvector_to_json(app->people_online));
}, },
// receive // receive
[](User& user, std::string in){ [](User& user, std::string in){
@ -111,8 +38,6 @@ websockets::TestProtocol<User> default_protocol{
} }
}; };
struct Empty{};
websockets::TestProtocol<Empty> observer_protocol{ websockets::TestProtocol<Empty> observer_protocol{
// connection established // connection established
[](Empty& user){}, [](Empty& user){},
@ -120,14 +45,16 @@ websockets::TestProtocol<Empty> observer_protocol{
[](Empty& user){}, [](Empty& user){},
// write (will always come after receive) // write (will always come after receive)
[](Empty& user) -> std::string{ [](Empty& user) -> std::string{
update_positions(); app->update_positions();
return write_json(ptrvector_to_json(people_online)); return write_json(ptrvector_to_json(app->people_online));
}, },
// receive // receive
[](Empty& user, std::string in){} [](Empty& user, std::string in){}
}; };
int main(int argc, char **argv){ int main(int argc, char **argv){
app.reset(new App);
libwebsocket_protocols protocols[] = { libwebsocket_protocols protocols[] = {
WSstandard_protocol("default", default_protocol), WSstandard_protocol("default", default_protocol),
WSstandard_protocol("observer", observer_protocol), WSstandard_protocol("observer", observer_protocol),