diff options
Diffstat (limited to 'glib/examples/statemachine/statemachine-client.c')
| -rw-r--r-- | glib/examples/statemachine/statemachine-client.c | 192 | 
1 files changed, 157 insertions, 35 deletions
| diff --git a/glib/examples/statemachine/statemachine-client.c b/glib/examples/statemachine/statemachine-client.c index 54c630ff..88b21847 100644 --- a/glib/examples/statemachine/statemachine-client.c +++ b/glib/examples/statemachine/statemachine-client.c @@ -59,8 +59,9 @@ typedef struct  {    char *name;    char *state; +  gdouble progress;    DBusGProxy *proxy; -  DBusGProxyCall *get_initial_state_call; +  DBusGProxyCall *get_progress_call;  } MachineInfo;  typedef struct @@ -91,6 +92,15 @@ proxy_to_iter (GtkTreeModel *model, DBusGProxy *proxy, GtkTreeIter *iter)  }  static void +signal_row_change (ClientState *state, GtkTreeIter *iter) +{ +  GtkTreePath *path; +  path = gtk_tree_model_get_path (state->store, iter); +  gtk_tree_model_row_changed (state->store, path, iter); +  gtk_tree_path_free (path); +} + +static void  get_machine_info_cb (DBusGProxy *proxy,  		     DBusGProxyCall *call,  		     gpointer data) @@ -115,13 +125,67 @@ get_machine_info_cb (DBusGProxy *proxy,    info->name = name;    g_free (info->state);    info->state = statename; -  { -    GtkTreePath *path; -    path = gtk_tree_model_get_path (state->store, &iter); -    gtk_tree_model_row_changed (state->store, path, &iter); -    gtk_tree_path_free (path); -  } -  info->get_initial_state_call = NULL; +  signal_row_change (state, &iter); +} + +static void +set_proxy_acquisition_progress (ClientState *state, +				DBusGProxy *proxy, +				double progress) +{ +  MachineInfo *info; +  GtkTreeIter iter; + +  if (!proxy_to_iter (state->store, proxy, &iter)) +    g_assert_not_reached (); +  gtk_tree_model_get (state->store, &iter, 0, &info, -1); + +  /* Ignore machines in unknown state */ +  if (!info->state) +    return; +   +  if (strcmp (info->state, "Acquired")) +    lose ("Got AcquisitionProgress signal in bad state %s", +	  info->state); + +  g_print ("Got acquisition progress change for %p (%s) to %f\n", proxy, info->name ? info->name : "(unknown)", progress); + +  info->progress = progress; + +  signal_row_change (state, &iter); +} + +static void +proxy_acquisition_changed_cb (DBusGProxy *proxy, +			      double progress, +			      gpointer user_data) +{ +  set_proxy_acquisition_progress (user_data, proxy, progress); +} + +static void +get_acquiring_progress_cb (DBusGProxy *proxy, +			   DBusGProxyCall *call, +			   gpointer user_data) +{ +  GError *error = NULL; +  MachineInfo *info; +  GtkTreeIter iter; +  ClientState *state = user_data; +  gdouble progress; + +  if (!proxy_to_iter (state->store, proxy, &iter)) +    g_assert_not_reached (); +  gtk_tree_model_get (state->store, &iter, 0, &info, -1); + +  g_assert (info->get_progress_call == call); + +  if (!dbus_g_proxy_end_call (proxy, call, &error, +			      G_TYPE_DOUBLE, &progress, G_TYPE_INVALID)) +    lose_gerror ("Failed to complete GetAcquiringProgress call", error); +  info->get_progress_call = NULL; + +  set_proxy_acquisition_progress (state, proxy, progress);  }  static void @@ -139,25 +203,27 @@ proxy_state_changed_cb (DBusGProxy *proxy,    g_print ("Got state change for %p (%s) to %s\n", proxy, info->name ? info->name : "(unknown)", statename); -  /* If we got a signal for the state, we shouldn't update -   * based on the (possibly stale) call -   */ -  if (info->get_initial_state_call != NULL) -    { -      g_print ("Cancelling outstanding GetInfo call for %p due to signal\n", proxy); -      dbus_g_proxy_cancel_call (proxy, info->get_initial_state_call); -      info->get_initial_state_call = NULL; -    } -    g_free (info->state);    info->state = g_strdup (statename); -  { -    GtkTreePath *path; -    path = gtk_tree_model_get_path (state->store, &iter); -    gtk_tree_model_row_changed (state->store, path, &iter); -    gtk_tree_path_free (path); -  } +  if (!strcmp (info->state, "Acquired")) +    { +      g_print ("Starting GetAcquiringProgress call for %p\n", info->proxy); +      if (info->get_progress_call != NULL) +	{ +	  dbus_g_proxy_cancel_call (info->proxy, info->get_progress_call); +	  info->get_progress_call = NULL; +	} +      info->get_progress_call =  +	dbus_g_proxy_begin_call (info->proxy, "GetAcquiringProgress", +				 get_acquiring_progress_cb, +				 state, NULL, +				 G_TYPE_INVALID); +    } +  else +    info->progress = 0.0; + +  signal_row_change (state, &iter);  }  static void @@ -172,6 +238,7 @@ add_machine (ClientState *state,    info = g_new0 (MachineInfo, 1);    info->name = g_strdup (name);    info->state = g_strdup (mstate); +  info->progress = 0.0;    info->proxy = dbus_g_proxy_new_for_name (state->bus,  					   "com.example.StateServer", @@ -181,14 +248,11 @@ add_machine (ClientState *state,    if (!info->state)      {        g_print ("Starting GetInfo call for %p\n", info->proxy); -      info->get_initial_state_call -	= dbus_g_proxy_begin_call (info->proxy, "GetInfo", -				   get_machine_info_cb, -				   state, NULL, -				   G_TYPE_INVALID); +      dbus_g_proxy_begin_call (info->proxy, "GetInfo", +			       get_machine_info_cb, +			       state, NULL, +			       G_TYPE_INVALID);      } -  else -    info->get_initial_state_call = NULL;    /* Watch for state changes */    dbus_g_proxy_add_signal (info->proxy, "StateChanged", @@ -200,6 +264,15 @@ add_machine (ClientState *state,  			       state,  			       NULL); +  dbus_g_proxy_add_signal (info->proxy, "AcquisitionProgress", +			   G_TYPE_DOUBLE, G_TYPE_INVALID); +   +  dbus_g_proxy_connect_signal (info->proxy, +			       "AcquisitionProgress",  +			       G_CALLBACK (proxy_acquisition_changed_cb), +			       state, +			       NULL); +    gtk_list_store_prepend (GTK_LIST_STORE (state->store), &iter);    gtk_list_store_set (GTK_LIST_STORE (state->store), &iter, 0, info, -1); @@ -306,6 +379,12 @@ do_a_state_change (ClientState *state)        g_print ("Sending Start request to machine %s\n", info->name);        dbus_g_proxy_call_no_reply (info->proxy, "Start", G_TYPE_INVALID);      } +  else if (!strcmp (info->state, "Loading")) +    { +       +      g_print ("Sending Reacquire request to machine %s\n", info->name); +      dbus_g_proxy_call_no_reply (info->proxy, "Reacquire", G_TYPE_INVALID); +    }    else      {        g_print ("Sending Shutdown request to machine %s\n", info->name); @@ -318,7 +397,7 @@ do_something_random_2 (gpointer data)  {    ClientState *state = data;    do_a_state_change (state); -  g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); +  g_timeout_add (g_random_int_range (2000, 5000), do_something_random_2, state);    return FALSE;  } @@ -328,12 +407,13 @@ do_something_random (gpointer data)    ClientState *state = data;    gint n_children; -  switch (g_random_int_range (0, 2)) +  switch (g_random_int_range (0, 3))      {      case 0:        send_create_machine (state);        break;      case 1: +    case 2:        do_a_state_change (state);        break;      default: @@ -341,8 +421,11 @@ do_something_random (gpointer data)      }    n_children = gtk_tree_model_iter_n_children (state->store, NULL); -  if (n_children >= 8) -    g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); +  if (n_children >= 5) +    { +      g_print ("MAX children reached, switching to state changes only\n"); +      g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); +    }    else      g_timeout_add (g_random_int_range (500, 3000), do_something_random, state);    return FALSE; @@ -406,6 +489,34 @@ sort_by_state (GtkTreeModel *model,  		 info_b ? info_b->state : "");  } +static void  +set_cell_progress (GtkTreeViewColumn *tree_column, +		   GtkCellRenderer   *cell, +		   GtkTreeModel      *tree_model, +		   GtkTreeIter       *iter, +		   gpointer           data) +{ +  MachineInfo *info; +   +  gtk_tree_model_get (tree_model, iter, 0, &info, -1); +   +  g_object_set (cell, "value", (int) (info->progress * 100), NULL); +} + +static gint +sort_by_progress (GtkTreeModel *model, +		  GtkTreeIter  *a, +		  GtkTreeIter  *b, +		  gpointer      user_data) +{ +  MachineInfo *info_a, *info_b; + +  gtk_tree_model_get (model, a, 0, &info_a, -1); +  gtk_tree_model_get (model, b, 0, &info_b, -1); + +  return info_a->progress > info_b->progress ? 1 : -1; +} +  static void  get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data)  { @@ -458,6 +569,17 @@ get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data)  				   0, sort_by_state, NULL, NULL);    gtk_tree_view_column_set_sort_column_id (col, 0);    gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col); + +  rend = gtk_cell_renderer_progress_new (); +  col = gtk_tree_view_column_new_with_attributes (_("Progress"),  +						  rend,  +						  NULL); +  gtk_tree_view_column_set_cell_data_func (col, rend, set_cell_progress, NULL, NULL); +  gtk_tree_view_column_set_resizable (col, TRUE); +  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (state->store),  +				   0, sort_by_progress, NULL, NULL); +  gtk_tree_view_column_set_sort_column_id (col, 0); +  gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col);    for (i = 0; i < objs->len; i++)      { | 
