More smart pointers, clean up threading a little

The threading is still not good
This commit is contained in:
Jack Bond-Preston 2016-07-12 23:43:23 +01:00
parent 079dab7c91
commit 3f8e6bf5f5
6 changed files with 122 additions and 127 deletions

View File

@ -49,7 +49,7 @@ ClientConnection::ClientConnection() {
websocketpp::lib::placeholders::_1 websocketpp::lib::placeholders::_1
)); ));
gHandler = new GatewayHandler(); gh = std::make_unique<GatewayHandler>();
} }
// Open a connection to the URI provided // Open a connection to the URI provided
@ -111,8 +111,9 @@ void ClientConnection::on_message(websocketpp::connection_hdl hdl, message_ptr m
return; return;
} }
// Pass the message to the gateway handler // Pass the message to the gateway handler
gHandler->handle_data(message->get_payload(), c, hdl); gh->handle_data(message->get_payload(), c, hdl);
} }
void ClientConnection::on_close(websocketpp::connection_hdl) { void ClientConnection::on_close(websocketpp::connection_hdl) {

View File

@ -14,7 +14,7 @@ typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr; typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
typedef client::connection_ptr connection_ptr; typedef client::connection_ptr connection_ptr;
class GatewayHandler; #include "GatewayHandler.hpp"
class ClientConnection { class ClientConnection {
public: public:
@ -33,7 +33,7 @@ public:
private: private:
client c; client c;
GatewayHandler *gHandler; std::unique_ptr<GatewayHandler> gh;
}; };
#endif #endif

View File

@ -31,37 +31,27 @@ void GatewayHandler::handle_data(std::string data, client &c, websocketpp::conne
} }
} }
void GatewayHandler::heartbeat(websocketpp::lib::error_code const & ec, client *c, websocketpp::connection_hdl *hdl) { void GatewayHandler::heartbeat(client *c, websocketpp::connection_hdl hdl, int interval) {
while (true) {
boost::this_thread::sleep(boost::posix_time::milliseconds(interval));
json heartbeat = { json heartbeat = {
{ "op", 1 }, { "op", 1 },
{ "d", last_seq } { "d", last_seq }
}; };
c->send(*hdl, heartbeat.dump(), websocketpp::frame::opcode::text); c->send(hdl, heartbeat.dump(), websocketpp::frame::opcode::text);
c->set_timer(heartbeat_interval, websocketpp::lib::bind(
&GatewayHandler::heartbeat,
this,
websocketpp::lib::placeholders::_1,
c,
hdl
));
c->get_alog().write(websocketpp::log::alevel::app, "Sent heartbeat. (seq: " + std::to_string(last_seq) + ")"); c->get_alog().write(websocketpp::log::alevel::app, "Sent heartbeat. (seq: " + std::to_string(last_seq) + ")");
} }
}
void GatewayHandler::on_hello(json decoded, client &c, websocketpp::connection_hdl &hdl) { void GatewayHandler::on_hello(json decoded, client &c, websocketpp::connection_hdl &hdl) {
heartbeat_interval = decoded["d"]["heartbeat_interval"]; heartbeat_interval = decoded["d"]["heartbeat_interval"];
c.get_alog().write(websocketpp::log::alevel::app, "Heartbeat interval: " + std::to_string(heartbeat_interval / 1000.0f) + " seconds"); c.get_alog().write(websocketpp::log::alevel::app, "Heartbeat interval: " + std::to_string(heartbeat_interval / 1000.0f) + " seconds");
c.set_timer(heartbeat_interval, websocketpp::lib::bind( heartbeat_thread = std::make_unique<boost::thread>(boost::bind(&GatewayHandler::heartbeat, this, &c, hdl, heartbeat_interval));
&GatewayHandler::heartbeat,
this,
websocketpp::lib::placeholders::_1,
&c,
&hdl
));
identify(c, hdl); identify(c, hdl);
} }
@ -78,13 +68,22 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
} }
else if (event_name == "GUILD_CREATE") { else if (event_name == "GUILD_CREATE") {
std::string guild_id = data["id"]; std::string guild_id = data["id"];
try {
guilds[guild_id] = std::make_unique<DiscordObjects::Guild>(data); guilds[guild_id] = std::make_unique<DiscordObjects::Guild>(data);
}
catch (std::domain_error err) {
// this doesn't even work
c.get_alog().write(websocketpp::log::elevel::rerror, "Domain error");
}
c.get_alog().write(websocketpp::log::alevel::app, "Loaded guild: " + guilds[guild_id]->name);
for (json channel : data["channels"]) { for (json channel : data["channels"]) {
std::string channel_id = channel["id"]; std::string channel_id = channel["id"];
channel["guild_id"] = guild_id; channel["guild_id"] = guild_id;
// create channel obj, add to overall channel list // create channel obj, add to overall channel list
channels[channel_id] = std::make_unique<DiscordObjects::Channel>(channel); channels[channel_id] = std::make_shared<DiscordObjects::Channel>(channel);
// add ptr to said channel list to guild's channel list // add ptr to said channel list to guild's channel list
guilds[guild_id]->channels.push_back(std::shared_ptr<DiscordObjects::Channel>(channels[channel_id])); guilds[guild_id]->channels.push_back(std::shared_ptr<DiscordObjects::Channel>(channels[channel_id]));
} }

View File

@ -42,7 +42,7 @@ public:
void handle_data(std::string data, client &c, websocketpp::connection_hdl &hdl); void handle_data(std::string data, client &c, websocketpp::connection_hdl &hdl);
void heartbeat(websocketpp::lib::error_code const & ec, client *c, websocketpp::connection_hdl *hdl); void heartbeat(client *c, websocketpp::connection_hdl hdl, int interval);
void on_hello(json decoded, client &c, websocketpp::connection_hdl &hdl); void on_hello(json decoded, client &c, websocketpp::connection_hdl &hdl);
@ -69,6 +69,8 @@ private:
// <channel_id, game obj> // <channel_id, game obj>
std::map<std::string, std::unique_ptr<TriviaGame>> games; std::map<std::string, std::unique_ptr<TriviaGame>> games;
std::unique_ptr<boost::thread> heartbeat_thread;
APIHelper *ah; APIHelper *ah;
}; };

