# Game State
**Status**: Deprecated

Control flow in the game is centralized in two different places. All
navigation throughout the game between puzzles, is controlled by
`PlayWindow`. In addition, all navigation within a crossword once it's
loaded is handled by `PlayXword`. This doc covers the former. For the
latter, see `xword-state.md`.

When the main `PlayWindow` is first loaded, it loads list of all the
possible PlayPuzzleSets that the game knows about and puts them in a
`GListModel` (`:play_set_list`). It also creates a `GtkStack` with the
contents of the main window as the first page in the stack. These
contents are the first element in the stack and have the name `main`.
They shouldn't change for the lifetime of the window

Once the user selects a puzzle, `PlayWindow` will call
`::start_puzzles` on the appropriate puzzle set. It will then call get
phase to get widgets to display for the appropriate phases. Puzzles
should be prepared to give a widget at the start and populate them as
necessary (or display loading information, such as in the case of
network-based puzzles).


Control will flow to the PuzzleSet, which can call `::change_phase`
whenever appropriate to update the stack. Dialogs are fine to popup as
well as part of a phase change.

Once a puzzle is finished (either by beating the whole set, or from a
UI element), `::puzzles_done` is called on the puzzle set which will
free up memory / clear any widgets.

It's up to a puzzle set if it wants to keep the widget around when it
is removed from the stack. It should either call `ref_sink()` and
reparent it in future calls, or drop all references after puzzles_done
is called.

Notes:

* Calling `::change_phase` to `"main"` will _not_ trigger a `::puzzles_done`
  call. However, if the user selects a different puzzle set, it will be called.
* Every `::start_puzzles` call needs to be mirrored by a `puzzles_done`
  call before another puzzle set can start. Only one PuzzleSet is run at a time.
* If a puzzle set intends to keep a widget around between invocations, it should
  ref_sink it first.

