Example #1
0
/**
 * hif_state_child_percentage_changed_cb:
 **/
static void
hif_state_child_percentage_changed_cb(HifState *child, guint percentage, HifState *state)
{
    HifStatePrivate *priv = GET_PRIVATE(state);
    gfloat offset;
    gfloat range;
    gfloat extra;
    guint parent_percentage;

    /* propagate up the stack if HifState has only one step */
    if (priv->steps == 1) {
        hif_state_set_percentage(state, percentage);
        return;
    }

    /* did we call done on a state that did not have a size set? */
    if (priv->steps == 0)
        return;

    /* already at >= 100% */
    if (priv->current >= priv->steps) {
        g_warning("already at %i/%i steps on %p", priv->current, priv->steps, state);
        return;
    }

    /* we have to deal with non-linear steps */
    if (priv->step_data != NULL) {
        /* we don't store zero */
        if (priv->current == 0) {
            parent_percentage = percentage * priv->step_data[priv->current] / 100;
        } else {
            /* bilinearly interpolate for speed */
            parent_percentage =(((100 - percentage) * priv->step_data[priv->current-1]) +
                        (percentage * priv->step_data[priv->current])) / 100;
        }
        goto out;
    }

    /* get the offset */
    offset = hif_state_discrete_to_percent(priv->current, priv->steps);

    /* get the range between the parent step and the next parent step */
    range = hif_state_discrete_to_percent(priv->current+1, priv->steps) - offset;
    if (range < 0.01) {
        g_warning("range=%f(from %i to %i), should be impossible", range, priv->current+1, priv->steps);
        return;
    }

    /* restore the pre-child action */
    if (percentage == 100)
        priv->last_action = priv->child_action;

    /* get the extra contributed by the child */
    extra =((gfloat) percentage / 100.0f) * range;

    /* emit from the parent */
    parent_percentage =(guint)(offset + extra);
out:
    hif_state_set_percentage(state, parent_percentage);
}
Example #2
0
/**
 * hif_state_done_real:
 **/
gboolean
hif_state_done_real (HifState *state, GError **error, const gchar *strloc)
{
	gboolean ret;
	gdouble elapsed;
	gfloat percentage;

	g_return_val_if_fail (state != NULL, FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	/* check */
	ret = hif_state_check (state, error);
	if (!ret)
		goto out;

	/* do we care */
	if (!state->priv->report_progress)
		goto out;

	/* did we call done on a state that did not have a size set? */
	if (state->priv->steps == 0) {
		g_set_error (error, HIF_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR,
			     "done on a state %p that did not have a size set! [%s]",
			     state, strloc);
		hif_state_print_parent_chain (state, 0);
		ret = FALSE;
		goto out;
	}

	/* check the interval was too big in allow_cancel false mode */
	if (state->priv->enable_profile) {
		elapsed = g_timer_elapsed (state->priv->timer, NULL);
		if (!state->priv->allow_cancel_changed_state && state->priv->current > 0) {
			if (elapsed > 0.1f) {
				g_warning ("%.1fms between hif_state_done() and no hif_state_set_allow_cancel()", elapsed * 1000);
				hif_state_print_parent_chain (state, 0);
			}
		}

		/* save the duration in the array */
		if (state->priv->step_profile != NULL)
			state->priv->step_profile[state->priv->current] = elapsed;
		g_timer_start (state->priv->timer);
	}

	/* is already at 100%? */
	if (state->priv->current >= state->priv->steps) {
		g_set_error (error, HIF_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR,
			     "already at 100%% state [%s]", strloc);
		hif_state_print_parent_chain (state, 0);
		ret = FALSE;
		goto out;
	}

	/* is child not at 100%? */
	if (state->priv->child != NULL) {
		HifStatePrivate *child_priv = state->priv->child->priv;
		if (child_priv->current != child_priv->steps) {
			g_print ("child is at %i/%i steps and parent done [%s]\n",
				 child_priv->current, child_priv->steps, strloc);
			hif_state_print_parent_chain (state->priv->child, 0);
			ret = TRUE;
			/* do not abort, as we want to clean this up */
		}
	}

	/* we just checked for cancel, so it's not true to say we're blocking */
	hif_state_set_allow_cancel (state, TRUE);

	/* another */
	state->priv->current++;

	/* find new percentage */
	if (state->priv->step_data == NULL) {
		percentage = hif_state_discrete_to_percent (state->priv->current,
							    state->priv->steps);
	} else {
		/* this is cumalative, for speedy access */
		percentage = state->priv->step_data[state->priv->current - 1];
	}
	hif_state_set_percentage (state, (guint) percentage);

	/* show any profiling stats */
	if (state->priv->enable_profile &&
	    state->priv->current == state->priv->steps &&
	    state->priv->step_profile != NULL) {
		hif_state_show_profile (state);
	}

	/* reset child if it exists */
	if (state->priv->child != NULL)
		hif_state_reset (state->priv->child);
out:
	return ret;
}