Skip to content

fix(python): fix event routing sender mismatch for playhead events#300

Closed
richardssam wants to merge 1 commit into
AcademySoftwareFoundation:developfrom
richardssam:pr/python-event-routing
Closed

fix(python): fix event routing sender mismatch for playhead events#300
richardssam wants to merge 1 commit into
AcademySoftwareFoundation:developfrom
richardssam:pr/python-event-routing

Conversation

@richardssam

Copy link
Copy Markdown
Contributor

Linked issues

N/A

Summarize your change.

Fixes EventToPythonThreadLockerActor so that playhead and selection events
subscribed from Python are actually delivered, and prevents a SIGSEGV crash
when the subscribed actor is torn down during a timeline switch.

Describe the reason for the change.

When a C++ event group (e.g. a Playhead's broadcast group) sends a message, the
CAF sender is the owner actor (the Playhead itself), not the event-group
actor that the Python code subscribed to. EventToPythonThreadLockerActor
looked up callbacks by sender address, found no match, and silently dropped the
message. This meant subscribe_to_playhead_events and similar subscriptions
delivered nothing.

A second problem: the broadcast_down_atom handler was a TODO no-op. When the
subscribed owner actor died (e.g. on a timeline switch), any in-flight message
attributed to its address was dispatched to a now-invalid callback_func,
causing a signal 11 (SIGSEGV) crash.

Describe what you have tested and on which operating system.

Tested on macOS: a Python plugin using subscribe_to_playhead_events now
receives position_atom events on every frame change. Timeline switches (which
tear down and recreate the Playhead actor) no longer crash the application.

Add a list of changes, and note any that might need special attention during the review.

  • src/python_module/src/py_context.cpp:

    • Add callback_to_event_group_ map (Uuid → caf::actor) to track which
      event-group actor owns each callback, enabling correct leave_broadcast
      when a subscription is cancelled.
    • Add a new 3-argument (events_source, owner_actor, callback_id) message
      handler that registers owner_actor's address as an additional routing key
      for the same callback, so messages sent by the owner are routed correctly.
    • Implement broadcast_down_atom handler: on actor death, walk
      actor_to_callback_uuid_ for the dead address, erase the corresponding
      entries from callback_to_event_group_, then remove the actor entry.
    • Move the leave_broadcast send into the Uuid-cancellation handler so it
      uses callback_to_event_group_ for O(1) lookup instead of a linear scan.
    • Extend py_add_message_callback to accept an optional third argument
      (owner actor), passing it to the new 3-argument handler when present.

    Note for reviewers: the broadcast_down_atom fix addresses a latent crash
    that would have occurred for any Python subscription whose source actor could
    be destroyed at runtime (playheads, selection actors). The original TODO
    comment acknowledged this was unfinished.

  • python/src/xstudio/api/module.py:

    • subscribe_to_event_group passes the owner actor as the third argument to
      add_message_callback when one is available.

If possible, provide screenshots.

N/A

This was developed with the assistance of claude code.

Resolve issue where playhead events (position_atom, etc.) were silently
dropped in the Python API. When C++ event groups broadcast messages, the
sender is set to the owner actor (e.g. Playhead) rather than the event
group address.

- Add actor_to_callback_uuid_ map in EventToPythonThreadLockerActor to
  track the optional owner actor per callback ID.
- Route incoming messages via the owner actor address as a fallback when
  the sender does not match any event-group key.
- Implement broadcast_down_atom handler to purge stale callback entries
  when a subscribed owner actor dies, preventing a SIGSEGV on timeline
  switches where the old playhead is torn down mid-dispatch.
- Update subscribe_to_event_group in module.py to pass the owner actor
  as the third argument to add_message_callback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@richardssam

Copy link
Copy Markdown
Contributor Author

Sorry, ignore this its a duplicate.

@richardssam richardssam closed this Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant