## ZifState ZifState — Progress reporting |

## Synopsis

    #define             ZIF_STATE_ERROR
    struct              ZifState;
    enum                ZifStateAction;
    struct              ZifStateClass;
    enum                ZifStateError;
    gboolean            (*ZifStateErrorHandlerCb)           (const GError *error,
                                                             gpointer user_data);
    gboolean            (*ZifStateLockHandlerCb)            (ZifState *state,
                                                             ZifLock *lock,
                                                             ZifLockType lock_type,
                                                             GError **error,
                                                             gpointer user_data);
    gboolean            zif_state_action_start              (ZifState *state,
                                                             ZifStateAction action,
                                                             const gchar *action_hint);
    gboolean            zif_state_action_stop               (ZifState *state);
    const gchar *       zif_state_action_to_string          (ZifStateAction action);
    gboolean            zif_state_check                     (ZifState *state,
                                                             GError **error);
    #define             zif_state_done                      (state,
                                                             error)
    gboolean            zif_state_done_real                 (ZifState *state,
                                                             GError **error,
                                                             const gchar *strloc);
    gboolean            zif_state_error_handler             (ZifState *state,
                                                             const GError *error);
    GQuark              zif_state_error_quark               (void);
    #define             zif_state_finished                  (state,
                                                             error)
    gboolean            zif_state_finished_real             (ZifState *state,
                                                             GError **error,
                                                             const gchar *strloc);
    ZifStateAction      zif_state_get_action                (ZifState *state);
    const gchar *       zif_state_get_action_hint           (ZifState *state);
    gboolean            zif_state_get_allow_cancel          (ZifState *state);
    GCancellable *      zif_state_get_cancellable           (ZifState *state);
    ZifState *          zif_state_get_child                 (ZifState *state);
    guint               zif_state_get_percentage            (ZifState *state);
    guint64             zif_state_get_speed                 (ZifState *state);
    ZifState *          zif_state_new                       (void);
    gboolean            zif_state_reset                     (ZifState *state);
    void                zif_state_set_allow_cancel          (ZifState *state,
                                                             gboolean allow_cancel);
    void                zif_state_set_cancellable           (ZifState *state,
                                                             GCancellable *cancellable);
    void                zif_state_set_enable_profile        (ZifState *state,
                                                             gboolean enable_profile);
    void                zif_state_set_error_handler         (ZifState *state,
                                                             ZifStateErrorHandlerCb error_handler_cb,
                                                             gpointer user_data);
    void                zif_state_set_lock_handler          (ZifState *state,
                                                             ZifStateLockHandlerCb lock_handler_cb,
                                                             gpointer user_data);
    #define             zif_state_set_number_steps          (state,
                                                             steps)
    gboolean            zif_state_set_number_steps_real     (ZifState *state,
                                                             guint steps,
                                                             const gchar *strloc);
    void                zif_state_set_package_progress      (ZifState *state,
                                                             const gchar *package_id,
                                                             ZifStateAction action,
                                                             guint percentage);
    gboolean            zif_state_set_percentage            (ZifState *state,
                                                             guint percentage);
    void                zif_state_set_report_progress       (ZifState *state,
                                                             gboolean report_progress);
    void                zif_state_set_speed                 (ZifState *state,
                                                             guint64 speed);
    #define             zif_state_set_steps                 (state,
                                                             error,
                                                             value,
                                                             ...)
    gboolean            zif_state_set_steps_real            (ZifState *state,
                                                             GError **error,
                                                             const gchar *strloc,
                                                             gint value,
                                                             ...);
    gboolean            zif_state_take_lock                 (ZifState *state,
                                                             ZifLockType lock_type,
                                                             ZifLockMode lock_mode,
                                                             GError **error);
    gboolean            zif_state_valid                     (ZifState *state);

## Object Hierarchy

      GObject
       +----ZifState

## Properties

      "speed"                    guint64               : Read

## Signals

      "action-changed"                                 : Run Last
      "allow-cancel-changed"                           : Run Last
      "package-progress-changed"                       : Run Last
      "percentage-changed"                             : Run Last
      "subpercentage-changed"                          : Run Last

## Description

Objects can use `zif_state_set_percentage()` if the absolute percentage is known. Percentages should always go up, not down.

Modules usually set the number of steps that are expected using `zif_state_set_number_steps()` and then after each section is completed, the `zif_state_done()` function should be called. This will automatically call `zif_state_set_percentage()` with the correct values.

ZifState allows sub-modules to be "chained up" to the parent module so that as the sub-module progresses, so does the parent. The child can be reused for each section, and chains can be deep.

To get a child object, you should use `zif_state_get_child()` and then use the result in any sub-process. You should ensure that the child is not re-used without calling `zif_state_done()`.

There are a few nice touches in this module, so that if a module only has one progress step, the child progress is used for updates.

Example 1. Using a ZifState.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    static void
    _do_something (ZifState *state)
    {
       ZifState *state_local;

       // setup correct number of steps
       zif_state_set_number_steps (state, 2);

       // we can't cancel this function
       zif_state_set_allow_cancel (state, FALSE);

       // run a sub function
       state_local = zif_state_get_child (state);
       _do_something_else1 (state_local);

       // this section done
       zif_state_done (state);

       // run another sub function
       state_local = zif_state_get_child (state);
       _do_something_else2 (state_local);

       // this section done (all complete)
       zif_state_done (state);
    }

## Details

### ZIF_STATE_ERROR

    #define ZIF_STATE_ERROR		(zif_state_error_quark ())

### struct ZifState

    struct ZifState;

### enum ZifStateAction

    typedef enum {
    	ZIF_STATE_ACTION_DOWNLOADING,
    	ZIF_STATE_ACTION_CHECKING,
    	ZIF_STATE_ACTION_LOADING_REPOS,
    	ZIF_STATE_ACTION_DECOMPRESSING,
    	ZIF_STATE_ACTION_DEPSOLVING_CONFLICTS,
    	ZIF_STATE_ACTION_DEPSOLVING_INSTALL,
    	ZIF_STATE_ACTION_DEPSOLVING_REMOVE,
    	ZIF_STATE_ACTION_DEPSOLVING_UPDATE,
    	ZIF_STATE_ACTION_PREPARING,
    	ZIF_STATE_ACTION_INSTALLING,
    	ZIF_STATE_ACTION_REMOVING,
    	ZIF_STATE_ACTION_UPDATING,
    	ZIF_STATE_ACTION_CLEANING,
    	ZIF_STATE_ACTION_TEST_COMMIT,
    	ZIF_STATE_ACTION_LOADING_RPMDB,		/* Since: 0.2.4 */
    	ZIF_STATE_ACTION_CHECKING_UPDATES, /* Since: 0.2.4 */
    	ZIF_STATE_ACTION_UNKNOWN
    } ZifStateAction;

`ZIF_STATE_ACTION_DOWNLOADING` |
`ZIF_STATE_ACTION_CHECKING` |
`ZIF_STATE_ACTION_LOADING_REPOS` |
`ZIF_STATE_ACTION_DECOMPRESSING` |
`ZIF_STATE_ACTION_DEPSOLVING_CONFLICTS` |
`ZIF_STATE_ACTION_DEPSOLVING_INSTALL` |
`ZIF_STATE_ACTION_DEPSOLVING_REMOVE` |
`ZIF_STATE_ACTION_DEPSOLVING_UPDATE` |
`ZIF_STATE_ACTION_PREPARING` |
`ZIF_STATE_ACTION_INSTALLING` |
`ZIF_STATE_ACTION_REMOVING` |
`ZIF_STATE_ACTION_UPDATING` |
`ZIF_STATE_ACTION_CLEANING` |
`ZIF_STATE_ACTION_TEST_COMMIT` |
`ZIF_STATE_ACTION_LOADING_RPMDB` |
`ZIF_STATE_ACTION_CHECKING_UPDATES` |
`ZIF_STATE_ACTION_UNKNOWN` |

### struct ZifStateClass

    struct ZifStateClass {
    	GObjectClass	 parent_class;
    	/* Signals */
    	void		(* percentage_changed)		(ZifState *state,
    							 guint		 value);
    	void		(* subpercentage_changed) (ZifState *state,
    							 guint		 value);
    	void		(* allow_cancel_changed) (ZifState *state,
    							 gboolean	 allow_cancel);
    	void		(* action_changed)		(ZifState *state,
    							 ZifStateAction	 action,
    							 const gchar *action_hint);
    	void		(* package_progress_changed) (ZifState *state,
    							 const gchar *package_id,
    							 ZifStateAction	 action,
    							 guint		 percentage);
    	/* Padding for future expansion */
    	void (*_zif_reserved1) (void);
    	void (*_zif_reserved2) (void);
    	void (*_zif_reserved3) (void);
    	void (*_zif_reserved4) (void);
    };

