[Bf-blender-cvs] [7a8ac1b09b1] blender2.8: WM: message bus replacement for property notifiers

Campbell Barton noreply at git.blender.org
Mon Dec 4 10:29:57 CET 2017


Commit: 7a8ac1b09b1cf321f259b8eb9b832424d2c7bf5b
Author: Campbell Barton
Date:   Mon Nov 13 19:43:34 2017 +1100
Branches: blender2.8
https://developer.blender.org/rB7a8ac1b09b1cf321f259b8eb9b832424d2c7bf5b

WM: message bus replacement for property notifiers

Use dynamically generated message publish/subscribe
so buttons and manipulators update properly.

This resolves common glitches where manipulators weren't updating
as well as the UI when add-ons exposed properties which
hard coded listeners weren't checking for.

Python can also publish/scribe changes via `bpy.msgbus`.

See D2917

===================================================================

M	release/scripts/modules/bpy/__init__.py
M	source/blender/blenkernel/BKE_context.h
M	source/blender/blenkernel/BKE_screen.h
M	source/blender/blenkernel/intern/context.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/screen/screen_edit.c
M	source/blender/editors/space_buttons/space_buttons.c
M	source/blender/editors/space_file/space_file.c
M	source/blender/editors/space_time/space_time.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/editors/space_view3d/view3d_manipulator_camera.c
M	source/blender/editors/transform/transform_manipulator.c
M	source/blender/makesdna/DNA_windowmanager_types.h
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/python/intern/CMakeLists.txt
M	source/blender/python/intern/bpy.c
A	source/blender/python/intern/bpy_msgbus.c
A	source/blender/python/intern/bpy_msgbus.h
M	source/blender/windowmanager/CMakeLists.txt
A	source/blender/windowmanager/WM_message.h
M	source/blender/windowmanager/WM_types.h
M	source/blender/windowmanager/intern/wm.c
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_files.c
M	source/blender/windowmanager/intern/wm_init_exit.c
M	source/blender/windowmanager/manipulators/WM_manipulator_api.h
M	source/blender/windowmanager/manipulators/WM_manipulator_types.h
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
M	source/blender/windowmanager/manipulators/wm_manipulator_fn.h
A	source/blender/windowmanager/message_bus/intern/wm_message_bus.c
A	source/blender/windowmanager/message_bus/intern/wm_message_bus_intern.h
A	source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c
A	source/blender/windowmanager/message_bus/intern/wm_message_bus_static.c
A	source/blender/windowmanager/message_bus/wm_message_bus.h

===================================================================

diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 6312c25065f..a80135a59e1 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -39,6 +39,7 @@ from _bpy import (
     app,
     context,
     data,
+    msgbus,
     props,
     types,
 )
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 5628c650d34..75e658613cb 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -156,6 +156,7 @@ struct ARegion *CTX_wm_region(const bContext *C);
 void *CTX_wm_region_data(const bContext *C);
 struct ARegion *CTX_wm_menu(const bContext *C);
 struct wmManipulatorGroup *CTX_wm_manipulator_group(const bContext *C);
+struct wmMsgBus *CTX_wm_message_bus(const bContext *C);
 struct ReportList *CTX_wm_reports(const bContext *C);
 
 struct View3D *CTX_wm_view3d(const bContext *C);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 8ba103b915e..6669f3103da 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -56,6 +56,7 @@ struct wmWindow;
 struct wmWindowManager;
 struct WorkSpace;
 struct GPUFXSettings;
+struct wmMsgBus;
 
 #include "BLI_compiler_attrs.h"
 
@@ -139,6 +140,12 @@ typedef struct ARegionType {
 	/* contextual changes should be handled here */
 	void (*listener)(struct bScreen *, struct ScrArea *, struct ARegion *,
 	                 struct wmNotifier *, const struct Scene *scene);
+	/* Optional callback to generate subscriptions. */
+	void (*message_subscribe)(
+	        const struct bContext *C,
+	        struct WorkSpace *workspace, struct Scene *scene,
+	        struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar,
+	        struct wmMsgBus *mbus);
 
 	void (*free)(struct ARegion *);
 
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 855216d089b..7b7a7c8b7af 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -679,6 +679,11 @@ struct wmManipulatorGroup *CTX_wm_manipulator_group(const bContext *C)
 	return C->wm.manipulator_group;
 }
 
+struct wmMsgBus *CTX_wm_message_bus(const bContext *C)
+{
+	return C->wm.manager ? C->wm.manager->message_bus : NULL;
+}
+
 struct ReportList *CTX_wm_reports(const bContext *C)
 {
 	if (C->wm.manager)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e6d2be02977..9e09d2e0bd1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6531,6 +6531,8 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
 	wm->addonconf = NULL;
 	wm->userconf = NULL;
 	
+	wm->message_bus = NULL;
+
 	BLI_listbase_clear(&wm->jobs);
 	BLI_listbase_clear(&wm->drags);
 	
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 23e65011387..89a6828a59d 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -55,6 +55,9 @@ struct ARegion;
 struct uiBlock;
 struct rcti;
 struct Main;
+struct wmMsgBus;
+struct wmMsgSubscribeKey;
+struct wmMsgSubscribeValue;
 
 /* regions */
 void    ED_region_do_listen(
@@ -86,6 +89,18 @@ void    ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
 float	ED_region_blend_factor(struct ARegion *ar);
 void	ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
 
+/* message_bus callbacks */
+void ED_region_do_msg_notify_tag_redraw(
+        struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val);
+void ED_area_do_msg_notify_tag_refresh(
+        struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val);
+
+/* message bus */
+void ED_region_message_subscribe(
+        struct bContext *C,
+        struct WorkSpace *workspace, struct Scene *scene,
+        struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
+        struct wmMsgBus *mbus);
 
 /* spaces */
 void    ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index e2a6ca65b51..eba31a21094 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -73,6 +73,7 @@ struct bNodeSocket;
 struct wmDropBox;
 struct wmDrag;
 struct wmEvent;
+struct wmMsgBus;
 
 typedef struct uiBut uiBut;
 typedef struct uiBlock uiBlock;
@@ -875,6 +876,8 @@ uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int s
 void UI_block_layout_set_current(uiBlock *block, uiLayout *layout);
 void UI_block_layout_resolve(uiBlock *block, int *x, int *y);
 
+void UI_region_message_subscribe(struct ARegion *ar, struct wmMsgBus *mbus);
+
 uiBlock *uiLayoutGetBlock(uiLayout *layout);
 
 void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index fbdd48d42a7..9e6d9f23442 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -41,6 +41,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_userdef_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BLI_math.h"
 #include "BLI_listbase.h"
@@ -69,11 +70,14 @@
 #include "WM_api.h"
 #include "WM_types.h"
 #include "wm_subwindow.h"
+#include "WM_message.h"
 
 #include "RNA_access.h"
 
 #include "BPY_extern.h"
 
+#include "ED_screen.h"
+
 #include "IMB_colormanagement.h"
 
 #include "interface_intern.h"
@@ -1453,6 +1457,40 @@ void UI_block_draw(const bContext *C, uiBlock *block)
 	ui_draw_links(block);
 }
 
+static void ui_block_message_subscribe(ARegion *ar, struct wmMsgBus *mbus, uiBlock *block)
+{
+	uiBut *but_prev = NULL;
+	/* possibly we should keep the region this block is contained in? */
+	for (uiBut *but = block->buttons.first; but; but = but->next) {
+		if (but->rnapoin.type && but->rnaprop) {
+			/* quick check to avoid adding buttons representing a vector, multiple times. */
+			if ((but_prev &&
+			    (but_prev->rnaprop == but->rnaprop) &&
+			    (but_prev->rnapoin.type == but->rnapoin.type) &&
+			    (but_prev->rnapoin.data == but->rnapoin.data) &&
+			    (but_prev->rnapoin.id.data == but->rnapoin.id.data)) == false)
+			{
+				/* TODO: could make this into utility function. */
+				WM_msg_subscribe_rna(
+				        mbus, &but->rnapoin, but->rnaprop,
+				        &(const wmMsgSubscribeValue){
+				            .owner = ar,
+				            .user_data = ar,
+				            .notify = ED_region_do_msg_notify_tag_redraw,
+				        }, __func__);
+				but_prev = but;
+			}
+		}
+	}
+}
+
+void UI_region_message_subscribe(ARegion *ar, struct wmMsgBus *mbus)
+{
+	for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
+		ui_block_message_subscribe(ar, mbus, block);
+	}
+}
+
 /* ************* EVENTS ************* */
 
 /**
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 315b02cde93..08d92dfc9ff 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -51,6 +51,7 @@
 
 #include "WM_api.h"
 #include "WM_types.h"
+#include "WM_message.h"
 #include "wm_subwindow.h"
 
 #include "ED_screen.h"
@@ -511,6 +512,33 @@ void ED_region_set(const bContext *C, ARegion *ar)
 	ED_region_pixelspace(ar);
 }
 
+/* Follow wmMsgNotifyFn spec */
+void ED_region_do_msg_notify_tag_redraw(
+        bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
+{
+	ARegion *ar = msg_val->owner;
+	ED_region_tag_redraw(ar);
+
+	/* This avoids _many_ situations where header/properties control display settings.
+	 * the common case is space properties in the header */
+	if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_UI)) {
+		while (ar && ar->prev) {
+			ar = ar->prev;
+		}
+		for (; ar; ar = ar->next) {
+			if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS)) {
+				ED_region_tag_redraw(ar);
+			}
+		}
+	}
+}
+/* Follow wmMsgNotifyFn spec */
+void ED_area_do_msg_notify_tag_refresh(
+        bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
+{
+	ScrArea *sa = msg_val->user_data;
+	ED_area_tag_refresh(sa);
+}
 
 /* only exported for WM */
 void ED_region_do_draw(bContext *C, ARegion *ar)
@@ -589,6 +617,37 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
 			region_draw_emboss(ar, &ar->winrct);
 		}
 	}
