Skip to content

Fix event annotation lifecycle and persistence after the sexp_tree refactor#7595

Merged
Goober5000 merged 3 commits into
scp-fs2open:masterfrom
Goober5000:fix/annotations_post_refactor
Jul 11, 2026
Merged

Fix event annotation lifecycle and persistence after the sexp_tree refactor#7595
Goober5000 merged 3 commits into
scp-fs2open:masterfrom
Goober5000:fix/annotations_post_refactor

Conversation

@Goober5000

Copy link
Copy Markdown
Contributor

New version of #7538 subsequent to the sexp_tree refactor.

Follow-up to the sexp_tree refactor (#7301). The refactor changed how event annotations are tracked internally, which fixed most of the old detachment problems — but annotations on the event name itself could still be lost or misplaced, and annotations saved by pre-refactor FRED no longer loaded correctly. This PR fixes those cases in both FRED2 and qtFRED:

  • Deleting an event now discards the comment on its name. Previously it lingered behind the scenes and a new event could inherit it.
  • Insert Operator on an event's top operator no longer detaches the comment on the event's name.
  • In qtFRED, reordering events no longer discards annotation edits made since the editor was opened.
  • Annotations from missions saved with pre-refactor FRED resolved one level too deep in the tree, and a comment on an event's top operator migrated onto the event name. The old file format is now read and written exactly as before.
  • An annotation whose node no longer exists is dropped at save instead of being written to the mission file in an unmatchable form; while the mission was open, such an orphan could also show its comment on unrelated items.
  • The FRED2 help box once again shows the comment when an event's name is selected.

@Goober5000 Goober5000 added fix A fix for bugs, not-a-bugs, and/or regressions. qtfred A feature or issue related to qtFred. fred A feature or issue related to the FReespace EDitor (FRED) labels Jul 11, 2026
@github-project-automation github-project-automation Bot moved this to Work In Progress (PRs) in qtFRED2 Jul 11, 2026
@github-project-automation github-project-automation Bot moved this from Work In Progress (PRs) to In Review (PRs) in qtFRED2 Jul 11, 2026
@Goober5000
Goober5000 force-pushed the fix/annotations_post_refactor branch 2 times, most recently from 866c760 to e1826de Compare July 11, 2026 03:48
Goober5000 and others added 3 commits July 11, 2026 00:31
Post-refactor successor of fix/annotations, rebuilt for the shared sexp
tree model introduced by the sexp_tree refactor (scp-fs2open#7301).  The refactor
re-keyed annotations from UI item handles to tree_nodes[] indices, which
fixed most of the original decoupling by construction and already prunes
regular-node annotations in free_node2().  Two gaps remained, plus one
qtFRED regression:

- free_node2() only removed annotations keyed by node index, never a
  root-label annotation keyed rootKey(formula).  Deleting an event left
  that annotation live, so a later event whose formula reused the slot
  inherited the deleted event's annotation.  Remove the root key too;
  since the global Event_annotations are only rewritten at save, the
  removal still survives a Cancel.

- Inserting an operator above a labeled root changes the event's formula
  node, orphaning the root-label annotation keyed to the old index.
  Re-key it in insert_operator() so it follows the event.  (This is the
  only such flow: replace_operator() reuses the node in place.)

- qtFRED reorderByRootFormulaOrder() reloaded annotations from the
  global state, discarding any annotation edits made since the dialog
  was opened.  A root reorder changes neither node indices nor formulas,
  so drop the reload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Annotation +Path: values written by pre-refactor FRED were built over
the UI tree, where each event's root item is the event-name label and
every element after the event index is a child position at successive
levels below it: [event] is the label, [event, 0] the top operator
(the label's only child), [event, 0, k...] its descendants.  The
refactored SexpAnnotationModel built paths over tree_nodes[], which
represents the label's single child directly as the formula node, so
paths came out one level shallower: existing missions' annotations
resolved one level too deep (and were re-saved wrong), and a
top-operator annotation produced the length-1 path that decodes as a
root-label key, silently migrating onto the event label.

Emit and consume the label-level child position in
buildPath/resolveFromPath to preserve the on-disk contract.  Child 0
resolves to the formula node and any other index fails resolution,
matching the old traverse_path behavior of walking off the label's
sibling list.  Annotations on the event label itself are unaffected:
they remain the length-1 path handled by the root-key branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root-label annotations (event-name comments/colors) that lose their
node — e.g. because their event was deleted — could survive
indefinitely and surface on the wrong items:

- saveToGlobal's root-key branch kept an unresolvable annotation in
  Event_annotations with an empty path instead of marking it for
  pruning, so once a zombie was persisted in a mission file it
  survived every save/load cycle.
- getByKey(-1) matched annotations whose node_index had been reset to
  the unresolved sentinel, so such a zombie's comment could display on
  any item that has no annotation key of its own.

Guard findByKey against the -1 sentinel, and prune any annotation
whose rebuilt path is empty at save time.  (The complementary
in-session fixes — removing a root-label annotation when its event is
deleted and re-keying it when insert-operator changes the formula
node — are handled in the shared model and actions by 'Keep event
annotations attached to their node across tree mutations'.)

Also restore root-label comments in the FRED2 help box: update_help
resolved comments by model node index, which is -1 for labels.  Route
it through a get_item_comment virtual that the event editor's tree
overrides with its annotation key lookup, matching pre-refactor
behavior.  (qtFRED renders comments per-item via NoteRole, which
already covers labels; its help box does not show comments by design.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Goober5000
Goober5000 force-pushed the fix/annotations_post_refactor branch from e1826de to 5aabccc Compare July 11, 2026 04:46
@Goober5000
Goober5000 enabled auto-merge (rebase) July 11, 2026 04:48
@Goober5000
Goober5000 merged commit 50de61c into scp-fs2open:master Jul 11, 2026
18 checks passed
@github-project-automation github-project-automation Bot moved this from In Review (PRs) to Done in qtFRED2 Jul 11, 2026
@Goober5000
Goober5000 deleted the fix/annotations_post_refactor branch July 11, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix A fix for bugs, not-a-bugs, and/or regressions. fred A feature or issue related to the FReespace EDitor (FRED) qtfred A feature or issue related to qtFred.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants