From 8ae6051e97f728569c526d5e53fa195bd7ddac49 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Thu, 8 Dec 2011 02:01:56 +0100 Subject: [PATCH] Support reconnecting to agents Agents do not die immediately on disconnect anymore. Instead, agent_id is sent at birth and can be sent during negotiation to attach to a disconnected agent. --- README | 19 ++++++++++++++++--- agent.cc | 1 - client/example.pl | 11 ++++++++--- connection.cc | 28 ++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/README b/README index 6dd7123..d637647 100644 --- a/README +++ b/README @@ -20,6 +20,9 @@ CRLF ("\r\n"), not just LF ("\n")! The following inputs (in no particular order) are supported: + agent_id + unique id of agent; may be sent only once at the beginning + (you can use it to reconnect to the same agent later) tick BUMP if received, the agent's move failed @@ -62,9 +65,10 @@ The following outputs are supported: energy required is proportional to phintensity -After connecting, the client specifies its desired attributes, -in the same format as in normal output (line-based, terminated -by empty line), but with these commands instead: +When new agent connects, the client first enters the "negotiation" +phase, specifying its desired attributes, in the same format as in +normal output (line-based, terminated by empty line), but with +these commands instead: move between 0 and 1, describing probability @@ -76,3 +80,12 @@ by empty line), but with these commands instead: In general, higher rate means higher energy maintenance of the appropriate actuators. + +Alternately, the client may send a single command in the negotiation +phase: + + agent_id + +If the id corresponds to a disconnected agent, the connection +is immediately attached to that agent. Combining this with other +negotiation commands is undefined. diff --git a/agent.cc b/agent.cc index da51732..43e6891 100644 --- a/agent.cc +++ b/agent.cc @@ -126,7 +126,6 @@ agent::on_action_takes(void) return; if (conn->error) { - if (!dead) die(); conn->cancel(); conn = NULL; return; diff --git a/client/example.pl b/client/example.pl index 6e852a5..e4abe45 100755 --- a/client/example.pl +++ b/client/example.pl @@ -143,9 +143,14 @@ $socket = IO::Socket::INET->new( print "[ii] connected\r\n"; # negotiate attributs -print $socket "move 1.0\r\n"; -print $socket "attack 1.0\r\n"; -print $socket "defense 1.0\r\n"; +if ($ARGV[1]) { + print "[ii] recovering agent $ARGV[1]\r\n"; + print $socket "agent_id $ARGV[1]\r\n"; +} else { + print $socket "move 1.0\r\n"; + print $socket "attack 1.0\r\n"; + print $socket "defense 1.0\r\n"; +} print $socket "\r\n"; print "[ii] agent created\r\n"; diff --git a/connection.cc b/connection.cc index e91f914..99cf31e 100644 --- a/connection.cc +++ b/connection.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -9,6 +10,7 @@ #include "agent.h" #include "connection.h" +#include "main.h" #define buf_incomplete(buf) \ (buf.find("\r\n") == std::string::npos || (buf.find("\r\n") > 0 && buf.find("\r\n\r\n") == std::string::npos)) @@ -120,6 +122,28 @@ connection::actions(class agent &agent) if (rate >= 0 && rate <= 1) agent.attr.defense = rate; + } else if (negotiation && !cmd.compare("agent_id")) { + int id = -1; + sscanf(line.c_str(), "%d", &id); + if (id < 0) { +bump_negot: + bump(); out_buf.append("\r\n"); + } else { + class agent *a2 = NULL; + for (std::list::iterator ai = agents.begin(); ai != agents.end(); ai++) { + if ((*ai)->id == id) { + a2 = *ai; + break; + } + } + if (!a2 || a2->conn || !a2->tile || (dynamic_cast (a2))) + goto bump_negot; + /* Round and round she goes, where she stops, nobody knows. */ + a2->conn = this; + agent.conn = NULL; + negotiation = false; + } + } else if (!negotiation && !cmd.compare("move_dir") && !(mask & 1)) { int x = 0, y = 0; sscanf(line.c_str(), "%d %d", &x, &y); @@ -154,6 +178,10 @@ connection::actions(class agent &agent) if (negotiation) { negotiation = false; agent.spawn(); + + std::stringstream s; + s << "agent_id " << agent.id << "\r\n"; + out_buf.append(s.str()); } pthread_mutex_unlock(&buf_lock);