Crossword Editor Codebase Overview

The Crossword Editor is an authoring tool for creating and editing crossword puzzles. It follows a Unidirectional Data Flow Architecture (Action-Model-View) instead of a more traditional MVC-style architecutre. This is to manage a high complexity, while remaining predictable and testable.

There’s an intro to the architecture of the editor in these slides from a talk I gave.

Architectural Principles

The editor is built on several key principles:

  1. Single Value State: All state is kept in a single struct (EditState). Updates are discrete and atomic.

  2. Centralized Control Flow: Control flow follows a top-down dispatch model. UI callbacks generate actions (value-typed commands) rather than modifying the model.

  3. Stateless Widgets: Widgets are commutative. This means that given a certain state, they always render identically independent of the path taken to reach that state. They don’t query or mutate a model directly, but are updated externally.

  4. Concentrated Complexity: Complexity is isolated in specific areas. For example:

    • edit-window-controls.c: Translates between GTK events and values.

    • grid-state.c: Handles crossword-specific behavior and mutations.

    • puzzle-stack.c: Manages the undo/redo stack by storing state snapshots. These areas are marked as such in a comment in the code.

Key Components

EditState

The central struct representable as a “value”. It contains over twenty-five members, including four distinct GridState objects for different views (Grid, Clues, Style, and Preview). Every EditState has its own, full copy of the IpuzPuzzle object.

EditWindow

The main application window. It binds the EditState to the UI. It is structured around the four primary authoring stages:

  • Grid: For designing the grid layout, symmetry, and automatic fill.

  • Clues: For writing and manages clues, supported by clue assistants (definitions, anagrams, etc).

  • Style: For customizing the visual appearance (colors, shapes).

  • Metadata: For editing puzzle information (title, author, copyright).

PuzzleStack

Stores the current EditState being edited. It has a stack of prior ones that can be used to implement undo/redo.