Esempio n. 1
0
int clean_population()
/* Frees memory for all individuals in population and for the global
   population itself. */
{
     int current_id;

     if (NULL != global_population.individual_array)
     {
        current_id = get_first();
        while(current_id != -1)
        {
           remove_individual(current_id);
           current_id = get_next(current_id);
        }
        
        free_stack(&global_population.free_ids_stack);
        free(global_population.individual_array);

        global_population.individual_array = NULL;
        global_population.size = 0;
        global_population.last_identity = -1;
        
     }
     
        
     return (0);
}
/* This is emitted for *all* individuals in the individual aggregator (not
 * just the ones we keep a reference to), to allow for the case where a new
 * individual doesn't contain an EmpathyContact, but later has a persona added
 * which does. */
static void
individual_notify_personas_cb (FolksIndividual *individual,
    GParamSpec *pspec,
    EmpathyIndividualManager *self)
{
  EmpathyIndividualManagerPriv *priv = GET_PRIV (self);

  const gchar *id = folks_individual_get_id (individual);
  gboolean has_contact = empathy_folks_individual_contains_contact (individual);
  gboolean had_contact = (g_hash_table_lookup (priv->individuals,
      id) != NULL) ? TRUE : FALSE;

  if (had_contact == TRUE && has_contact == FALSE)
    {
      GList *removed = NULL;

      /* The Individual has lost its EmpathyContact */
      removed = g_list_prepend (removed, individual);
      g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL, NULL, removed,
          TP_CHANNEL_GROUP_CHANGE_REASON_NONE /* FIXME */);
      g_list_free (removed);

      remove_individual (self, individual);
    }
  else if (had_contact == FALSE && has_contact == TRUE)
    {
      GList *added = NULL;

      /* The Individual has gained its first EmpathyContact */
      add_individual (self, individual);

      added = g_list_prepend (added, individual);
      g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL, added, NULL,
          TP_CHANNEL_GROUP_CHANGE_REASON_NONE /* FIXME */);
      g_list_free (added);
    }
}
static void
aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator,
    GeeMultiMap *changes,
    EmpathyIndividualManager *self)
{
  EmpathyIndividualManagerPriv *priv = GET_PRIV (self);
  GeeIterator *iter;
  GeeSet *removed;
  GeeCollection *added;
  GList *added_set = NULL, *added_filtered = NULL, *removed_list = NULL;

  /* We're not interested in the relationships between the added and removed
   * individuals, so just extract collections of them. Note that the added
   * collection may contain duplicates, while the removed set won't. */
  removed = gee_multi_map_get_keys (changes);
  added = gee_multi_map_get_values (changes);

  /* Handle the removals first, as one of the added Individuals might have the
   * same ID as one of the removed Individuals (due to linking). */
  iter = gee_iterable_iterator (GEE_ITERABLE (removed));
  while (gee_iterator_next (iter))
    {
      FolksIndividual *ind = gee_iterator_get (iter);

      if (ind == NULL)
        continue;

      g_signal_handlers_disconnect_by_func (ind,
          individual_notify_personas_cb, self);

      if (g_hash_table_lookup (priv->individuals,
          folks_individual_get_id (ind)) != NULL)
        {
          remove_individual (self, ind);
          removed_list = g_list_prepend (removed_list, ind);
        }

      g_clear_object (&ind);
    }
  g_clear_object (&iter);

  /* Filter the individuals for ones which contain EmpathyContacts */
  iter = gee_iterable_iterator (GEE_ITERABLE (added));
  while (gee_iterator_next (iter))
    {
      FolksIndividual *ind = gee_iterator_get (iter);

      /* Make sure we handle each added individual only once. */
      if (ind == NULL || g_list_find (added_set, ind) != NULL)
        continue;
      added_set = g_list_prepend (added_set, ind);

      g_signal_connect (ind, "notify::personas",
          G_CALLBACK (individual_notify_personas_cb), self);

      if (empathy_folks_individual_contains_contact (ind) == TRUE)
        {
          add_individual (self, ind);
          added_filtered = g_list_prepend (added_filtered, ind);
        }

      g_clear_object (&ind);
    }
  g_clear_object (&iter);

  g_list_free (added_set);

  g_object_unref (added);
  g_object_unref (removed);

  /* Bail if we have no individuals left */
  if (added_filtered == NULL && removed == NULL)
    return;

  added_filtered = g_list_reverse (added_filtered);

  g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL,
      added_filtered, removed_list,
      TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
      TRUE);

  g_list_free (added_filtered);
  g_list_free (removed_list);
}