Fix crash re-registering the same manipulator type
Wasn't unlinking from the group instance.
This commit is contained in:
parent
d221a999cb
commit
02257ace22
|
@ -462,12 +462,10 @@ static StructRNA *rna_Manipulator_register(
|
|||
return dummywt.ext.srna;
|
||||
}
|
||||
|
||||
static void rna_Manipulator_unregister(struct Main *UNUSED(bmain), StructRNA *type)
|
||||
static void rna_Manipulator_unregister(struct Main *bmain, StructRNA *type)
|
||||
{
|
||||
wmManipulatorType *wt = RNA_struct_blender_type_get(type);
|
||||
|
||||
/* TODO, remove widgets from interface! */
|
||||
|
||||
if (!wt)
|
||||
return;
|
||||
|
||||
|
@ -475,7 +473,7 @@ static void rna_Manipulator_unregister(struct Main *UNUSED(bmain), StructRNA *ty
|
|||
|
||||
RNA_struct_free_extension(type, &wt->ext);
|
||||
|
||||
WM_manipulatortype_remove_ptr(wt);
|
||||
WM_manipulatortype_remove_ptr(NULL, bmain, wt);
|
||||
|
||||
RNA_struct_free(&BLENDER_RNA, type);
|
||||
}
|
||||
|
|
|
@ -113,8 +113,8 @@ void WM_manipulator_properties_free(struct PointerRNA *ptr);
|
|||
const struct wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet);
|
||||
void WM_manipulatortype_append(void (*wtfunc)(struct wmManipulatorType *));
|
||||
void WM_manipulatortype_append_ptr(void (*mnpfunc)(struct wmManipulatorType *, void *), void *userdata);
|
||||
bool WM_manipulatortype_remove(const char *idname);
|
||||
void WM_manipulatortype_remove_ptr(struct wmManipulatorType *wt);
|
||||
bool WM_manipulatortype_remove(struct bContext *C, struct Main *bmain, const char *idname);
|
||||
void WM_manipulatortype_remove_ptr(struct bContext *C, struct Main *bmain, struct wmManipulatorType *wt);
|
||||
void WM_manipulatortype_iter(struct GHashIterator *ghi);
|
||||
|
||||
/* wm_manipulator_group_type.c */
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
@ -36,6 +41,8 @@
|
|||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
/* only for own init/exit calls (wm_manipulatortype_init/wm_manipulatortype_free) */
|
||||
#include "wm.h"
|
||||
|
||||
|
@ -123,16 +130,50 @@ static void manipulatortype_free(wmManipulatorType *wt)
|
|||
MEM_freeN(wt);
|
||||
}
|
||||
|
||||
void WM_manipulatortype_remove_ptr(wmManipulatorType *wt)
|
||||
/**
|
||||
* \param C: May be NULL.
|
||||
*/
|
||||
static void manipulatortype_unlink(
|
||||
bContext *C, Main *bmain, wmManipulatorType *wt)
|
||||
{
|
||||
/* Free instances. */
|
||||
for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
|
||||
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
|
||||
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
|
||||
for (ARegion *ar = lb->first; ar; ar = ar->next) {
|
||||
wmManipulatorMap *mmap = ar->manipulator_map;
|
||||
if (mmap) {
|
||||
wmManipulatorGroup *mgroup;
|
||||
for (mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) {
|
||||
for (wmManipulator *mpr = mgroup->manipulators.first, *mpr_next; mpr; mpr = mpr_next) {
|
||||
mpr_next = mpr->next;
|
||||
BLI_assert(mgroup->parent_mmap == mmap);
|
||||
if (mpr->type == wt) {
|
||||
WM_manipulator_free(&mgroup->manipulators, mgroup->parent_mmap, mpr, C);
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WM_manipulatortype_remove_ptr(bContext *C, Main *bmain, wmManipulatorType *wt)
|
||||
{
|
||||
BLI_assert(wt == WM_manipulatortype_find(wt->idname, false));
|
||||
|
||||
BLI_ghash_remove(global_manipulatortype_hash, wt->idname, NULL, NULL);
|
||||
|
||||
manipulatortype_unlink(C, bmain, wt);
|
||||
|
||||
manipulatortype_free(wt);
|
||||
}
|
||||
|
||||
bool WM_manipulatortype_remove(const char *idname)
|
||||
bool WM_manipulatortype_remove(bContext *C, Main *bmain, const char *idname)
|
||||
{
|
||||
wmManipulatorType *wt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
|
||||
|
||||
|
@ -140,7 +181,7 @@ bool WM_manipulatortype_remove(const char *idname)
|
|||
return false;
|
||||
}
|
||||
|
||||
WM_manipulatortype_remove_ptr(wt);
|
||||
WM_manipulatortype_remove_ptr(C, bmain, wt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue