[Bf-blender-cvs] [643df8fdab7] custom-manipulators: Add support for delayed removal

Campbell Barton noreply at git.blender.org
Thu Jun 15 22:24:07 CEST 2017


Commit: 643df8fdab78f623284d1b81ee73088c57f4c96a
Author: Campbell Barton
Date:   Fri Jun 16 06:24:42 2017 +1000
Branches: custom-manipulators
https://developer.blender.org/rB643df8fdab78f623284d1b81ee73088c57f4c96a

Add support for delayed removal

This is needed so manipulators can tag themselves for removal
without causing problems from freeing data within a callback.

Also use properties within the dial manipulator and fix an error where
removing a wmManipulatorGroupType didn't remove its keymap.

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

M	source/blender/editors/manipulator_library/dial3d_manipulator.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.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c

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

diff --git a/source/blender/editors/manipulator_library/dial3d_manipulator.c b/source/blender/editors/manipulator_library/dial3d_manipulator.c
index 1db87ac9a3d..55d5f257eb4 100644
--- a/source/blender/editors/manipulator_library/dial3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/dial3d_manipulator.c
@@ -75,6 +75,9 @@ typedef struct DialManipulator {
 typedef struct DialInteraction {
 	float init_mval[2];
 
+	/* only for when using properties */
+	float init_prop_angle;
+
 	/* cache the last angle to detect rotations bigger than -/+ PI */
 	float last_angle;
 	/* number of full rotations */
@@ -348,8 +351,15 @@ static void manipulator_dial_modal(bContext *C, wmManipulator *mpr, const wmEven
 	dial_ghostarc_get_angles(dial, event, CTX_wm_region(C), mat, co_outer, &angle_ofs, &angle_delta);
 
 	DialInteraction *inter = dial->manipulator.interaction_data;
+
 	inter->output.angle_delta = angle_delta;
 	inter->output.angle_ofs = angle_ofs;
+
+	/* set the property for the operator and call its modal function */
+	wmManipulatorProperty *mpr_prop = WM_manipulator_property_find(mpr, "offset");
+	if (mpr_prop && WM_manipulator_property_is_valid(mpr_prop)) {
+		WM_manipulator_property_value_set(C, mpr, mpr_prop, inter->init_prop_angle + angle_delta);
+	}
 }
 
 static void manipulator_dial_invoke(
@@ -360,6 +370,11 @@ static void manipulator_dial_invoke(
 	inter->init_mval[0] = event->mval[0];
 	inter->init_mval[1] = event->mval[1];
 
+	wmManipulatorProperty *mpr_prop = WM_manipulator_property_find(mpr, "offset");
+	if (mpr_prop && WM_manipulator_property_is_valid(mpr_prop)) {
+		inter->init_prop_angle = WM_manipulator_property_value_get(mpr, mpr_prop);
+	}
+
 	mpr->interaction_data = inter;
 }
 
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
index c24d1db3ba2..076c0f89a88 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
@@ -104,7 +104,8 @@ struct wmManipulatorGroupTypeRef *WM_manipulatorgrouptype_append_and_link(
 
 /* Dynamic Updates (for RNA runtime registration) */
 void WM_manipulatorconfig_update_tag_init(struct wmManipulatorMapType *mmap_type, struct wmManipulatorGroupType *wgt);
-void WM_manipulatorconfig_update(const struct Main *bmain);
+void WM_manipulatorconfig_update_tag_remove(struct wmManipulatorMapType *mmap_type, struct wmManipulatorGroupType *wgt);
+void WM_manipulatorconfig_update(struct Main *bmain);
 
 
 /* wm_maniulator_property.c */
@@ -196,4 +197,11 @@ void WM_manipulator_group_remove_ptr(
         struct Main *bmain, struct wmManipulatorGroupType *wgt);
 void WM_manipulator_group_remove(struct Main *bmain, const char *idname);
 
+void WM_manipulator_group_remove_ptr_delayed_ex(
+        struct wmManipulatorGroupType *wgt,
+        struct wmManipulatorMapType *mmap_type);
+void WM_manipulator_group_remove_ptr_delayed(
+        struct wmManipulatorGroupType *wgt);
+void WM_manipulator_group_remove_delayed(const char *idname);
+
 #endif  /* __WM_MANIPULATOR_API_H__ */
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
index 8a4f8ba2e00..cb39ff21be1 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
@@ -240,6 +240,8 @@ typedef struct wmManipulatorGroupType {
 
 	/* keymap created with callback from above */
 	struct wmKeyMap *keymap;
+	/* Only for convenient removal. */
+	struct wmKeyConfig *keyconf;
 
 	/* Disable for now, maybe some day we want properties. */
 #if 0
@@ -283,6 +285,7 @@ typedef struct wmManipulatorGroup {
 enum eManipulatorMapTypeUpdateFlags {
 	/* A new type has been added, needs to be initialized for all views. */
 	WM_MANIPULATORMAPTYPE_UPDATE_INIT = (1 << 0),
+	WM_MANIPULATORMAPTYPE_UPDATE_REMOVE = (1 << 1),
 };
 
 /**
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
index ae7353971f0..b71cfdb15cf 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -172,8 +172,13 @@ void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmMa
 	}
 	BLI_freelistN(&mpr->properties);
 
-	if (manipulatorlist)
+	if (manipulatorlist) {
 		BLI_remlink(manipulatorlist, mpr);
+	}
+
+	BLI_assert(mmap->mmap_context.highlight != mpr);
+	BLI_assert(mmap->mmap_context.active != mpr);
+
 	MEM_freeN(mpr);
 }
 
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
index 3deef0cee5c..bfbdfbe57df 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
@@ -608,6 +608,10 @@ void WM_manipulatormaptype_group_unlink(
 		BLI_remlink(&mmap_type->grouptype_refs, wgt_ref);
 		WM_manipulatormaptype_group_free(wgt_ref);
 	}
+
+	/* Note, we may want to keep this keymap for editing */
+	WM_keymap_remove(wgt->keyconf, wgt->keymap);
+
 	BLI_assert(WM_manipulatormaptype_group_find_ptr(mmap_type, wgt) == NULL);
 }
 
@@ -615,6 +619,7 @@ void wm_manipulatorgrouptype_setup_keymap(
         wmManipulatorGroupType *wgt, wmKeyConfig *keyconf)
 {
 	wgt->keymap = wgt->setup_keymap(wgt, keyconf);
+	wgt->keyconf = keyconf;
 }
 
 /** \} */ /* wmManipulatorGroupType */
@@ -678,4 +683,27 @@ void WM_manipulator_group_remove(struct Main *bmain, const char *idname)
 	WM_manipulator_group_remove_ptr(bmain, wgt);
 }
 
+/* delayed versions */
+
+void WM_manipulator_group_remove_ptr_delayed_ex(
+        wmManipulatorGroupType *wgt,
+        wmManipulatorMapType *mmap_type)
+{
+	WM_manipulatorconfig_update_tag_remove(mmap_type, wgt);
+}
+
+void WM_manipulator_group_remove_ptr_delayed(
+        wmManipulatorGroupType *wgt)
+{
+	wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(&wgt->mmap_params);
+	WM_manipulator_group_remove_ptr_delayed_ex(wgt, mmap_type);
+}
+
+void WM_manipulator_group_remove_delayed(const char *idname)
+{
+	wmManipulatorGroupType *wgt = WM_manipulatorgrouptype_find(idname, false);
+	BLI_assert(wgt != NULL);
+	WM_manipulator_group_remove_ptr_delayed(wgt);
+}
+
 /** \} */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
index 123c46f9c50..4574a1eb2ce 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
@@ -66,6 +66,7 @@ static ListBase manipulatormaptypes = {NULL, NULL};
 /* so operator removal can trigger update */
 enum {
 	WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT = (1 << 0),
+	WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE = (1 << 1),
 };
 
 static char wm_mmap_type_update_flag = 0;
@@ -239,9 +240,10 @@ static void manipulatormap_prepare_drawing(
  */
 static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators)
 {
-	if (!mmap)
+	/* Can be empty if we're dynamically added and removed. */
+	if ((mmap == NULL) || BLI_listbase_is_empty(&mmap->groups)) {
 		return;
-	BLI_assert(!BLI_listbase_is_empty(&mmap->groups));
+	}
 
 	const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE);
 
@@ -778,7 +780,8 @@ void wm_manipulators_keymap(wmKeyConfig *keyconf)
  * \{ */
 
 
-void WM_manipulatorconfig_update_tag_init(wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt)
+void WM_manipulatorconfig_update_tag_init(
+        wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt)
 {
 	/* tag for update on next use */
 	mmap_type->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_INIT;
@@ -787,11 +790,21 @@ void WM_manipulatorconfig_update_tag_init(wmManipulatorMapType *mmap_type, wmMan
 	wm_mmap_type_update_flag |= WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT;
 }
 
+void WM_manipulatorconfig_update_tag_remove(
+        wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt)
+{
+	/* tag for update on next use */
+	mmap_type->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_REMOVE;
+	wgt->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_REMOVE;
+
+	wm_mmap_type_update_flag |= WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE;
+}
+
 /**
  * Run incase new types have been added (runs often, early exit where possible).
  * Follows #WM_keyconfig_update concentions.
  */
-void WM_manipulatorconfig_update(const struct Main *bmain)
+void WM_manipulatorconfig_update(struct Main *bmain)
 {
 	if (G.background)
 		return;
@@ -799,6 +812,26 @@ void WM_manipulatorconfig_update(const struct Main *bmain)
 	if (wm_mmap_type_update_flag == 0)
 		return;
 
+	if (wm_mmap_type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE) {
+		for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first;
+		     mmap_type;
+		     mmap_type = mmap_type->next)
+		{
+			if (mmap_type->type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE) {
+				mmap_type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_REMOVE;
+				for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first, *wgt_ref_next;
+				     wgt_ref;
+				     wgt_ref = wgt_ref_next)
+				{
+					wgt_ref_next = wgt_ref->next;
+					WM_manipulatormaptype_group_unlink(NULL, bmain, mmap_type, wgt_ref->type);
+				}
+			}
+		}
+
+		wm_mmap_type_update_flag &= ~WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE;
+	}
+
 	if (wm_mmap_type_update_flag & WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT) {
 		for (wmManipulatorMapType *mmap_type = manipulatormaptypes.first;
 		     mmap_type;




More information about the Bf-blender-cvs mailing list