Fix crash handling manipulator events before drawing
authorCampbell Barton <ideasman42@gmail.com>
Thu, 24 Aug 2017 14:03:45 +0000 (00:03 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 24 Aug 2017 14:20:14 +0000 (00:20 +1000)
source/blender/windowmanager/manipulators/WM_manipulator_types.h
source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c
source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c

index 82bf556ce205353aae62016e0eec9efc806ad29b..23c0fa305a969b7a0fd574fa6642ab3a5af85981 100644 (file)
@@ -97,6 +97,15 @@ typedef enum eWM_ManipulatorGroupTypeFlag {
        WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL = (1 << 5),
 } eWM_ManipulatorGroupTypeFlag;
 
+
+/**
+ * #wmManipulatorGroup.init_flag
+ */
+typedef enum eWM_ManipulatorGroupInitFlag {
+       /* mgroup has been initialized */
+       WM_MANIPULATORGROUP_INIT_SETUP = (1 << 0),
+} eWM_ManipulatorGroupInitFlag;
+
 /**
  * #wmManipulatorMapType.type_update_flag
  * Manipulator-map type update flag
@@ -362,7 +371,7 @@ typedef struct wmManipulatorGroup {
 
        void *customdata;
        void (*customdata_free)(void *); /* for freeing customdata from above */
-       int init_flag; /* private (C source only) */
+       eWM_ManipulatorGroupInitFlag init_flag;
 } wmManipulatorGroup;
 
 /* -------------------------------------------------------------------- */
index 808051560bcb20b8fc105ca04075d3081cc93e80..94064c84701e08157ef430eba18e6cdb9ac41f22 100644 (file)
  *
  * \{ */
 
-/* wmManipulatorGroup.flag */
-enum {
-       WM_MANIPULATORGROUP_INITIALIZED = (1 << 2), /* mgroup has been initialized */
-};
-
 /**
  * Create a new manipulator-group from \a wgt.
  */
@@ -179,7 +174,7 @@ void wm_manipulatorgroup_intersectable_manipulators_to_list(const wmManipulatorG
 void wm_manipulatorgroup_ensure_initialized(wmManipulatorGroup *mgroup, const bContext *C)
 {
        /* prepare for first draw */
-       if (UNLIKELY((mgroup->init_flag & WM_MANIPULATORGROUP_INITIALIZED) == 0)) {
+       if (UNLIKELY((mgroup->init_flag & WM_MANIPULATORGROUP_INIT_SETUP) == 0)) {
                mgroup->type->setup(C, mgroup);
 
                /* Not ideal, initialize keymap here, needed for RNA runtime generated manipulators. */
@@ -190,7 +185,7 @@ void wm_manipulatorgroup_ensure_initialized(wmManipulatorGroup *mgroup, const bC
                        BLI_assert(wgt->keymap != NULL);
                }
 
-               mgroup->init_flag |= WM_MANIPULATORGROUP_INITIALIZED;
+               mgroup->init_flag |= WM_MANIPULATORGROUP_INIT_SETUP;
        }
 }
 
index 06578fee5550d236c8f97add6c19f6d867653bcd..8682ec4e390df8a2c5760fbb2dc82a70d460a417 100644 (file)
@@ -75,6 +75,7 @@ struct wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
 void wm_manipulatorgroup_intersectable_manipulators_to_list(
         const struct wmManipulatorGroup *mgroup, struct ListBase *listbase);
 void wm_manipulatorgroup_ensure_initialized(struct wmManipulatorGroup *mgroup, const struct bContext *C);
+bool wm_manipulatorgroup_is_initialized(const wmManipulatorGroup *mgroup);
 bool wm_manipulatorgroup_is_visible(const struct wmManipulatorGroup *mgroup, const struct bContext *C);
 bool wm_manipulatorgroup_is_visible_in_drawstep(
         const struct wmManipulatorGroup *mgroup, const eWM_ManipulatorMapDrawStep drawstep);
index 9155c03db2a9dac29183c21fa5fd287067ef152d..cece24df85f967339072c6d7939de08526cbfae6 100644 (file)
@@ -560,6 +560,14 @@ wmManipulator *wm_manipulatormap_highlight_find(
        ListBase visible_3d_manipulators = {NULL};
 
        for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) {
+
+               /* If it were important we could initialize here,
+                * but this only happens when events are handled before drawing,
+                * just skip to keep code-path for initializing manipulators simple. */
+               if ((mgroup->init_flag & WM_MANIPULATORGROUP_INIT_SETUP) == 0) {
+                       continue;
+               }
+
                if (wm_manipulatorgroup_is_visible(mgroup, C)) {
                        if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) {
                                if ((mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_3D] & MANIPULATORMAP_IS_REFRESH_CALLBACK) &&