### enum ZifStateError

    typedef enum {
    	ZIF_STATE_ERROR_CANCELLED,
    	ZIF_STATE_ERROR_INVALID,
    	ZIF_STATE_ERROR_LAST
    } ZifStateError;

`ZIF_STATE_ERROR_CANCELLED` |
`ZIF_STATE_ERROR_INVALID` |
`ZIF_STATE_ERROR_LAST` |

### ZifStateErrorHandlerCb ()

    gboolean            (*ZifStateErrorHandlerCb)           (const GError *error,
                                                             gpointer user_data);

### ZifStateLockHandlerCb ()

    gboolean            (*ZifStateLockHandlerCb)            (ZifState *state,
                                                             ZifLock *lock,
                                                             ZifLockType lock_type,
                                                             GError **error,
                                                             gpointer user_data);

### zif_state_action_start ()

    gboolean            zif_state_action_start              (ZifState *state,
                                                             ZifStateAction action,
                                                             const gchar *action_hint);

Sets the action which is being performed. This is emitted up the chain to any parent `ZifState` objects, using the action-changed signal.

If a `ZifState` reaches 100% then it is automatically stopped with a call to `zif_state_action_stop()`.

It is allowed to call `zif_state_action_start()` more than once for a given `ZifState` instance.

`state` : | A ZifState
`action` : | An action, e.g. `ZIF_STATE_ACTION_DECOMPRESSING`
`action_hint` : | A hint on what the action is doing, e.g. "/var/cache/yum/i386/15/koji/primary.sqlite"
Returns : | `TRUE` if the signal was propagated, `FALSE` otherwise

Since 0.1.2

### zif_state_action_stop ()

    gboolean            zif_state_action_stop               (ZifState *state);

Returns the ZifState to it's previous value. It is not expected you will ever need to use this funtion.

`state` : | A ZifState
Returns : | `TRUE` if the signal was propagated, `FALSE` otherwise

Since 0.1.2

### zif_state_action_to_string ()

    const gchar *       zif_state_action_to_string          (ZifStateAction action);

Converts the `ZifStateAction` to a string.

`action` : | A `ZifStateAction` value
Returns : | A string, or `NULL` for unknown.

Since 0.1.2

### zif_state_check ()

    gboolean            zif_state_check                     (ZifState *state,
                                                             GError **error);

Do any checks to see if the task has been cancelled.

`state` : | A ZifState
`error` : | A GError or `NULL`
Returns : | `TRUE` for success, `FALSE` otherwise

Since 0.3.4

### zif_state_done()

    #define zif_state_done(state, error)			zif_state_done_real(state, error, G_STRLOC)

### zif_state_done_real ()

    gboolean            zif_state_done_real                 (ZifState *state,
                                                             GError **error,
                                                             const gchar *strloc);

Called when the current sub-task has finished.

`state` : | A ZifState
`error` : | A GError or `NULL`
Returns : | `TRUE` for success, `FALSE` otherwise

Since 0.1.0

### zif_state_error_handler ()

    gboolean            zif_state_error_handler             (ZifState *state,
                                                             const GError *error);

`state` : | A ZifState
`error` : | A GError
Returns : | `FALSE` if the error is fatal, `TRUE` otherwise

Since 0.1.0

### zif_state_error_quark ()

    GQuark              zif_state_error_quark               (void);

Returns : | An error quark.

Since 0.1.0

### zif_state_finished()

    #define zif_state_finished(state, error)		zif_state_finished_real(state, error, G_STRLOC)

### zif_state_finished_real ()

    gboolean            zif_state_finished_real             (ZifState *state,
                                                             GError **error,
                                                             const gchar *strloc);

Called when the current sub-task wants to finish early and still complete.

`state` : | A ZifState
`error` : | A GError or `NULL`
Returns : | `TRUE` for success, `FALSE` otherwise

Since 0.1.0

### zif_state_get_action ()

    ZifStateAction      zif_state_get_action                (ZifState *state);

Gets the last set action value.

`state` : | A ZifState
Returns : | An action, e.g. `ZIF_STATE_ACTION_DECOMPRESSING`

Since 0.1.2

### zif_state_get_action_hint ()

    const gchar *       zif_state_get_action_hint           (ZifState *state);

Gets the action hint, which may be useful to the users.

`state` : | A ZifState
Returns : | An a ction hint, e.g. "/var/cache/yum/i386/15/koji/primary.sqlite"

Since 0.1.2

### zif_state_get_allow_cancel ()

    gboolean            zif_state_get_allow_cancel          (ZifState *state);

