GtkTextBuffer *message_buffer;
GtkWidget *message_view;
GtkWidget *command_entry;
+ GtkTextIter message_iter;
} grr_game_t;
static int
-do_gui (grr_game_t *game);
+grr_game_start_gui (grr_game_t *game);
-void
-game_callback (gpointer data,
- gint fd,
- GdkInputCondition condition);
+static void
+grr_game_read_notices (grr_game_t *game);
+
+static GSource *
+grr_game_notices_source_new (grr_game_t *game);
int
main (int argc, char **argv)
args_t args;
rr_status_t status;
grr_game_t game;
+ GSource *source;
char *diagram;
game.board = rr_board_create (16, 16);
- gdk_input_add (rr_client_fd (game.client),
- GDK_INPUT_READ,
- game_callback,
- &game);
+ source = grr_game_notices_source_new (&game);
+ g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+ g_source_attach (source, NULL);
+ g_source_unref (source);
rr_client_show (game.client, &diagram);
rr_board_parse (game.board, diagram);
free (diagram);
- return do_gui (&game);
+ return grr_game_start_gui (&game);
+}
+
+typedef struct _GrrNoticeSource {
+ GSource source;
+ grr_game_t *game;
+} GrrNoticeSource;
+
+static gboolean
+grr_game_notices_prepare (GSource *source,
+ gint *timeout)
+{
+ GrrNoticeSource *src = (GrrNoticeSource*)source;
+ grr_game_t *game = src->game;
+ gboolean retval;
+
+ GDK_THREADS_ENTER ();
+ *timeout = -1;
+ retval = rr_client_notice_pending (game->client);
+ GDK_THREADS_LEAVE ();
+
+ return retval;
+}
+
+static gboolean
+grr_game_notices_check (GSource *source)
+{
+ GrrNoticeSource *src = (GrrNoticeSource*)source;
+ grr_game_t *game = src->game;
+ gboolean retval;
+
+ GDK_THREADS_ENTER ();
+ retval = rr_client_notice_pending (game->client);
+ GDK_THREADS_LEAVE ();
+
+ return retval;
+}
+
+static gboolean
+grr_game_notices_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GrrNoticeSource *src = (GrrNoticeSource*)source;
+ grr_game_t *game = src->game;
+
+ grr_game_read_notices (game);
+
+ return TRUE;
+}
+
+static GSourceFuncs game_notices_funcs = {
+ grr_game_notices_prepare,
+ grr_game_notices_check,
+ grr_game_notices_dispatch,
+ NULL
+};
+
+static GSource *
+grr_game_notices_source_new (grr_game_t *game)
+{
+ GSource *source = g_source_new (&game_notices_funcs, sizeof (GrrNoticeSource));
+ GrrNoticeSource *src = (GrrNoticeSource*)source;
+ src->game = game;
+ return source;
}
-void
-game_callback (gpointer data,
- gint fd,
- GdkInputCondition condition)
+static void
+grr_game_read_notices (grr_game_t *game)
{
- grr_game_t *game = data;
rr_board_t *board = game->board;
rr_status_t status;
char **notice_s;
rr_notice_t *notice;
+ int i;
while (rr_client_notice_pending (game->client)) {
status = rr_client_next_notice (game->client, ¬ice_s);
gtk_exit (1);
return;
}
+ for (i=0; notice_s[i]; i++) {
+ gtk_text_buffer_insert_at_cursor (game->message_buffer, notice_s[i], -1);
+ gtk_text_buffer_insert_at_cursor (game->message_buffer, " ", -1);
+ }
+ gtk_text_buffer_insert_at_cursor (game->message_buffer, "\n", -1);
+ gtk_text_buffer_get_iter_at_offset (game->message_buffer,
+ &game->message_iter,
+ -1);
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (game->message_view),
+ &game->message_iter,
+ 0.0, FALSE, 0.0, 0.0);
+
notice = rr_client_parse_notice (game->client, notice_s);
+ if (notice == NULL) {
+ int i;
+ fprintf (stderr, "Failed to parse notice: ");
+ for (i=0; notice_s[i]; i++)
+ fprintf (stderr, " %s", notice_s[i]);
+ fprintf (stderr, "\n");
+ return;
+ }
+
switch (notice->type) {
case RR_NOTICE_USER:
case RR_NOTICE_QUIT:
case RR_NOTICE_DISPOSE:
case RR_NOTICE_MESSAGE:
case RR_NOTICE_GAMESTATE:
- case RR_NOTICE_TURN:
case RR_NOTICE_JOIN:
case RR_NOTICE_WATCH:
case RR_NOTICE_PART:
case RR_NOTICE_RESET:
case RR_NOTICE_SCORE:
case RR_NOTICE_ACTIVATE:
- /* Ignore these requests */
+ /* XXX: Need to actually handle many of these. */
+ fprintf (stderr, "Warning: Ignoring notice of type %d\n", notice->type);
break;
case RR_NOTICE_POSITION:
rr_board_position (board, notice->u.position.robot,
notice->u.position.x, notice->u.position.y);
gtk_widget_queue_draw (GTK_WIDGET (game->window));
break;
+ case RR_NOTICE_TURN:
+ rr_board_set_goal_target (board, notice->u.target);
+ gtk_widget_queue_draw (GTK_WIDGET (game->window));
+ break;
}
free (notice);
}
}
-void
-command_callback (GtkWidget *widget,
- grr_game_t *game)
+static void
+grr_game_entry_callback (GtkWidget *widget,
+ grr_game_t *game)
{
+ rr_status_t status;
const gchar *entry_text;
char **response;
+ int i;
- entry_text = gtk_entry_get_text (GTK_ENTRY (widget));
- rr_client_request (game->client, entry_text, &response);
- gtk_entry_set_text (GTK_ENTRY (widget), "");
- gtk_text_buffer_insert_at_cursor (game->message_buffer, entry_text, -1);
+ entry_text = gtk_entry_get_text (GTK_ENTRY (game->command_entry));
+
+ status = rr_client_request (game->client, entry_text, &response);
+ if (status) {
+ gtk_text_buffer_insert_at_cursor (game->message_buffer,
+ "ERROR: ", -1);
+ gtk_text_buffer_insert_at_cursor (game->message_buffer,
+ rr_status_str (status), -1);
+ gtk_text_buffer_insert_at_cursor (game->message_buffer,
+ "\n", -1);
+ } else {
+ for (i=0; response[i]; i++) {
+ gtk_text_buffer_insert_at_cursor (game->message_buffer,
+ response[i], -1);
+ gtk_text_buffer_insert_at_cursor (game->message_buffer,
+ " ", -1);
+ }
+ gtk_text_buffer_insert_at_cursor (game->message_buffer, "\n", -1);
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (game->command_entry), "");
/* XXX: Huh? Why is this triggering valgrind?
free (response);
}
static int
-do_gui (grr_game_t *game)
+grr_game_start_gui (grr_game_t *game)
{
GtkWidget *board_frame;
GtkWidget *vpaned;
G_CALLBACK (exit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
- vpaned = gtk_vpaned_new ();
- gtk_container_set_border_width (GTK_CONTAINER (vpaned), 5);
- gtk_container_add (GTK_CONTAINER (window), vpaned);
+ vbox = gtk_vbox_new (FALSE, 1);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
{
- board_frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
- gtk_paned_pack1 (GTK_PANED (vpaned), board_frame, TRUE, TRUE);
- {
- game->board_view = grr_board_view_new (game->board);
+ game->board_view = grr_board_view_new (game->board);
+ grr_board_view_set_client (GRR_BOARD_VIEW (game->board_view), game->client);
+ game->message_buffer = gtk_text_buffer_new (NULL);
+ game->message_view = gtk_text_view_new_with_buffer (game->message_buffer);
+ game->command_entry = gtk_entry_new ();
- gtk_container_add (GTK_CONTAINER (board_frame), game->board_view);
- gtk_widget_show (game->board_view);
- }
- gtk_widget_show (board_frame);
-
- vbox = gtk_vbox_new (FALSE, 1);
- gtk_paned_pack2 (GTK_PANED (vpaned), vbox, FALSE, TRUE);
+ vpaned = gtk_vpaned_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (vpaned), 0);
+ gtk_box_pack_start (GTK_BOX (vbox), vpaned,
+ TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (vbox), vpaned);
{
+ board_frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
+ gtk_paned_pack1 (GTK_PANED (vpaned), board_frame, TRUE, TRUE);
+ {
+ gtk_container_add (GTK_CONTAINER (board_frame), game->board_view);
+ gtk_widget_show (game->board_view);
+ }
+ gtk_widget_show (board_frame);
+
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (vbox), sw);
+ gtk_paned_pack2 (GTK_PANED (vpaned), sw, FALSE, TRUE);
+ {
+ message_view = game->message_view;
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (message_view), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (message_view), FALSE);
+ gtk_container_add (GTK_CONTAINER (sw), message_view);
+ gtk_widget_show (message_view);
+ }
gtk_widget_show (sw);
-
- game->message_buffer = gtk_text_buffer_new (NULL);
- game->message_view = gtk_text_view_new_with_buffer (game->message_buffer);
- message_view = game->message_view;
- gtk_text_view_set_editable (GTK_TEXT_VIEW (message_view), FALSE);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (message_view), FALSE);
- gtk_container_add (GTK_CONTAINER (sw), message_view);
- gtk_widget_show (message_view);
-
- game->command_entry = gtk_entry_new ();
- command_entry = game->command_entry;
- gtk_container_add (GTK_CONTAINER (vbox), command_entry);
- gtk_widget_show (command_entry);
- g_signal_connect (G_OBJECT (command_entry), "activate",
- G_CALLBACK (command_callback),
- (gpointer) game);
}
- gtk_widget_show (vbox);
+ gtk_widget_show (vpaned);
+
+ command_entry = game->command_entry;
+ gtk_box_pack_end (GTK_BOX (vbox), command_entry,
+ FALSE, FALSE, 0);
+ gtk_widget_show (command_entry);
+ g_signal_connect (G_OBJECT (command_entry), "activate",
+ G_CALLBACK (grr_game_entry_callback),
+ (gpointer) game);
}
- gtk_widget_show (vpaned);
+ gtk_widget_show (vbox);
gtk_widget_show (window);