Fix/workaround T37073: Crash updating custom props visible in the UI
This commit is contained in:
parent
c8ef04e726
commit
3346ab0348
|
@ -91,6 +91,7 @@ void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src)
|
|||
void IDP_SyncGroupTypes(struct IDProperty *dest, const struct IDProperty *src, const bool do_arraylen) ATTR_NONNULL();
|
||||
void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL();
|
||||
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
|
||||
void IDP_ReplaceInGroup_ex(struct IDProperty *group, struct IDProperty *prop, struct IDProperty *prop_exist);
|
||||
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) ATTR_NONNULL();
|
||||
bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
|
||||
bool IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous,
|
||||
|
|
|
@ -571,18 +571,18 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src)
|
|||
* Checks if a property with the same name as prop exists, and if so replaces it.
|
||||
* Use this to preserve order!
|
||||
*/
|
||||
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
|
||||
void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist)
|
||||
{
|
||||
IDProperty *loop;
|
||||
|
||||
BLI_assert(group->type == IDP_GROUP);
|
||||
|
||||
if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) {
|
||||
BLI_insertlinkafter(&group->data.group, loop, prop);
|
||||
BLI_assert(prop_exist == IDP_GetPropertyFromGroup(group, prop->name));
|
||||
|
||||
if ((prop_exist = IDP_GetPropertyFromGroup(group, prop->name))) {
|
||||
BLI_insertlinkafter(&group->data.group, prop_exist, prop);
|
||||
|
||||
BLI_remlink(&group->data.group, loop);
|
||||
IDP_FreeProperty(loop);
|
||||
MEM_freeN(loop);
|
||||
BLI_remlink(&group->data.group, prop_exist);
|
||||
IDP_FreeProperty(prop_exist);
|
||||
MEM_freeN(prop_exist);
|
||||
}
|
||||
else {
|
||||
group->len++;
|
||||
|
@ -590,6 +590,13 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
|
|||
}
|
||||
}
|
||||
|
||||
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
|
||||
{
|
||||
IDProperty *prop_exist = IDP_GetPropertyFromGroup(group, prop->name);
|
||||
|
||||
IDP_ReplaceInGroup_ex(group, prop, prop_exist);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a property is missing in \a dest, add it.
|
||||
*/
|
||||
|
|
|
@ -510,7 +510,22 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
|
|||
MEM_freeN(prop);
|
||||
}
|
||||
else {
|
||||
IDP_ReplaceInGroup(group, prop);
|
||||
IDProperty *prop_exist;
|
||||
|
||||
/* avoid freeing when types match incase they are referenced by the UI, see: T37073
|
||||
* obviously this isn't a complete solution, but helps for common cases. */
|
||||
prop_exist = IDP_GetPropertyFromGroup(group, prop->name);
|
||||
if ((prop_exist != NULL) &&
|
||||
(prop_exist->type == prop->type) &&
|
||||
(prop_exist->subtype == prop->subtype))
|
||||
{
|
||||
IDP_FreeProperty(prop_exist);
|
||||
*prop_exist = *prop;
|
||||
MEM_freeN(prop);
|
||||
}
|
||||
else {
|
||||
IDP_ReplaceInGroup_ex(group, prop, prop_exist);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue