From de6a4d656fa928f7ba19448ff59667273bd99c38 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sun, 27 Nov 2011 02:14:57 +0100 Subject: [PATCH] Support for command input For starters, 'move_dir x y' command is supported. --- agent.cc | 9 +++++++++ agent.h | 1 + connection.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- connection.h | 5 ++++- main.cc | 5 +++++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/agent.cc b/agent.cc index 348c948..f9169ae 100644 --- a/agent.cc +++ b/agent.cc @@ -28,6 +28,15 @@ agent::move_dir(int dir_x, int dir_y) return true; } +void +agent::on_action_takes(void) +{ + if (!conn) + return; + + conn->actions(this); +} + void agent::on_tick(void) { diff --git a/agent.h b/agent.h index 4a31728..714f1e1 100644 --- a/agent.h +++ b/agent.h @@ -19,6 +19,7 @@ public: bool move_dir(int dir_x, int dir_y); + void on_action_takes(void); void on_tick(void); void on_senses_update(void); diff --git a/connection.cc b/connection.cc index fdc2221..9425e6b 100644 --- a/connection.cc +++ b/connection.cc @@ -2,9 +2,10 @@ #include #include #include -#include +#include #include +#include #include "agent.h" #include "connection.h" @@ -20,6 +21,38 @@ connection::senses(int tick_id, char around[4]) pthread_mutex_unlock(&buf_lock); } +void +connection::actions(class agent *agent) +{ + pthread_mutex_lock(&buf_lock); + if (in_buf.find("\r\n\r\n") == std::string::npos) { + /* Not enough data, needs to wait until next turn, sorry. */ + pthread_mutex_unlock(&buf_lock); + return; + } + + while (in_buf.c_str()[0] != '\r') { + int nlofs = in_buf.find("\r\n"); + std::string line = in_buf.substr(0, nlofs); + in_buf.erase(0, nlofs + 2); + + int spofs = line.find(' '); + std::string cmd = line.substr(0, spofs); + line.erase(0, spofs + 1); + + if (!cmd.compare("move_dir")) { + int x = 0, y = 0; + sscanf(line.c_str(), "%d %d", &x, &y); + agent->move_dir(x, y); + } else { + std::cout << "unknown line " << cmd << " " << line << " ...\n"; + } + } + in_buf.erase(0, 2); + + pthread_mutex_unlock(&buf_lock); +} + void connection::cancel(void) { @@ -69,7 +102,26 @@ connection::thread_loop(void) pthread_mutex_unlock(&buf_lock); } - /* TODO: The reading. ;-) */ + struct timeval tv; + tv.tv_sec = 0; tv.tv_usec = 0; + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + while (select(fd + 1, &rfds, NULL, NULL, &tv)) { + char cbuf[1024]; + len = read(fd, cbuf, sizeof(cbuf)); + if (len < 0) { + error = true; + } else { + bool want_moar = false; + pthread_mutex_lock(&buf_lock); + in_buf.append(cbuf, len); + want_moar = (in_buf.find("\r\n\r\n") == std::string::npos); + pthread_mutex_unlock(&buf_lock); + if (!want_moar) + break; + } + } usleep(10000); // XXX: Signal-oriented instead. } diff --git a/connection.h b/connection.h index 272c517..b956ac9 100644 --- a/connection.h +++ b/connection.h @@ -8,6 +8,8 @@ #include "map.h" +class agent; + class connection { public: int fd; @@ -25,11 +27,12 @@ public: } void senses(int tick_id, char around[4]); + void actions(class agent *); void cancel(void); private: - std::string out_buf; + std::string out_buf, in_buf; pthread_mutex_t buf_lock; pthread_cond_t cancel_cond; diff --git a/main.cc b/main.cc index 51c914e..9683852 100644 --- a/main.cc +++ b/main.cc @@ -69,6 +69,11 @@ next_agent: agents.push_back(new class agent(agents.size(), map.agent_startpos(), conn)); } + /* Collect and take actions. */ + + for (std::list::iterator agent = agents.begin(); agent != agents.end(); agent++) + (*agent)->on_action_takes(); + /* Run on_tick everywhere. */ map.on_tick();