+
+	/* We may want to detach message-subscriptions from drawing. */
+	{
+		WorkSpace *workspace = CTX_wm_workspace(C);
+		wmWindowManager *wm = CTX_wm_manager(C);
+		bScreen *screen = WM_window_get_active_screen(win);
+		Scene *scene = CTX_data_scene(C);
+		struct wmMsgBus *mbus = wm->message_bus;
+		WM_msgbus_clear_by_owner(mbus, ar);
+
+		/* Cheat, always subscribe to this space type properties.
+		 *
+		 * This covers most cases and avoids copy-paste similar code for each space type.
+		 */
+		if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS, RGN_TYPE_UI, RGN_TYPE_TOOLS)) {
+			SpaceLink *sl = sa->spacedata.first;
+
+			PointerRNA ptr;
+			RNA_pointer_create(&screen->id, &RNA_Space, sl, &ptr);
+
+			wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+				.owner = ar,
+				.user_data = ar,
+				.notify = ED_region_do_msg_notify_tag_redraw,
+			};
+			/* All properties for this space type. */
+			WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__);
+		}
+
+		ED_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
+	}
 }
 
 /* **********************************
@@ -2595,3 +2654,25 @@ void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segme
 		immUnbindProgram();
 	}
 }
+
+/**
+ * Generate subscriptions for this region.
+ */
+void ED_region_message_subscribe(
+        bContext *C,
+        struct WorkSpace *workspace, struct Scene *scene,
+        struct bScreen *screen, struct ScrArea *sa, str

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list