State saving


Data Structures

struct  osso_state_t

Functions

osso_return_t osso_state_write (osso_context_t *osso, osso_state_t *state)
osso_return_t osso_state_read (osso_context_t *osso, osso_state_t *state)

Detailed Description

State saving functionality is provided for applications as a convenient way of storing and retrieving GUI state information (e.g. the view to the last open document, scroll bar position). The information saved by using these functions does not survive over power off of the device, so other means need to be used to save e.g. the document that the user was writing (see Autosaving functions). The application should load the state information during startup in order to present the user with the previous GUI state from the start. No automatic saving of GUI state is done; it is left as responsibility of the application to call the appropriate Libosso function to do it.

The new osso_state_read() and osso_state_write() functions take care of state data reading and writing. The only limitation is that only a fixed-size contiguous memory area can be stored. This means that memory pointed by pointers cannot be stored (unless the pointed area is inside the contiguous memory area). The easiest way to define a contiguous memory area of different data types is to define a structure such as

struct state_data{
  gchar string[STRING_LENGTH];
  guint32 i;
  gchar filename[PATH_MAX];
};

One particular version (the version is given to osso_initialize()) of the application can have only one state file.

Here are steps that an application could use to handle state saving (and auto-saving). The steps 1 and 2 (and possibly 10) should be done in startup of the application.

1) Register callback to execute when the application goes to background and foreground:

g_signal_connect(G_OBJECT(program), "notify::is-topmost",
                 G_CALLBACK(topmost_status_change), data);
Where program is the HildonProgram object, topmost_status_change is a function to execute when the application goes to background or foreground. The function could look like this:
static void topmost_status_change(GObject *gobject,
                                  GParamSpec *arg1,
                                  gpointer data)
{
    HildonProgram *program = HILDON_PROGRAM(gobject);

    if (hildon_program_get_is_topmost(program)) {
        hildon_program_set_can_hibernate(program, FALSE);
    } else {
        save_state();
        hildon_program_set_can_hibernate(program, TRUE);
    }
}

2) Read old UI state with osso_state_read(), if it exists. (Build the UI according to the saved state, if it existed.)

3) Save the UI state with osso_state_write(), whenever the program goes to background. If the UI was successfully saved, set the 'killable' flag with hildon_program_set_can_hibernate(). Note that the killable flag should be set even if dialog contents could not be completely saved, provided that the user does not lose data that he/she input to the dialog.

4) Whenever the program goes to foreground, remove the killable flag with hildon_program_set_can_hibernate().

5) Save the UI state before exiting when the user closes the application.

In addition to the above steps, follow these steps if the application handles 'user data' (e.g. unsaved draft document):

6) Register a callback function for saving the user data with osso_application_set_autosave_cb().

7) When the application has unsaved user data, call osso_application_userdata_changed(). This causes the autosave callback to be called, after a timer has expired.

8) Whenever the application goes to background, call osso_application_autosave_force() if the program has unsaved user data.

9) When the application exits (for whatever reason), call osso_application_autosave_force() if the program has unsaved user data.

10) When the application is started the next time, check if there is autosaved user data. If there is, the application should allow the user to continue editing the data.

Note that the state saving information is stored to volatile memory (RAM), but the autosaved information should be stored to non-volatile memory (e.g. the internal flash). This is partly because of reliability: this way the application cannot save a permanent, possibly corrupted, UI state that would crash or break the application whenever it is started (however, the autosaved user data could still do it).

TODO: Libosso should provide more support for autosaving user data (for saving, loading and removing it).


Function Documentation

osso_return_t osso_state_read ( osso_context_t osso,
osso_state_t state 
)

This function reads a saved (GUI) state.

Parameters:
osso The library context as returned by osso_initialize.
state A pointer to an allocated osso_state_t structure. The data should point to a memory block that is at least as large as state_size. If the state_data member is NULL, the memory will be dynamically allocated and must be freed by the caller. If the state_size member is zero, the needed space is read from the state file.
Returns:
OSSO_OK if the state reading was successful. OSSO_ERROR if the operation failed for some reason. OSSO_INVALID if function arguments were invalid. OSSO_ERROR_NO_STATE if the state file was not found. OSSO_ERROR_STATE_SIZE if the state is not the specified size.
#include <libosso.h>
#include <stdio.h>
int main()
{
  char buf[50];
  osso_context_t *osso;
  osso_state_t state;
  osso_return_t ret;
  buf[0] = '\0';
  osso = osso_initialize("app", "1", 0, NULL);
  if (osso == NULL) return 1;
  state.state_size = 18;
  state.state_data = buf;
  ret = osso_state_read(osso, &state);
  if (ret != OSSO_OK) {
    printf("could not read the state\n");
    return 1;
  } else {
    printf("read state: %s\n", buf);
    return 0;
  }
}

osso_return_t osso_state_write ( osso_context_t osso,
osso_state_t state 
)

This function writes a (GUI) state to a file. Any existing state file will be overwritten.

Parameters:
osso The library context as returned by osso_initialize.
state The state to save.
Returns:
OSSO_OK if the operation succeeded. OSSO_ERROR if the state could not be saved. OSSO_INVALID if any argument is invalid.
#include <libosso.h>
#include <string.h>
int main()
{
  static char* s = "this is the state";
  osso_context_t *osso;
  osso_state_t state;
  osso_return_t ret;
  osso = osso_initialize("app", "1", 0, NULL);
  if (osso == NULL) return 1;
  state.state_size = strlen(s) + 1;
  state.state_data = (gpointer) s;
  ret = osso_state_write(osso, &state);
  if (ret != OSSO_OK)
    return 1;
  else
    return 0;
}


Generated on Thu Oct 4 11:35:32 2007 for Libosso by  doxygen 1.5.1