Skip to content

Commit 12d28cd

Browse files
committed
feat(annotations): broadcast live-stroke geometry to plugin_events_group
AnnotationBasePtr is not Python-bound, so Python plugins cannot subscribe to live_edit_event_group directly. Serialize the cumulative in-progress stroke via Annotation::serialise() and broadcast it as a JsonStore alongside (event_atom, annotation_data_atom, user_id, stroke_completed) via plugin_events_group(), so Python plugins can render partial strokes directly from event geometry instead of polling/hot-scanning bookmarks. Shapes (Square/Circle/Arrow/Line/ Ellipse) are only broadcast on pen-up, since a shape isn't a meaningful annotation until the drag completes. Also fix subscribe_to_plugin_events: BroadcastActor forwards messages via send_as(current_sender(), subscriber, msg), so a Python subscriber sees the owning actor as the sender, not the broadcast group. The 2-arg add_message_callback() only registered the group's address, so plugin_events_ messages were silently dropped. Pass the plugin's actor as the owner_actor (3rd arg), mirroring the same fix already applied to subscribe_to_event_group. Signed-off-by: Sam.Richards@taurich.org <Sam.Richards@taurich.org>
1 parent eb3d235 commit 12d28cd

2 files changed

Lines changed: 28 additions & 7 deletions

File tree

python/src/xstudio/plugin/plugin_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def subscribe_to_plugin_events(self, plugin, callback_method):
296296
raise Exception("Actor has no event group.")
297297

298298
return self.connection.link.add_message_callback(
299-
event_group, callback_method
299+
event_group, callback_method, plugin.remote
300300
)
301301

302302
def register_ui_panel_qml(self,

src/plugin/viewport_overlay/annotations/src/annotations_core_plugin.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,13 +1291,34 @@ void AnnotationsCore::broadcast_live_stroke(
12911291
if (user_edit_data->live_stroke)
12921292
anno->canvas().append_item(*(user_edit_data->live_stroke));
12931293

1294-
mail(
1295-
utility::event_atom_v,
1296-
annotation_data_atom_v,
1297-
AnnotationBasePtr(anno),
1298-
user_id,
1299-
stroke_completed)
1294+
AnnotationBasePtr anno_ptr(anno);
1295+
1296+
mail(utility::event_atom_v, annotation_data_atom_v, anno_ptr, user_id, stroke_completed)
13001297
.send(live_edit_event_group_);
1298+
1299+
// Python-accessible event: AnnotationBasePtr is not Python-bound, so broadcast
1300+
// the serialised geometry via plugin_events_ so Python plugins can render
1301+
// in-progress strokes directly, without polling/hot-scanning bookmarks.
1302+
// Shapes (as opposed to pen/brush strokes) are only broadcast on pen-up,
1303+
// since a shape isn't a meaningful annotation until the drag completes.
1304+
const bool is_shape = user_edit_data->item_type == Canvas::ItemType::Square ||
1305+
user_edit_data->item_type == Canvas::ItemType::Circle ||
1306+
user_edit_data->item_type == Canvas::ItemType::Arrow ||
1307+
user_edit_data->item_type == Canvas::ItemType::Line ||
1308+
user_edit_data->item_type == Canvas::ItemType::Ellipse;
1309+
1310+
if (!is_shape || stroke_completed) {
1311+
utility::Uuid plugin_uuid;
1312+
utility::JsonStore anno_json = anno_ptr->serialise(plugin_uuid);
1313+
1314+
mail(
1315+
utility::event_atom_v,
1316+
annotation_data_atom_v,
1317+
anno_json,
1318+
user_id,
1319+
stroke_completed)
1320+
.send(plugin_events_group());
1321+
}
13011322
}
13021323

13031324
void AnnotationsCore::broadcast_live_laser_stroke(

0 commit comments

Comments
 (0)