[Commit]
librr/src rr.h,1.5,1.6 rr_board.c,1.6,1.7 rr_client.c,1.2,1.3
rr_strbuf.c,1.1,1.2 rr_string.c,1.1,1.2 rrint.h,1.4,1.5
Keith Packard
commit at keithp.com
Thu Jun 12 01:09:11 PDT 2003
- Previous message: [Commit] Xr/src xrgstate.c,1.36,1.37
- Next message: [Commit] rrserver dispatch.5c,1.24,1.25 games.5c,1.21,1.22
protocol,1.27,1.28 server.5c,1.12,1.13
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: keithp
Update of /local/src/CVS/librr/src
In directory home.keithp.com:/tmp/cvs-serv3291/src
Modified Files:
rr.h rr_board.c rr_client.c rr_strbuf.c rr_string.c rrint.h
Log Message:
added notices, eliminate threads
Index: rr.h
===================================================================
RCS file: /local/src/CVS/librr/src/rr.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- rr.h 11 Jun 2003 23:26:14 -0000 1.5
+++ rr.h 12 Jun 2003 07:09:09 -0000 1.6
@@ -143,6 +143,89 @@
RR_DIRECTION_SOUTH = RR_DIRECTION_DOWN
} rr_direction_t;
+typedef enum {
+ /* global game notices */
+ RR_NOTICE_USER,
+ RR_NOTICE_QUIT,
+ RR_NOTICE_GAME,
+ RR_NOTICE_DISPOSE,
+ RR_NOTICE_MESSAGE,
+ RR_NOTICE_GAMESTATE,
+ RR_NOTICE_TURN,
+ RR_NOTICE_JOIN,
+ RR_NOTICE_WATCH,
+ RR_NOTICE_PART,
+ /* bid notices */
+ RR_NOTICE_BID,
+ RR_NOTICE_REVOKE,
+ RR_NOTICE_TIMER,
+ RR_NOTICE_ABANDON,
+ RR_NOTICE_NOBID,
+ /* solving notices */
+ RR_NOTICE_ACTIVE,
+ RR_NOTICE_MOVE,
+ RR_NOTICE_UNDO,
+ RR_NOTICE_RESET,
+ RR_NOTICE_POSITION,
+ RR_NOTICE_SCORE,
+ /* user notices */
+ RR_NOTICE_ACTIVATE
+} rr_notice_type_t;
+
+typedef enum {
+ RR_GAMESTATE_NEW,
+ RR_GAMESTATE_BID,
+ RR_GAMESTATE_SHOW,
+ RR_GAMESTATE_DONE,
+} rr_gamestate_t;
+
+typedef struct {
+ rr_notice_type_t type;
+ union {
+
+ /*
+ * USER, QUIT, JOIN, WATCH, PART, REVOKE,
+ * ABANDON, NOBID, GAME, DISPOSE
+ */
+ char *string;
+
+ /* MESSAGE */
+ struct {
+ char *username;
+ char *text;
+ } message;
+
+ /* GAMESTATE */
+ rr_gamestate_t gamestate;
+
+ /* TURN */
+ rr_target_t target;
+
+ /* BID, ACTIVE, SCORE */
+ struct {
+ char *username;
+ int number;
+ } bid;
+
+ /* TIME, ACTIVATE */
+ int number;
+
+ /* MOVE */
+ struct {
+ int count;
+ rr_robot_t robot;
+ rr_direction_t direction;
+ } move;
+
+ /* POSITION */
+ struct {
+ rr_robot_t robot;
+ int x, y;
+ } position;
+
+ } u;
+} rr_notice_t;
+
/* rr_board.c */
rr_board_t *
@@ -240,6 +323,9 @@
#define RR_CELL_GET_ROBOT(cell) ((cell) & RR_ROBOT_ANY)
#define RR_CELL_GET_TARGET(cell) ((cell) & RR_TARGET_ANY)
+int
+rr_board_notice (rr_board_t *board, const char **notify);
+
/* rr_cell.c */
int
@@ -267,32 +353,29 @@
const char *port,
const char *user);
-rr_board_t *
-rr_client_get_board (rr_client_t *client);
+int
+rr_client_fd (rr_client_t *client);
rr_status_t
rr_client_helo (rr_client_t *client, const char *user);
rr_status_t
-rr_client_games (rr_client_t *client, char **games);
+rr_client_games (rr_client_t *client, char ***games);
rr_status_t
rr_client_message (rr_client_t *client, const char *text);
rr_status_t
-rr_client_help (rr_client_t *client, char **help);
-
-rr_status_t
rr_client_quit (rr_client_t *client);
rr_status_t
-rr_client_players (rr_client_t *client, char **players);
+rr_client_players (rr_client_t *client, char ***players);
rr_status_t
-rr_client_watchers (rr_client_t *client, char **watchers);
+rr_client_watchers (rr_client_t *client, char ***watchers);
rr_status_t
-rr_client_gameinfo (rr_client_t *client, const char *game, char **info);
+rr_client_gameinfo (rr_client_t *client, const char *game, char ***info);
rr_status_t
rr_client_new (rr_client_t *client, const char *game);
@@ -307,10 +390,7 @@
rr_client_dispose (rr_client_t *client, const char *game);
rr_status_t
-rr_client_userinfo (rr_client_t *client, const char *user, char **info);
-
-rr_status_t
-rr_client_update_board (rr_client_t *client);
+rr_client_userinfo (rr_client_t *client, const char *user, char ***info);
rr_status_t
rr_client_show (rr_client_t *client, char **diagram);
@@ -342,6 +422,14 @@
void
rr_client_destroy (rr_client_t *client);
+int
+rr_client_notice_pending (rr_client_t *client);
+
+rr_status_t
+rr_client_next_notice (rr_client_t *client, char ***notice);
+
+rr_notice_t *
+rr_client_parse_notice (rr_client_t *client, char **notice);
/* rr.c */
const char *
Index: rr_board.c
===================================================================
RCS file: /local/src/CVS/librr/src/rr_board.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- rr_board.c 11 Jun 2003 23:26:14 -0000 1.6
+++ rr_board.c 12 Jun 2003 07:09:09 -0000 1.7
@@ -544,5 +544,3 @@
return RR_STATUS_SUCCESS;
}
-
-
Index: rr_client.c
===================================================================
RCS file: /local/src/CVS/librr/src/rr_client.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- rr_client.c 11 Jun 2003 23:26:14 -0000 1.2
+++ rr_client.c 12 Jun 2003 07:09:09 -0000 1.3
@@ -26,9 +26,11 @@
#include <unistd.h>
#include <sys/socket.h>
+#include <sys/poll.h>
#include <netdb.h>
#include <errno.h>
#include <ctype.h>
+#include <fcntl.h>
#include "rrint.h"
@@ -53,7 +55,7 @@
static rr_status_t
_rr_client_request (rr_client_t *client,
rr_cmd_t cmd, const char *arg,
- char **response);
+ char ***response);
static rr_status_t
_rr_client_send (rr_client_t *client, const char *fmt, ...);
@@ -62,7 +64,7 @@
_rr_client_send_va (rr_client_t *client, const char *fmt, va_list va);
static rr_status_t
-_rr_client_recv (rr_client_t *client, rr_cmd_t cmd, char **arg);
+_rr_client_recv (rr_client_t *client, rr_cmd_t cmd, char ***arg);
static rr_status_t
_rr_client_error_to_status (const char *error);
@@ -124,20 +126,10 @@
{
rr_status_t status;
- pthread_mutex_init (&client->mutex, NULL);
- pthread_cond_init (&client->response_cond, NULL);
-
- status = _rr_board_init (&client->board, 0, 0);
- if (status)
- return status;
-
status = _rr_client_connect (client, host, port);
if (status)
return status;
- pthread_create (&client->response_thread, NULL,
- _rr_client_response_thread_start, client);
-
status = rr_client_helo (client, user);
if (status) {
char *user_uniq;
@@ -166,18 +158,17 @@
static rr_status_t
_rr_client_fini (rr_client_t *client)
{
- pthread_mutex_lock (&client->mutex);
-
- _rr_board_fini (&client->board);
-
_rr_client_disconnect (client);
- pthread_cond_destroy (&client->response_cond);
- pthread_mutex_unlock (&client->mutex);
-
return RR_STATUS_SUCCESS;
}
+int
+rr_client_fd (rr_client_t *client)
+{
+ return client->sock;
+}
+
void
rr_client_destroy (rr_client_t *client)
{
@@ -212,6 +203,8 @@
if (err) {
return RR_STATUS_CONNECT_ERROR;
}
+ fcntl (client->sock, F_SETFL,
+ fcntl (client->sock, F_GETFL, 0) | O_NONBLOCK);
freeaddrinfo (addr);
@@ -229,25 +222,90 @@
return RR_STATUS_SUCCESS;
}
-/* XXX: Might want to add a realistically sized buffered read here */
static rr_status_t
-_rr_client_read_char (rr_client_t *client, char *c)
+_rr_client_fill (rr_client_t *client)
{
- char buf[1];
- int cnt;
+ int r = read (client->sock, client->buf, RR_BUF_SIZE);
+ if (r > 0)
+ {
+ client->end = r;
+ client->ptr = 0;
+ return RR_STATUS_SUCCESS;
+ }
+ if (r == 0)
+ return RR_STATUS_EOF;
+ if (errno == EWOULDBLOCK)
+ {
+ client->end = 0;
+ client->ptr = 0;
+ return RR_STATUS_SUCCESS;
+ }
+ return RR_STATUS_IO_ERROR;
+}
- while (1) {
- cnt = read (client->sock, &buf, 1);
- if (cnt == 1) {
- *c = buf[0];
- return RR_STATUS_SUCCESS;
- } else if (cnt == 0)
- return RR_STATUS_EOF;
- else if (errno == EINTR || errno == EAGAIN)
- continue;
- else
- return RR_STATUS_IO_ERROR;
+static int
+_rr_client_poll (rr_client_t *client, int events, int timeout)
+{
+ struct pollfd p;
+ int r;
+
+ p.fd = client->sock;
+ p.events = events;
+ p.revents = 0;
+ for (;;)
+ {
+ r = poll (&p, 1, timeout);
+ if (r >= 0)
+ return r;
+ if (errno != EINTR && errno != EAGAIN)
+ return r;
+ }
+}
+
+static rr_status_t
+_rr_client_read_block (rr_client_t *client)
+{
+ if (_rr_client_poll (client, POLLIN, -1) < 0)
+ return RR_STATUS_IO_ERROR;
+ return RR_STATUS_SUCCESS;
+}
+
+static rr_status_t
+_rr_client_write_block (rr_client_t *client)
+{
+ if (_rr_client_poll (client, POLLOUT, -1) < 0)
+ return RR_STATUS_IO_ERROR;
+ return RR_STATUS_SUCCESS;
+}
+
+static int
+_rr_client_readable (rr_client_t *client)
+{
+ if (client->ptr < client->end)
+ return 1;
+ if (_rr_client_poll (client, POLLIN, 0) != 0)
+ return 1;
+ return 0;
+}
+
+static rr_status_t
+_rr_client_read_char (rr_client_t *client, char *c)
+{
+ rr_status_t status;
+ while (client->ptr >= client->end)
+ {
+ status = _rr_client_fill (client);
+ if (status != RR_STATUS_SUCCESS)
+ return status;
+ if (client->ptr >= client->end)
+ {
+ status = _rr_client_read_block (client);
+ if (status != RR_STATUS_SUCCESS)
+ return status;
+ }
}
+ *c = client->buf[client->ptr++];
+ return RR_STATUS_SUCCESS;
}
static rr_status_t
@@ -313,87 +371,63 @@
}
static rr_status_t
-_rr_client_read_word (rr_client_t *client, char **str, char *delimiter)
-{
- rr_status_t status = RR_STATUS_SUCCESS;
- rr_strbuf_t strbuf;
-
- _rr_strbuf_init (&strbuf);
-
- status = _rr_client_read_word_strbuf (client, &strbuf, delimiter);
-
- *str = _rr_strbuf_fini (&strbuf);
-
- return status;
-}
-
-static rr_status_t
-_rr_client_read_line (rr_client_t *client, char **str)
+_rr_client_read_line (rr_client_t *client, char ***strstr)
{
rr_status_t status = RR_STATUS_SUCCESS;
- rr_strbuf_t strbuf;
+ rr_strstrbuf_t strstrbuf;
char delimiter;
- _rr_strbuf_init (&strbuf);
+ _rr_strstrbuf_init (&strstrbuf);
while (1) {
+ rr_strbuf_t strbuf;
+ _rr_strbuf_init (&strbuf);
status = _rr_client_read_word_strbuf (client,
&strbuf,
&delimiter);
+ _rr_strstrbuf_append (&strstrbuf, _rr_strbuf_str (&strbuf));
+ _rr_strbuf_fini (&strbuf);
if (status || delimiter == '\n')
break;
- _rr_strbuf_append (&strbuf, ' ');
};
- *str = _rr_strbuf_fini (&strbuf);
+ *strstr = _rr_strstrbuf_fini (&strstrbuf);
return status;
}
-static void *
-_rr_client_response_thread_start (void *closure)
+/* return a reply */
+static rr_status_t
+_rr_client_queue_notice (rr_client_t *client, char **arg)
{
- rr_status_t status;
- rr_client_t *client = closure;
- char *response, *arg;
- char delimiter;
-
- while (1) {
- status = _rr_client_read_word (client, &response, &delimiter);
- if (status)
- break;
- if (delimiter == '\n') {
- arg = strdup("");
- if (arg == NULL)
- return (void *) RR_STATUS_NO_MEMORY;
- } else {
- status = _rr_client_read_line (client, &arg);
- if (status)
- break;
- }
-
- if (strcmp (response, "NOTICE") == 0) {
- /* XXX: Need to handle these. */
- fprintf (stderr, "Not handling response: %s %s\n", response, arg);
- free (response);
- free (arg);
- continue;
- }
-
- pthread_mutex_lock (&client->mutex);
- client->response = response;
- client->arg = arg;
- pthread_mutex_unlock (&client->mutex);
- pthread_cond_signal (&client->response_cond);
+ rr_notice_elt_t *e = malloc (sizeof (rr_notice_elt_t)), **p;
+ if (!e) {
+ free (arg);
+ return RR_STATUS_NO_MEMORY;
}
-
- return (void *) RR_STATUS_SUCCESS;
+ for (p = &client->notice_queue; *p; p = &(*p)->next);
+ e->notice = arg;
+ e->next = 0;
+ *p = e;
}
-rr_board_t *
-rr_client_get_board (rr_client_t *client)
+static rr_status_t
+_rr_client_reply (rr_client_t *client, char ***response)
{
- return &client->board;
+ while (1) {
+ char **arg;
+ rr_status_t status = _rr_client_read_line (client, &arg);
+ if (status != RR_STATUS_SUCCESS)
+ return status;
+
+ if (arg[0] && strcmp (arg[0], "NOTICE") == 0) {
+ _rr_strings_cdr (arg);
+ _rr_client_queue_notice (client, arg);
+ } else {
+ *response = arg;
+ return RR_STATUS_SUCCESS;
+ }
+ }
}
rr_status_t
@@ -403,7 +437,7 @@
}
rr_status_t
-rr_client_games (rr_client_t *client, char **games)
+rr_client_games (rr_client_t *client, char ***games)
{
return _rr_client_request (client, RR_CMD_GAMES, NULL, games);
}
@@ -415,31 +449,25 @@
}
rr_status_t
-rr_client_help (rr_client_t *client, char **help)
-{
- return _rr_client_request (client, RR_CMD_HELP, NULL, help);
-}
-
-rr_status_t
rr_client_quit (rr_client_t *client)
{
return _rr_client_request (client, RR_CMD_QUIT, NULL, NULL);
}
rr_status_t
-rr_client_players (rr_client_t *client, char **players)
+rr_client_players (rr_client_t *client, char ***players)
{
return _rr_client_request (client, RR_CMD_PLAYERS, NULL, players);
}
rr_status_t
-rr_client_watchers (rr_client_t *client, char **watchers)
+rr_client_watchers (rr_client_t *client, char ***watchers)
{
return _rr_client_request (client, RR_CMD_WATCHERS, NULL, watchers);
}
rr_status_t
-rr_client_gameinfo (rr_client_t *client, const char *game, char **info)
+rr_client_gameinfo (rr_client_t *client, const char *game, char ***info)
{
return _rr_client_request (client, RR_CMD_GAMEINFO, game, info);
}
@@ -469,39 +497,23 @@
}
rr_status_t
-rr_client_userinfo (rr_client_t *client, const char *user, char **info)
+rr_client_userinfo (rr_client_t *client, const char *user, char ***info)
{
return _rr_client_request (client, RR_CMD_USERINFO, user, info);
}
rr_status_t
-rr_client_update_board (rr_client_t *client)
-{
- rr_status_t status;
- char *diagram;
-
- status = rr_client_show (client, &diagram);
- if (diagram)
- free (diagram);
- if (status)
- return status;
-
- return RR_STATUS_SUCCESS;
-}
-
-rr_status_t
rr_client_show (rr_client_t *client, char **diagram)
{
rr_status_t status;
+ char **args;
- status = _rr_client_request (client, RR_CMD_SHOW, NULL, diagram);
- if (status)
- return status;
-
- status = rr_board_parse (&client->board, *diagram);
+ status = _rr_client_request (client, RR_CMD_SHOW, NULL, &args);
if (status)
return status;
+ *diagram = _rr_string_dup (args[0]);
+ free (args);
return RR_STATUS_SUCCESS;
}
@@ -556,13 +568,11 @@
static rr_status_t
_rr_client_request (rr_client_t *client,
rr_cmd_t cmd, const char *arg,
- char **response)
+ char ***response)
{
rr_status_t status = RR_STATUS_SUCCESS;
char *cmd_str;
- char *recv;
-
- pthread_mutex_lock (&client->mutex);
+ char **recv;
cmd_str = RR_CLIENT_COMMAND[cmd].arg;
@@ -583,7 +593,6 @@
free (recv);
DONE:
- pthread_mutex_unlock (&client->mutex);
return status;
}
@@ -606,7 +615,9 @@
static rr_status_t
_rr_client_send_va (rr_client_t *client, const char *fmt, va_list va)
{
- char *msg;
+ char *msg, *m;
+ int len, r;
+ rr_status_t status = RR_STATUS_SUCCESS;
if (client->sock == -1)
return RR_STATUS_NOT_CONNECTED;
@@ -615,10 +626,29 @@
if (msg == NULL)
return RR_STATUS_NO_MEMORY;
- write (client->sock, msg, strlen (msg));
+ len = strlen (msg);
+ m = msg;
+ while (len)
+ {
+ r = write (client->sock, m, len);
+ if (r > 0)
+ {
+ m += r;
+ len -= r;
+ }
+ else if (r == 0 ||
+ (errno == EWOULDBLOCK && errno != EAGAIN))
+ {
+ status = RR_STATUS_IO_ERROR;
+ break;
+ }
+ else
+ _rr_client_write_block (client);
+ }
+
free (msg);
- return RR_STATUS_SUCCESS;
+ return status;
}
static rr_status_t
@@ -667,29 +697,323 @@
}
/* NOTE: Called with client->mutex held */
static rr_status_t
-_rr_client_recv (rr_client_t *client, rr_cmd_t cmd, char **arg)
+_rr_client_recv (rr_client_t *client, rr_cmd_t cmd, char ***argp)
{
- rr_status_t status;
-
- pthread_cond_wait (&client->response_cond, &client->mutex);
-
- if (strcmp (client->response, RR_CLIENT_COMMAND[cmd].arg) == 0) {
- *arg = client->arg;
+ char **arg;
+ rr_status_t status = _rr_client_reply (client, &arg);
+
+ if (arg[0] && strcmp (arg[0], RR_CLIENT_COMMAND[cmd].arg) == 0) {
status = RR_STATUS_SUCCESS;
- } else if (strcmp (client->response, "ERROR") == 0) {
- *arg = NULL;
- status = _rr_client_error_to_status (client->arg);
- free (client->arg);
- client->arg = NULL;
+ _rr_strings_cdr (arg);
+ *argp = arg;
+ } else if (arg[0] && strcmp (arg[0], "ERROR") == 0) {
+ status = _rr_client_error_to_status (arg[1]);
+ free (arg);
+ *argp = 0;
} else {
- fprintf (stderr, "Unexpected response: %s %s\n",
- client->response, client->arg);
status = RR_STATUS_PROTOCOL_ERROR;
+ fprintf (stderr, "Unexpected response: %s\n",
+ arg[0]);
+ free (arg);
+ *argp = 0;
}
+ return status;
+}
- free (client->response);
- client->response = NULL;
+int
+rr_client_notice_pending (rr_client_t *client)
+{
+ if (client->notice_queue)
+ return 1;
+ if (_rr_client_readable (client))
+ return 1;
+ return 0;
+}
- return status;
+rr_status_t
+rr_client_next_notice (rr_client_t *client, char ***notice)
+{
+ rr_notice_elt_t *elt = client->notice_queue;
+ rr_status_t status;
+ char **arg;
+ if (elt)
+ {
+ client->notice_queue = elt->next;
+ *notice = elt->notice;
+ free (elt);
+ return RR_STATUS_SUCCESS;
+ }
+ status = _rr_client_read_line (client, &arg);
+ if (status != RR_STATUS_SUCCESS)
+ return status;
+ _rr_strings_cdr (arg);
+ *notice = arg;
+ return RR_STATUS_SUCCESS;
+}
+
+static rr_notice_t *
+_rr_notice_create (rr_notice_type_t type, int extra)
+{
+ rr_notice_t *n = malloc (sizeof (rr_notice_t) + extra);
+ if (!n)
+ return 0;
+ memset (n, '\0', sizeof (rr_notice_t) + extra);
+ n->type = type;
+ return n;
+}
+
+static rr_robot_t
+_rr_parse_robot (char *name)
+{
+ static struct {
+ char *name;
+ rr_robot_t robot;
+ } robots[] = {
+ { "red", RR_ROBOT_RED },
+ { "yellow", RR_ROBOT_YELLOW },
+ { "green", RR_ROBOT_GREEN },
+ { "blue", RR_ROBOT_BLUE },
+ };
+#define RR_NUM_ROBOTS (sizeof (robots) / sizeof (robots[0]))
+ int i;
+
+ for (i = 0; i < RR_NUM_ROBOTS; i++)
+ if (!strcmp (robots[i].name, name))
+ return robots[i].robot;
+ return robots[0].robot;
+}
+
+static rr_target_color_t
+_rr_parse_color (char *name)
+{
+ static struct {
+ char *name;
+ rr_target_color_t color;
+ } colors[] = {
+ { "red", RR_TARGET_RED },
+ { "yellow", RR_TARGET_YELLOW },
+ { "green", RR_TARGET_GREEN },
+ { "blue", RR_TARGET_BLUE },
+ { "whirl", RR_TARGET_MULTI },
+ };
+#define RR_NUM_COLORS (sizeof (colors) / sizeof (colors[0]))
+ int i;
+
+ for (i = 0; i < RR_NUM_COLORS; i++)
+ if (!strcmp (colors[i].name, name))
+ return colors[i].color;
+ return colors[0].color;
+}
+
+static rr_target_shape_t
+_rr_parse_shape (char *name)
+{
+ static struct {
+ char *name;
+ rr_target_shape_t shape;
+ } shapes[] = {
+ { "circle", RR_TARGET_CIRCLE },
+ { "octagon", RR_TARGET_OCTAGON },
+ { "square", RR_TARGET_SQUARE },
+ { "triangle", RR_TARGET_TRIANGLE },
+ { "whirl", RR_TARGET_SHAPE_WHIRL },
+ };
+#define RR_NUM_SHAPES (sizeof (shapes) / sizeof (shapes[0]))
+ int i;
+
+ for (i = 0; i < RR_NUM_SHAPES; i++)
+ if (!strcmp (shapes[i].name, name))
+ return shapes[i].shape;
+ return shapes[0].shape;
}
+static rr_direction_t
+_rr_parse_direction (char *name)
+{
+ static struct {
+ char *name;
+ rr_direction_t direction;
+ } directions[] = {
+ { "north", RR_DIRECTION_NORTH },
+ { "east", RR_DIRECTION_EAST },
+ { "south", RR_DIRECTION_SOUTH },
+ { "west", RR_DIRECTION_WEST },
+ };
+#define RR_NUM_DIRECTIONS (sizeof (directions) / sizeof (directions[0]))
+ int i;
+
+ for (i = 0; i < RR_NUM_DIRECTIONS; i++)
+ if (!strcmp (directions[i].name, name))
+ return directions[i].direction;
+ return directions[0].direction;
+}
+
+static int
+_rr_parse_int (char *n)
+{
+ return atoi (n);
+}
+
+static rr_notice_t *
+_rr_notice_void (rr_notice_type_t type, char **notice)
+{
+ return _rr_notice_create (type, 0);
+}
+
+static rr_notice_t *
+_rr_notice_string (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, strlen (notice[1]) + 1);
+ if (!n)
+ return 0;
+ n->u.string = (char *) (n + 1);
+ strcpy (n->u.string, notice[1]);
+ return n;
+}
+
+static rr_notice_t *
+_rr_notice_message (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type,
+ strlen (notice[1]) + 1 +
+ strlen (notice[2]) + 1);
+ if (!n)
+ return 0;
+ n->u.message.username = (char *) (n + 1);
+ n->u.message.text = n->u.message.username + strlen (notice[1]) + 1;
+ strcpy (n->u.message.username, notice[1]);
+ strcpy (n->u.message.text, notice[2]);
+ return n;
+}
+
+static rr_notice_t *
+_rr_notice_gamestate (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, 0);
+ static struct {
+ char *name;
+ rr_gamestate_t gamestate;
+ } gamestates[] = {
+ "NEW", RR_GAMESTATE_NEW,
+ "BID", RR_GAMESTATE_BID,
+ "SHOW", RR_GAMESTATE_SHOW,
+ "DONE", RR_GAMESTATE_DONE
+ };
+
+#define RR_NUM_GAMESTATES (sizeof (gamestates) / sizeof (gamestates[0]))
+ int i;
+
+ if (!n)
+ return 0;
+ for (i = 0; i < RR_NUM_GAMESTATES; i++)
+ if (!strcmp (notice[1], gamestates[i].name))
+ {
+ n->u.gamestate = gamestates[i].gamestate;
+ return n;
+ }
+ free (n);
+ return 0;
+}
+
+static rr_notice_t *
+_rr_notice_target (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, 0);
+ if (!n)
+ return 0;
+ n->u.target = _rr_parse_color (notice[1]) | _rr_parse_shape (notice[2]);
+ return n;
+}
+
+static rr_notice_t *
+_rr_notice_bid (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, strlen (notice[1]) + 1);
+ if (!n)
+ return 0;
+ n->u.bid.username = (char *) (n + 1);
+ strcpy (n->u.bid.username, notice[1]);
+ n->u.bid.number = _rr_parse_int(notice[2]);
+ return n;
+}
+
+static rr_notice_t *
+_rr_notice_number (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, 0);
+ if (!n)
+ return 0;
+ n->u.number = _rr_parse_int(notice[1]);
+ return n;
+}
+
+static rr_notice_t *
+_rr_notice_move (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, 0);
+ if (!n)
+ return 0;
+ n->u.move.count = _rr_parse_int(notice[1]);
+ n->u.move.robot = _rr_parse_robot(notice[2]);
+ n->u.move.direction = _rr_parse_direction (notice[3]);
+ return n;
+}
+
+static rr_notice_t *
+_rr_notice_position (rr_notice_type_t type, char **notice)
+{
+ rr_notice_t *n = _rr_notice_create (type, 0);
+ if (!n)
+ return 0;
+ n->u.position.robot = _rr_parse_robot (notice[1]);
+ n->u.position.x = _rr_parse_int (notice[2]);
+ n->u.position.y = _rr_parse_int (notice[3]);
+ return n;
+}
+
+static struct {
+ char *name;
+ rr_notice_type_t type;
+ rr_notice_t *(*func) (rr_notice_type_t, char **);
+} notices[] = {
+ /* global game notices */
+ { "USER", RR_NOTICE_USER, _rr_notice_string },
+ { "QUIT", RR_NOTICE_QUIT, _rr_notice_void },
+ { "GAME", RR_NOTICE_GAME, _rr_notice_string },
+ { "DISPOSE", RR_NOTICE_DISPOSE, _rr_notice_void},
+ { "MESSAGE", RR_NOTICE_MESSAGE, _rr_notice_message },
+ { "GAMESTATE", RR_NOTICE_GAMESTATE, _rr_notice_gamestate },
+ { "TURN", RR_NOTICE_TURN, _rr_notice_target },
+ { "GAME", RR_NOTICE_GAME, _rr_notice_string },
+ { "JOIN", RR_NOTICE_JOIN, _rr_notice_string },
+ { "WATCH", RR_NOTICE_WATCH, _rr_notice_string },
+ { "PART", RR_NOTICE_PART, _rr_notice_string },
+ /* bid notices */
+ { "BID", RR_NOTICE_BID, _rr_notice_bid },
+ { "REVOKE", RR_NOTICE_REVOKE, _rr_notice_string },
+ { "TIMER", RR_NOTICE_TIMER, _rr_notice_number },
+ { "ABANDON", RR_NOTICE_ABANDON, _rr_notice_string },
+ { "NOBID", RR_NOTICE_NOBID, _rr_notice_string },
+ /* solving notices */
+ { "ACTIVE", RR_NOTICE_ACTIVE, _rr_notice_bid },
+ { "MOVE", RR_NOTICE_MOVE, _rr_notice_move },
+ { "UNDO", RR_NOTICE_UNDO, _rr_notice_void },
+ { "RESET", RR_NOTICE_RESET, _rr_notice_void },
+ { "POSITION", RR_NOTICE_POSITION, _rr_notice_position },
+ { "SCORE", RR_NOTICE_SCORE, _rr_notice_bid },
+ /* user notices */
+ { "ACTIVATE", RR_NOTICE_ACTIVATE, _rr_notice_number }
+};
+
+#define NUM_NOTICES (sizeof (notices) / sizeof (notices[0]))
+
+rr_notice_t *
+rr_client_parse_notice (rr_client_t *client, char **notice)
+{
+ int i;
+
+ for (i = 0; i < NUM_NOTICES; i++)
+ if (!strcmp (notice[0], notices[i].name))
+ return (*notices[i].func) (notices[i].type, notice);
+ return 0;
+}
Index: rr_strbuf.c
===================================================================
RCS file: /local/src/CVS/librr/src/rr_strbuf.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- rr_strbuf.c 5 Jun 2003 14:32:42 -0000 1.1
+++ rr_strbuf.c 12 Jun 2003 07:09:09 -0000 1.2
@@ -37,7 +37,7 @@
}
char *
-_rr_strbuf_fini (rr_strbuf_t *buf)
+_rr_strbuf_str (rr_strbuf_t *buf)
{
char *str;
@@ -52,6 +52,16 @@
return str;
}
+void
+_rr_strbuf_fini (rr_strbuf_t *buf)
+{
+ if (buf->str)
+ free (buf->str);
+ buf->str = 0;
+ buf->size = 0;
+ buf->len = 0;
+}
+
#define RR_STRBUF_GROWTH 48
rr_status_t
_rr_strbuf_append (rr_strbuf_t *buf, char c)
@@ -72,3 +82,50 @@
return RR_STATUS_SUCCESS;
}
+rr_status_t
+_rr_strstrbuf_init (rr_strstrbuf_t *buf)
+{
+ _rr_strbuf_init (&buf->str);
+ buf->len = 0;
+ return RR_STATUS_SUCCESS;
+}
+
+char **
+_rr_strstrbuf_fini (rr_strstrbuf_t *buf)
+{
+ char **ret, *d, *s;
+ int i;
+
+ ret = (char **) malloc ((buf->len + 1) * (sizeof (char *)) +
+ buf->str.len + 1);
+ if (!ret)
+ return 0;
+ d = (char *) (ret + buf->len + 1);
+ s = buf->str.str;
+ for (i = 0; i < buf->len; i++)
+ {
+ int l;
+ ret[i] = d;
+ strcpy (d, s);
+ l = strlen (s);
+ d += l + 1;
+ s += l + 1;
+ }
+ ret[i] = 0;
+ _rr_strbuf_fini (&buf->str);
+ buf->len = 0;
+ return ret;
+}
+
+rr_status_t
+_rr_strstrbuf_append (rr_strstrbuf_t *buf, char *s)
+{
+ char c;
+ buf->len++;
+ do {
+ rr_status_t status = _rr_strbuf_append (&buf->str, c = *s++);
+ if (status != RR_STATUS_SUCCESS)
+ return status;
+ } while (c);
+ return RR_STATUS_SUCCESS;
+}
Index: rr_string.c
===================================================================
RCS file: /local/src/CVS/librr/src/rr_string.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- rr_string.c 5 Jun 2003 14:32:42 -0000 1.1
+++ rr_string.c 12 Jun 2003 07:09:09 -0000 1.2
@@ -69,3 +69,22 @@
*str = new_str;
}
}
+
+void
+_rr_strings_cdr (char **args)
+{
+ int l;
+
+ for (l = 0; args[l]; l++);
+ memmove (args, args + 1, l * sizeof (char *));
+}
+
+char *
+_rr_string_dup (char *s)
+{
+ char *r = malloc (strlen (s) + 1);
+ if (!r)
+ return 0;
+ strcpy (r, s);
+ return r;
+}
Index: rrint.h
===================================================================
RCS file: /local/src/CVS/librr/src/rrint.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- rrint.h 11 Jun 2003 23:26:14 -0000 1.4
+++ rrint.h 12 Jun 2003 07:09:09 -0000 1.5
@@ -32,7 +32,6 @@
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
-#include <pthread.h>
#include "rr.h"
@@ -101,17 +100,19 @@
char *arg;
} rr_command_t, rr_request_t, rr_response_t;
-struct rr_client {
- pthread_mutex_t mutex;
- pthread_t response_thread;
-
- char *response;
- char *arg;
- pthread_cond_t response_cond;
+typedef struct rr_notice_elt {
+ struct rr_notice_elt *next;
+ char **notice;
+} rr_notice_elt_t;
- rr_board_t board;
+#define RR_BUF_SIZE 1024
+struct rr_client {
int sock;
+ char buf[RR_BUF_SIZE];
+ int ptr;
+ int end;
+ rr_notice_elt_t *notice_queue;
};
typedef struct rr_strbuf {
@@ -120,6 +121,11 @@
int len;
} rr_strbuf_t;
+typedef struct rr_strstrbuf {
+ rr_strbuf_t str;
+ int len;
+} rr_strstrbuf_t;
+
/* rr.c */
char
_rr_robot_to_char (rr_robot_t robot);
@@ -176,11 +182,23 @@
_rr_strbuf_init (rr_strbuf_t *buf);
char *
+_rr_strbuf_str (rr_strbuf_t *buf);
+
+void
_rr_strbuf_fini (rr_strbuf_t *buf);
rr_status_t
_rr_strbuf_append (rr_strbuf_t *buf, char c);
+rr_status_t
+_rr_strstrbuf_init (rr_strstrbuf_t *buf);
+
+char **
+_rr_strstrbuf_fini (rr_strstrbuf_t *buf);
+
+rr_status_t
+_rr_strstrbuf_append (rr_strstrbuf_t *buf, char *s);
+
/* rr_string.c */
int
@@ -188,5 +206,11 @@
int
_rr_string_sprintf_alloc_va (char **str, const char *fmt, va_list ap);
+
+void
+_rr_strings_cdr (char **args);
+
+char *
+_rr_string_dup (char *str);
#endif
- Previous message: [Commit] Xr/src xrgstate.c,1.36,1.37
- Next message: [Commit] rrserver dispatch.5c,1.24,1.25 games.5c,1.21,1.22
protocol,1.27,1.28 server.5c,1.12,1.13
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Commit
mailing list