History Manager


The history manager allows the user to roll directly to a named state even if it is across multiple branches. It is possible to cycle through all branches of the history within a single stream.

The history manager supports multiple history streams. As you create and work with different parts, the individual parts maintain their own independent history streams. As an example, when working in Scheme, parts are managed in independent windows.

The history stream maintains three pointers. The first pointer is to the root delta state. The second pointer is to the last noted active delta state. The third pointer is to the delta state currently being created.

Figure. History Stream Structure

The following functions may be used with or without the Part Management Component.

Memory Management

api_prune_history
Remove delta states in a history stream

Save and Restore

api_save_entity_list_with_history
Save history information with the part
api_save_entity_list_with_history_file
Save history information with the part
api_restore_entity_list_with_history
Restore the part and history
api_restore_entity_list_with_history_file
Restore the part and history

History Management Functions with Part Manager

The calls to api_pm_start_state and api_pm_note_state (or api_part_start_state and api_part_note_state) must be strictly paired regardless of errors. Start state and note state are paired by the use of a static level counter. If the note state were skipped when there was an error, the counter would be off by one and subsequent states would not be noted.

int depth;
api_pm_start_state(depth);
API_BEGIN
result = api_do_stuff_1(args);
check_outcome(result);       // If result is not ok,
                            // jump to API_END
// Alternate style of using check_outcome
check_outcome(api_do_stuff_2(args));
// Tell the part manager and graphics what happened
record_entity(new top level entity);
update_entity(modified top level entity);
API_END
api_pm_note_state(outcome(API_SUCCESS), depth);

If an error occurs, it will be caught by API_END. The api_pm_note_state is always called regardless of error. Note that the outcome is checked before recording or updating entities, so the part manager and graphics do not see anything bad. The check level is controlled by the option history_checks.

You can also use API_SYS_BEGIN/END or EXCEPTION_BEGIN/TRY/CATCH/END with api_pm_start_state in the EXCEPTION_BEGIN block and api_pm_note_state in an EXCEPTION_CATCH( TRUE ) block.

History Management Functions without Part Manager

The Kernel has a set of APIs allowing advanced part management independent of the Part Management Component. For example, it is possible to use PART only as a port of entry to the Graphic Interaction Component. This permits roll back without using the Part Management Component.

Because Part Management uses the Kernel Component APIs, any use of the roll portions of the Part Management could interfere with tasks performed by the Kernel APIs. This includes indirect calls such as StartEntityCreation, EndEntityCreation, and the modification cousins. Searching for "api_pm_" should identify calls to avoid. Even innocuous APIs like api_pm_save_part and api_pm_load_part could cause problems, because they close delta states and could create new ones.

The following history-related APIs from the Kernel do not require anything from the Part Management Component.

Foundation of all History Management

api_note_state
Note delta states
api_delete_ds
Delete a delta state
api_change_state
Roll back and forward to a given state
api_bb_begin</dt>
Used in the API_BEGIN macro
api_bb_end
Used in the API_END macro

Advanced Navigation in Existing Streams

api_change_to_state
Roll to a given delta state
api_find_named_state
Recall a delta state with a given name
api_name_state
Name a delta state
api_roll_n_states
Roll back and forward

Support for Multiple History Streams

The api_add_state and api_remove_state are relatively easy to use. After noting a state, remove it from the default history stream and add it to the stream it should belong to. api_distribute_state_to_streams is much more difficult to use and incorporates the StreamFinder class.

api_add_state
Add states between streams
api_remove_state
Move states between streams
api_distribute_state_to_streams
After noting a state, distribute its bulletins to all the relevant history streams

Disabling History

History is not explicitly enabled or disabled. It is effectively enabled simply by making calls to functions to perform required tasks. ACIS provides two levels of disabling history.

With api_logging(FALSE), bulletins and delta states are still created, but kept only long enough to support error recovery.

With set_logging(FALSE), no bulletins are created, but bulletin boards and delta states are still created. Modeling errors can not be recovered unless the application developers provide their own mechanism.

The developer must be careful about the use of API_BEGIN/API_END, and should still call api_note_state periodically to clean up memory used by empty bulletin boards.

[Top]