View File

@ -23,6 +23,8 @@ TriviaGame::TriviaGame(GatewayHandler *gh, APIHelper *ah, std::string channel_id
} }
TriviaGame::~TriviaGame() { TriviaGame::~TriviaGame() {
current_thread.reset();
if (scores.size() == 0) { if (scores.size() == 0) {
ah->send_message(channel_id, ":red_circle: Game cancelled!"); ah->send_message(channel_id, ":red_circle: Game cancelled!");
return; return;
@ -164,7 +166,7 @@ TriviaGame::~TriviaGame() {
} }
void TriviaGame::start() { void TriviaGame::start() {
question(); current_thread = std::make_unique<boost::thread>(boost::bind(&TriviaGame::question, this));
} }
void TriviaGame::interrupt() { void TriviaGame::interrupt() {
@ -172,6 +174,7 @@ void TriviaGame::interrupt() {
} }
void TriviaGame::question() { void TriviaGame::question() {
while (questions_asked < total_questions) {
sqlite3 *db; int rc; std::string sql; sqlite3 *db; int rc; std::string sql;
/// open db /// open db
@ -201,7 +204,8 @@ void TriviaGame::question() {
boost::algorithm::to_lower(answer); boost::algorithm::to_lower(answer);
boost::split(current_answers, answer, boost::is_any_of("*")); boost::split(current_answers, answer, boost::is_any_of("*"));
} else if (rc != SQLITE_DONE) { }
else if (rc != SQLITE_DONE) {
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
std::cerr << "SQLite error." << std::endl; std::cerr << "SQLite error." << std::endl;
} }
@ -213,10 +217,13 @@ void TriviaGame::question() {
ah->send_message(channel_id, ":question: **(" + std::to_string(questions_asked) + "/" + std::to_string(total_questions) + ")** " + current_question); ah->send_message(channel_id, ":question: **(" + std::to_string(questions_asked) + "/" + std::to_string(total_questions) + ")** " + current_question);
question_start = boost::posix_time::microsec_clock::universal_time(); question_start = boost::posix_time::microsec_clock::universal_time();
current_thread = std::make_unique<boost::thread>(boost::bind(&TriviaGame::give_hint, this, 0, "")); give_hint(0, "");
}
gh->delete_game(channel_id);
} }
void TriviaGame::give_hint(int hints_given, std::string hint) { void TriviaGame::give_hint(int hints_given, std::string hint) {
while (hints_given < 4) {
boost::this_thread::sleep(interval); boost::this_thread::sleep(interval);
std::string answer = *current_answers.begin(); std::string answer = *current_answers.begin();
@ -276,23 +283,9 @@ void TriviaGame::give_hint(int hints_given, std::string hint) {
if (print) { if (print) {
ah->send_message(channel_id, ":small_orange_diamond: Hint: **`" + hint + "`**"); ah->send_message(channel_id, ":small_orange_diamond: Hint: **`" + hint + "`**");
} }
if (hints_given < 4) {
current_thread = std::make_unique<boost::thread>(boost::bind(&TriviaGame::give_hint, this, hints_given, hint));
} else {
current_thread = std::make_unique<boost::thread>(boost::bind(&TriviaGame::question_failed, this));
} }
}
void TriviaGame::question_failed() {
boost::this_thread::sleep(interval); boost::this_thread::sleep(interval);
ah->send_message(channel_id, ":exclamation: Question failed. Answer: ** `" + *current_answers.begin() + "` **"); ah->send_message(channel_id, ":exclamation: Question failed. Answer: ** `" + *current_answers.begin() + "` **");
if (questions_asked < total_questions) {
question();
} else {
gh->delete_game(channel_id);
}
} }
void TriviaGame::handle_answer(std::string answer, DiscordObjects::User sender) { void TriviaGame::handle_answer(std::string answer, DiscordObjects::User sender) {
@ -312,7 +305,8 @@ void TriviaGame::handle_answer(std::string answer, DiscordObjects::User sender)
update_average_time(sender.id, diff.total_milliseconds()); update_average_time(sender.id, diff.total_milliseconds());
if (questions_asked < total_questions) { if (questions_asked < total_questions) {
question(); interrupt(); current_thread.reset(); // don't know if required
current_thread = std::make_unique<boost::thread>(boost::bind(&TriviaGame::question, this));
} else { } else {
gh->delete_game(channel_id); gh->delete_game(channel_id);
} }

View File

@ -33,7 +33,6 @@ private:
void question(); void question();
void give_hint(int hints_given, std::string hint); void give_hint(int hints_given, std::string hint);
void question_failed();
void increase_score(std::string user_id); void increase_score(std::string user_id);
void update_average_time(std::string user_id, int time); void update_average_time(std::string user_id, int time);