Gets if the sub-task (or one of it's sub-sub-tasks) is cancellable

`state` : | A ZifState
Returns : | `TRUE` if the translation has a chance of being cancelled

Since 0.1.0

### zif_state_get_cancellable ()

    GCancellable *      zif_state_get_cancellable           (ZifState *state);

Gets the GCancellable for this operation

`state` : | A ZifState
Returns : | The GCancellable or `NULL`. [transfer none]

Since 0.1.0

### zif_state_get_child ()

    ZifState *          zif_state_get_child                 (ZifState *state);

Monitor a child state and proxy back up to the parent state. You should not `g_object_unref()` this object, it is owned by the parent.

`state` : | A ZifState
Returns : | A new `ZifState` or `NULL` for failure. [transfer none]

Since 0.1.0

### zif_state_get_percentage ()

    guint               zif_state_get_percentage            (ZifState *state);

Get the percentage state.

`state` : | A ZifState
Returns : | The percentage value, or `G_MAXUINT` for error

Since 0.1.0

### zif_state_get_speed ()

    guint64             zif_state_get_speed                 (ZifState *state);

Gets the transaction speed in bytes per second.

`state` : | A ZifState
Returns : | speed, or 0 for unknown.

Since 0.1.5

### zif_state_new ()

    ZifState *          zif_state_new                       (void);

Returns : | A new ZifState instance.

Since 0.1.0

### zif_state_reset ()

    gboolean            zif_state_reset                     (ZifState *state);

Resets the ZifState object to unset

`state` : | A ZifState
Returns : | `TRUE` for success, `FALSE` otherwise

Since 0.1.0

### zif_state_set_allow_cancel ()

    void                zif_state_set_allow_cancel          (ZifState *state,
                                                             gboolean allow_cancel);

Set is this sub task can be cancelled safely.

`state` : | A ZifState
`allow_cancel` : | If this sub-task can be cancelled

Since 0.1.0

### zif_state_set_cancellable ()

    void                zif_state_set_cancellable           (ZifState *state,
                                                             GCancellable *cancellable);

Sets the GCancellable object to use.

`state` : | A ZifState
`cancellable` : | The GCancellable which is used to cancel tasks, or `NULL`

Since 0.1.0

### zif_state_set_enable_profile ()

    void                zif_state_set_enable_profile        (ZifState *state,
                                                             gboolean enable_profile);

This enables profiling of ZifState. This may be useful in development, but be warned; enabling profiling makes ZifState very slow.

`state` : | A ZifState
`enable_profile` : | if profiling should be enabled

Since 0.1.3

### zif_state_set_error_handler ()

    void                zif_state_set_error_handler         (ZifState *state,
                                                             ZifStateErrorHandlerCb error_handler_cb,
                                                             gpointer user_data);

`state` : | A ZifState
`error_handler_cb` : | A ZifStateErrorHandlerCb which returns `FALSE` if the error is fatal. [scope async]
`user_data` : | A user_data to be passed to the ZifStateErrorHandlerCb

Since 0.1.0

### zif_state_set_lock_handler ()

    void                zif_state_set_lock_handler          (ZifState *state,
                                                             ZifStateLockHandlerCb lock_handler_cb,
                                                             gpointer user_data);

`state` : | A ZifState
`lock_handler_cb` : | A ZifStateLockHandlerCb which returns `FALSE` if the lock cannot be got. [scope async]
`user_data` : | A user_data to be passed to the ZifStateLockHandlerCb

Since 0.1.6

### zif_state_set_number_steps()

    #define zif_state_set_number_steps(state, steps) zif_state_set_number_steps_real(state, steps, G_STRLOC)

### zif_state_set_number_steps_real ()

    gboolean            zif_state_set_number_steps_real     (ZifState *state,
                                                             guint steps,
                                                             const gchar *strloc);

Sets the number of sub-tasks, i.e. how many times the `zif_state_done()` function will be called in the loop.

The function will immediately return with TRUE when the number of steps is 0 or if zif_state_set_report_progress(FALSE) was previously called.

`state` : | A ZifState
`steps` : | The number of sub-tasks in this transaction, can be 0
Returns : | `TRUE` for success, `FALSE` otherwise

Since 0.1.0

### zif_state_set_package_progress ()

    void                zif_state_set_package_progress      (ZifState *state,
                                                             const gchar *package_id,
                                                             ZifStateAction action,
                                                             guint percentage);

Sets any package progress.

`state` : | A ZifState
`package_id` : | A package_id
`action` : | A ZifStateAction
`percentage` : | A percentage

Since 0.3.1

### zif_state_set_percentage ()

    gboolean            zif_state_set_percentage            (ZifState *state,
                                                             guint percentage);

Set a percentage manually. NOTE: this must be above what was previously set, or it will be rejected.

`state` : | A ZifState
`percentage` : | Percentage value between 0% and 100%
Returns : | `TRUE` if the signal was propagated, `FALSE` otherwise

Since 0.1.0

### zif_state_set_report_progress ()

    void                zif_state_set_report_progress       (ZifState *state,
                                                             gboolean report_progress);

This disables progress tracking for ZifState. This is generally a bad thing to do, except when you know you cannot guess the number of steps in the state.

Using this function also reduced the amount of time spent getting a child state using `zif_state_get_child()` as a refcounted version of the parent is returned instead.

`state` : | A ZifState
`report_progress` : | if we care about percentage status

Since 0.1.3

### zif_state_set_speed ()

    void                zif_state_set_speed                 (ZifState *state,
                                                             guint64 speed);

Sets the download or install transaction speed in bytes per second.

`state` : | A ZifState
`speed` : | The transaction speed.

Since 0.1.5

### zif_state_set_steps()

    #define zif_state_set_steps(state, error, value, args...) zif_state_set_steps_real(state, error, G_STRLOC, value, ## args)

### zif_state_set_steps_real ()

    gboolean            zif_state_set_steps_real            (ZifState *state,
                                                             GError **error,
                                                             const gchar *strloc,
                                                             gint value,
                                                             ...);

This sets the step weighting, which you will want to do if one action will take a bigger chunk of time than another.

All the values must add up to 100, and the list must end with -1. Do not use this funtion directly, instead use the `zif_state_set_steps()` macro.

`state` : | A ZifState
`error` : | A GError, or `NULL`
`strloc` : | the code location
`value` : | A step weighting variable argument array
Returns : | `TRUE` for success

Since 0.1.3

### zif_state_take_lock ()

    gboolean            zif_state_take_lock                 (ZifState *state,
                                                             ZifLockType lock_type,
                                                             ZifLockMode lock_mode,
                                                             GError **error);

Takes a lock of a specified type. The lock is automatically free'd when the ZifState has been completed.

You can call `zif_state_take_lock()` multiple times with different or even the same `lock_type` value.

`state` : | A ZifState
`lock_type` : | A ZifLockType, e.g. `ZIF_LOCK_TYPE_RPMDB`
`lock_mode` : | A ZifLockMode, e.g. `ZIF_LOCK_MODE_PROCESS`
`error` : | A GError
Returns : | `FALSE` if the lock is fatal, `TRUE` otherwise

Since 0.3.0

### zif_state_valid ()

    gboolean            zif_state_valid                     (ZifState *state);

Returns if the `ZifState` is a valid object and ready for use. This is very useful in self-testing situations like: {{{ g_return_val_if_fail (zif_state_valid (md), FALSE); }}}

`state` : | A ZifState
Returns : | `TRUE` if the `ZifState` is okay to use, and has not been already used.

Since 0.1.2

## Property Details

### The `"speed"` property

      "speed"                    guint64               : Read

Default value: 0

Since 0.1.5

## Signal Details

### The `"action-changed"` signal

    void                user_function                      (ZifState *zifstate,
                                                            guint     arg1,
                                                            gchar    *arg2,
                                                            gpointer  user_data)      : Run Last

`zifstate` : | the object which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"allow-cancel-changed"` signal

    void                user_function                      (ZifState *zifstate,
                                                            gboolean  arg1,
                                                            gpointer  user_data)      : Run Last

`zifstate` : | the object which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"package-progress-changed"` signal

    void                user_function                      (ZifState *zifstate,
                                                            gchar    *arg1,
                                                            guint     arg2,
                                                            guint     arg3,
                                                            gpointer  user_data)      : Run Last

`zifstate` : | the object which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"percentage-changed"` signal

    void                user_function                      (ZifState *zifstate,
                                                            guint     arg1,
                                                            gpointer  user_data)      : Run Last

`zifstate` : | the object which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"subpercentage-changed"` signal

    void                user_function                      (ZifState *zifstate,
                                                            guint     arg1,
                                                            gpointer  user_data)      : Run Last

`zifstate` : | the object which received the signal.
`user_data` : | user data set when the signal handler was connected.