Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/makesrna/intern/rna_rna.c')
-rw-r--r--source/blender/makesrna/intern/rna_rna.c1130
1 files changed, 1130 insertions, 0 deletions
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 80aa5eff44a..53b98928c31 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -130,6 +130,9 @@ const EnumPropertyItem rna_enum_property_unit_items[] = {
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
+#include "BLI_string.h"
+
+#include "BKE_library_override.h"
/* Struct */
@@ -588,6 +591,13 @@ static int rna_Property_animatable_get(PointerRNA *ptr)
return (prop->flag & PROP_ANIMATABLE) != 0;
}
+static int rna_Property_overridable_get(PointerRNA *ptr)
+{
+ PropertyRNA *prop = (PropertyRNA *)ptr->data;
+
+ return (prop->flag_override & PROPOVERRIDE_OVERRIDABLE_STATIC) != 0;
+}
+
static int rna_Property_use_output_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
@@ -1106,6 +1116,1121 @@ static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key
return false;
}
+/* Default override (and compare) callbacks. */
+
+/* Ensures it makes sense to go inside the pointers to compare their content
+ * (if they are IDs, or have different names or RNA type, then this would be meaningless). */
+static bool rna_property_override_diff_propptr_validate_diffing(
+ PointerRNA *propptr_a, PointerRNA *propptr_b, const bool no_prop_name,
+ bool *r_is_id, bool *r_is_null, bool *r_is_type_diff,
+ char **r_propname_a, char *propname_a_buff, size_t propname_a_buff_size,
+ char **r_propname_b, char *propname_b_buff, size_t propname_b_buff_size)
+{
+ BLI_assert(propptr_a != NULL);
+
+ bool is_valid_for_diffing = true;
+ const bool do_force_name = !no_prop_name && r_propname_a != NULL;
+
+ if (do_force_name) {
+ BLI_assert(r_propname_a != NULL);
+ BLI_assert(r_propname_b != NULL);
+ }
+
+ *r_is_id = *r_is_null = *r_is_type_diff = false;
+
+ /* Beware, PointerRNA_NULL has no type and is considered a 'blank page'! */
+ if (propptr_a->type == NULL) {
+ if (propptr_b == NULL || propptr_b->type == NULL) {
+ *r_is_null = true;
+ }
+ else {
+ *r_is_id = RNA_struct_is_ID(propptr_b->type);
+ *r_is_null = true;
+ *r_is_type_diff = true;
+ }
+ is_valid_for_diffing = false;
+ }
+ else {
+ *r_is_id = RNA_struct_is_ID(propptr_a->type);
+ *r_is_null = *r_is_type_diff = (ELEM(NULL, propptr_b, propptr_b->type));
+ is_valid_for_diffing = !(*r_is_id || *r_is_null);
+ }
+
+ if (propptr_b == NULL || propptr_a->type != propptr_b->type) {
+ *r_is_type_diff = true;
+ is_valid_for_diffing = false;
+// printf("%s: different pointer RNA types\n", rna_path ? rna_path : "<UNKNOWN>");
+ }
+
+ /* We do a generic quick first comparison checking for "name" and/or "type" properties.
+ * We assume that is any of those are false, then we are not handling the same data.
+ * This helps a lot in static override case, especially to detect inserted items in collections. */
+ if (!no_prop_name && (is_valid_for_diffing || do_force_name)) {
+ PropertyRNA *nameprop_a = RNA_struct_name_property(propptr_a->type);
+ PropertyRNA *nameprop_b = (propptr_b != NULL) ? RNA_struct_name_property(propptr_b->type) : NULL;
+
+ int propname_a_len = 0, propname_b_len = 0;
+ char *propname_a = NULL;
+ char *propname_b = NULL;
+ char buff_a[4096];
+ char buff_b[4096];
+ if (nameprop_a != NULL) {
+ if (r_propname_a == NULL && propname_a_buff == NULL) {
+ propname_a_buff = buff_a;
+ propname_a_buff_size = sizeof(buff_a);
+ }
+
+ propname_a = RNA_property_string_get_alloc(
+ propptr_a, nameprop_a, propname_a_buff, propname_a_buff_size, &propname_a_len);
+// printf("propname_a = %s\n", propname_a ? propname_a : "<NONE>");
+
+ if (r_propname_a != NULL) {
+ *r_propname_a = propname_a;
+ }
+ }
+// else printf("item of type %s a has no name property!\n", propptr_a->type->name);
+ if (nameprop_b != NULL) {
+ if (r_propname_b == NULL && propname_b_buff == NULL) {
+ propname_b_buff = buff_b;
+ propname_b_buff_size = sizeof(buff_b);
+ }
+
+ propname_b = RNA_property_string_get_alloc(
+ propptr_b, nameprop_b, propname_b_buff, propname_b_buff_size, &propname_b_len);
+
+ if (r_propname_b != NULL) {
+ *r_propname_b = propname_b;
+ }
+ }
+ if (propname_a != NULL && propname_b != NULL) {
+ if (propname_a_len != propname_b_len ||
+ propname_a[0] != propname_b[0] ||
+ !STREQ(propname_a, propname_b))
+ {
+ is_valid_for_diffing = false;
+// printf("%s: different names\n", rna_path ? rna_path : "<UNKNOWN>");
+ }
+ }
+ }
+
+ if (*r_is_id) {
+ BLI_assert(propptr_a->data == propptr_a->id.data && propptr_b->data == propptr_b->id.data);
+ }
+
+ return is_valid_for_diffing;
+}
+
+/* Used for both Pointer and Collection properties. */
+static int rna_property_override_diff_propptr(
+ PointerRNA *propptr_a, PointerRNA *propptr_b,
+ eRNACompareMode mode, const bool no_ownership, const bool no_prop_name,
+ IDOverrideStatic *override, const char *rna_path, const int flags, bool *r_override_changed)
+{
+ const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
+
+ bool is_id = false;
+ bool is_null = false;
+ bool is_type_diff = false;
+ /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
+ bool is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
+ propptr_a, propptr_b, no_prop_name, &is_id, &is_null, &is_type_diff,
+ NULL, NULL, 0, NULL, NULL, 0);
+
+ if (is_id) {
+ BLI_assert(no_ownership); /* For now, once we deal with nodetrees we'll want to get rid of that one. */
+ }
+
+ if (override) {
+ if (no_ownership /* || is_id */ || is_null || is_type_diff || !is_valid_for_diffing) {
+ /* In case this pointer prop does not own its data (or one is NULL), do not compare structs!
+ * This is a quite safe path to infinite loop, among other nasty issues.
+ * Instead, just compare pointers themselves. */
+ const int comp = (propptr_a->data != propptr_b->data);
+
+ if (do_create && comp != 0) {
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ }
+
+ return comp;
+ }
+ else {
+ eRNAOverrideMatchResult report_flags = 0;
+ const bool match = RNA_struct_override_matches(propptr_a, propptr_b, rna_path, override, flags, &report_flags);
+ if (r_override_changed && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) != 0) {
+ *r_override_changed = true;
+ }
+ return !match;
+ }
+ }
+ else {
+ /* We could also use is_diff_pointer, but then we potentially lose the gt/lt info -
+ * and don't think performances are critical here for now anyway... */
+ return !RNA_struct_equals(propptr_a, propptr_b, mode);
+ }
+}
+
+
+
+#define RNA_PROPERTY_GET_SINGLE(_typename, _ptr, _prop, _index) \
+ (is_array ? RNA_property_##_typename##_get_index((_ptr), (_prop), (_index)) : \
+ RNA_property_##_typename##_get((_ptr), (_prop)))
+#define RNA_PROPERTY_SET_SINGLE(_typename, _ptr, _prop, _index, _value) \
+ (is_array ? RNA_property_##_typename##_set_index((_ptr), (_prop), (_index), (_value)) : \
+ RNA_property_##_typename##_set((_ptr), (_prop), (_value)))
+
+int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
+ PropertyRNA *prop_a, PropertyRNA *prop_b,
+ const int len_a, const int len_b,
+ const int mode,
+ IDOverrideStatic *override, const char *rna_path,
+ const int flags, bool *r_override_changed)
+{
+ BLI_assert(len_a == len_b);
+
+ /* Note: at this point, we are sure that when len_a is zero, we are not handling an (empty) array. */
+
+ const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
+
+ switch (RNA_property_type(prop_a)) {
+ case PROP_BOOLEAN:
+ {
+ if (len_a) {
+ int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ int *array_a, *array_b;
+
+ array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_a, "RNA equals") : array_stack_a;
+ array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_b, "RNA equals") : array_stack_b;
+
+ RNA_property_boolean_get_array(ptr_a, prop_a, array_a);
+ RNA_property_boolean_get_array(ptr_b, prop_b, array_b);
+
+ const int comp = memcmp(array_a, array_b, sizeof(int) * len_a);
+
+ if (do_create && comp != 0) {
+ /* XXX TODO this will have to be refined to handle array items */
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) {
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ else {
+ /* Already overriden prop, we'll have to check arrays items etc. */
+ }
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+
+ return comp;
+ }
+ else {
+ const int value_a = RNA_property_boolean_get(ptr_a, prop_a);
+ const int value_b = RNA_property_boolean_get(ptr_b, prop_b);
+ const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
+
+ if (do_create && comp != 0) {
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ }
+
+ return comp;
+ }
+ }
+
+ case PROP_INT:
+ {
+ if (len_a) {
+ int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ int *array_a, *array_b;
+
+ array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_a, "RNA equals") : array_stack_a;
+ array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_b, "RNA equals") : array_stack_b;
+
+ RNA_property_int_get_array(ptr_a, prop_a, array_a);
+ RNA_property_int_get_array(ptr_b, prop_b, array_b);
+
+ const int comp = memcmp(array_a, array_b, sizeof(int) * len_a);
+
+ if (do_create && comp != 0) {
+ /* XXX TODO this will have to be refined to handle array items */
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) {
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ else {
+ /* Already overriden prop, we'll have to check arrays items etc. */
+ }
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+
+ return comp;
+ }
+ else {
+ const int value_a = RNA_property_int_get(ptr_a, prop_a);
+ const int value_b = RNA_property_int_get(ptr_b, prop_b);
+ const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
+
+ if (do_create && comp != 0) {
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ }
+
+ return comp;
+ }
+ }
+
+ case PROP_FLOAT:
+ {
+ if (len_a) {
+ float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ float *array_a, *array_b;
+
+ array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_a, "RNA equals") : array_stack_a;
+ array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_b, "RNA equals") : array_stack_b;
+
+ RNA_property_float_get_array(ptr_a, prop_a, array_a);
+ RNA_property_float_get_array(ptr_b, prop_b, array_b);
+
+ const int comp = memcmp(array_a, array_b, sizeof(float) * len_a);
+
+ if (do_create && comp != 0) {
+ /* XXX TODO this will have to be refined to handle array items */
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) {
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE,
+ NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ else {
+ /* Already overriden prop, we'll have to check arrays items etc. */
+ }
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+
+ return comp;
+ }
+ else {
+ const float value_a = RNA_property_float_get(ptr_a, prop_a);
+ const float value_b = RNA_property_float_get(ptr_b, prop_b);
+ const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
+
+ if (do_create && comp != 0) {
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE,
+ NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ }
+
+ return comp ;
+ }
+ }
+
+ case PROP_ENUM:
+ {
+ const int value_a = RNA_property_enum_get(ptr_a, prop_a);
+ const int value_b = RNA_property_enum_get(ptr_b, prop_b);
+ const int comp = value_a != value_b;
+
+ if (do_create && comp != 0) {
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ }
+
+ return comp;
+ }
+
+ case PROP_STRING:
+ {
+ char fixed_a[4096], fixed_b[4096];
+ int len_str_a, len_str_b;
+ char *value_a = RNA_property_string_get_alloc(ptr_a, prop_a, fixed_a, sizeof(fixed_a), &len_str_a);
+ char *value_b = RNA_property_string_get_alloc(ptr_b, prop_b, fixed_b, sizeof(fixed_b), &len_str_b);
+ /* TODO we could do a check on length too, but then we would not have a 'real' string comparison...
+ * Maybe behind a eRNAOverrideMatch flag? */
+// const int comp = len_str_a < len_str_b ? -1 : len_str_a > len_str_b ? 1 : strcmp(value_a, value_b);
+ const int comp = strcmp(value_a, value_b);
+
+ if (do_create && comp != 0) {
+ bool created = false;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
+ if (r_override_changed) {
+ *r_override_changed = created;
+ }
+ }
+ }
+
+ if (value_a != fixed_a) MEM_freeN(value_a);
+ if (value_b != fixed_b) MEM_freeN(value_b);
+
+ return comp;
+ }
+
+ case PROP_POINTER:
+ {
+ if (STREQ(RNA_property_identifier(prop_a), "rna_type")) {
+ /* Dummy 'pass' answer, this is a meta-data and must be ignored... */
+ return 0;
+ }
+ else {
+ PointerRNA propptr_a = RNA_property_pointer_get(ptr_a, prop_a);
+ PointerRNA propptr_b = RNA_property_pointer_get(ptr_b, prop_b);
+ const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
+ const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
+ return rna_property_override_diff_propptr(
+ &propptr_a, &propptr_b, mode, no_ownership, no_prop_name,
+ override, rna_path, flags, r_override_changed);
+ }
+ break;
+ }
+
+ case PROP_COLLECTION:
+ {
+ /* Note: we assume we only insert in ptr_a (i.e. we can only get new items in ptr_a),
+ * and that we never remove anything. */
+ const bool use_insertion = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) && do_create;
+ const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
+ bool equals = true;
+ bool abort = false;
+ bool is_first_insert = true;
+ int idx_a = 0;
+ int idx_b = 0;
+
+#define RNA_PATH_BUFFSIZE 8192
+
+ char extended_rna_path_buffer[RNA_PATH_BUFFSIZE];
+ char *extended_rna_path = extended_rna_path_buffer;
+
+#define RNA_PATH_PRINTF(_str, ...) \
+ if (BLI_snprintf(extended_rna_path_buffer, RNA_PATH_BUFFSIZE, \
+ (_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE - 1) \
+ { extended_rna_path = BLI_sprintfN((_str), __VA_ARGS__); }(void)0
+#define RNA_PATH_FREE() \
+ if (extended_rna_path != extended_rna_path_buffer) MEM_freeN(extended_rna_path)
+
+ CollectionPropertyIterator iter_a, iter_b;
+ RNA_property_collection_begin(ptr_a, prop_a, &iter_a);
+ RNA_property_collection_begin(ptr_b, prop_b, &iter_b);
+
+ char buff_a[4096];
+ char buff_prev_a[4096] = {0};
+ char buff_b[4096];
+ char *propname_a = NULL;
+ char *prev_propname_a = buff_prev_a;
+ char *propname_b = NULL;
+
+ for (; iter_a.valid && !abort; ) {
+ bool is_valid_for_diffing;
+ bool is_valid_for_insertion;
+ do {
+ bool is_id = false, is_null = false, is_type_diff = false;
+
+ is_valid_for_insertion = use_insertion;
+
+ /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
+ if (iter_b.valid) {
+ is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
+ &iter_a.ptr, &iter_b.ptr, no_prop_name,
+ &is_id, &is_null, &is_type_diff,
+ &propname_a, buff_a, sizeof(buff_a),
+ &propname_b, buff_b, sizeof(buff_b));
+ }
+ else {
+ is_valid_for_diffing = false;
+ if (is_valid_for_insertion) {
+ /* We still need propname from 'a' item... */
+ rna_property_override_diff_propptr_validate_diffing(
+ &iter_a.ptr, NULL, no_prop_name,
+ &is_id, &is_null, &is_type_diff,
+ &propname_a, buff_a, sizeof(buff_a),
+ &propname_b, buff_b, sizeof(buff_b));
+ }
+ }
+
+ /* We do not support insertion of IDs for now, neither handle NULL pointers. */
+ if (is_id || is_valid_for_diffing) {
+ is_valid_for_insertion = false;
+ }
+
+#if 0
+ if (rna_path) {
+ printf("Checking %s, %s [%d] vs %s [%d]; diffing: %d; insert: %d (could be used: %d, do_create: %d)\n",
+ rna_path, propname_a ? propname_a : "", idx_a, propname_b ? propname_b : "", idx_b,
+ is_valid_for_diffing, is_valid_for_insertion,
+ (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) != 0, do_create);
+ }
+#endif
+
+ if (!(is_valid_for_diffing || is_valid_for_insertion)) {
+ /* Differences we cannot handle, we can break here
+ * (we do not support replacing ID pointers in collections e.g.). */
+ equals = false;
+ abort = true;
+ break;
+ }
+
+ /* There may be a propname defined in some cases, while no actual name set
+ * (e.g. happens with point cache), in that case too we want to fall back to index.
+ * Note that we do not need the RNA path for insertion operations. */
+ if (is_valid_for_diffing) {
+ if ((propname_a != NULL && propname_a[0] != '\0') &&
+ (propname_b != NULL && propname_b[0] != '\0'))
+ {
+ if (rna_path) {
+ /* In case of name, either it is valid for diffing, and _a and _b are identical,
+ * or it is valid for insertion, and we need to use _a. */
+ char esc_item_name[RNA_PATH_BUFFSIZE];
+ BLI_strescape(esc_item_name, propname_a, RNA_PATH_BUFFSIZE);
+ RNA_PATH_PRINTF("%s[\"%s\"]", rna_path, esc_item_name);
+ }
+ }
+ else { /* Based on index... */
+ if (rna_path) {
+ /* In case of indices, we need _a one for insertion, but _b ones for in-depth diffing.
+ * Insertion always happen once all 'replace' operations have been done,
+ * otherwise local and reference paths for those would have to be different! */
+ RNA_PATH_PRINTF("%s[%d]", rna_path, is_valid_for_insertion ? idx_a : idx_b);
+ }
+ }
+ }
+
+ /* Collections do not support replacement of their data (since they do not support removing),
+ * only in *some* cases, insertion.
+ * We also assume then that _a data is the one where things are inserted. */
+ if (is_valid_for_insertion && use_insertion) {
+ bool created;
+ IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
+
+ if (is_first_insert) {
+ /* We need to clean up all possible existing insertion operations, otherwise we'd end up
+ * with a mess of ops everytime something changes. */
+ for (IDOverrideStaticPropertyOperation *opop = op->operations.first;
+ opop != NULL;)
+ {
+ IDOverrideStaticPropertyOperation *opop_next = opop->next;
+ if (ELEM(opop->operation,
+ IDOVERRIDESTATIC_OP_INSERT_AFTER, IDOVERRIDESTATIC_OP_INSERT_BEFORE))
+ {
+ BKE_override_static_property_operation_delete(op, opop);
+ }
+ opop = opop_next;
+ }
+ is_first_insert = false;
+ }
+
+ BKE_override_static_property_operation_get(
+ op, IDOVERRIDESTATIC_OP_INSERT_AFTER,
+ NULL, prev_propname_a, -1, idx_a - 1, true, NULL, NULL);
+// printf("%s: Adding insertion op override after '%s'/%d\n", rna_path, prev_propname_a, idx_a - 1);
+ }
+ else if (is_valid_for_diffing) {
+ if (equals || do_create) {
+ const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
+ const int eq = rna_property_override_diff_propptr(
+ &iter_a.ptr, &iter_b.ptr, mode, no_ownership, no_prop_name,
+ override, extended_rna_path, flags, r_override_changed);
+ equals = equals && eq;
+ }
+ }
+
+ if (prev_propname_a != buff_prev_a) {
+ MEM_freeN(prev_propname_a);
+ prev_propname_a = buff_prev_a;
+ }
+ prev_propname_a[0] = '\0';
+ if (propname_a != NULL &&
+ BLI_strncpy_rlen(prev_propname_a, propname_a, sizeof(buff_prev_a)) >= sizeof(buff_prev_a) - 1)
+ {
+ prev_propname_a = BLI_strdup(propname_a);
+ }
+ if (propname_a != buff_a) {
+ MEM_SAFE_FREE(propname_a);
+ propname_a = buff_a;
+ }
+ propname_a[0] = '\0';
+ if (propname_b != buff_b) {
+ MEM_SAFE_FREE(propname_b);
+ propname_b = buff_b;
+ }
+ propname_b[0] = '\0';
+ RNA_PATH_FREE();
+
+ if (!do_create && !equals) {
+ abort = true; /* Early out in case we do not want to loop over whole collection. */
+ break;
+ }
+
+ if (!(use_insertion && !is_valid_for_diffing)) {
+ break;
+ }
+
+ if (iter_a.valid) {
+ RNA_property_collection_next(&iter_a);
+ idx_a++;
+ }
+ } while (iter_a.valid);
+
+ if (iter_a.valid) {
+ RNA_property_collection_next(&iter_a);
+ idx_a++;
+ }
+ if (iter_b.valid) {
+ RNA_property_collection_next(&iter_b);
+ idx_b++;
+ }
+
+#undef RNA_PATH_BUFFSIZE
+#undef RNA_PATH_PRINTF
+#undef RNA_PATH_FREE
+ }
+
+ equals = equals && !(iter_a.valid || iter_b.valid) && !abort; /* Not same number of items in both collections... */
+ RNA_property_collection_end(&iter_a);
+ RNA_property_collection_end(&iter_b);
+
+ return (equals == false);
+ }
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+bool rna_property_override_store_default(
+ PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage,
+ PropertyRNA *prop_local, PropertyRNA *prop_reference, PropertyRNA *prop_storage,
+ const int len_local, const int len_reference, const int len_storage,
+ IDOverrideStaticPropertyOperation *opop)
+{
+ BLI_assert(len_local == len_reference && (!ptr_storage || len_local == len_storage));
+ UNUSED_VARS_NDEBUG(len_reference, len_storage);
+
+ bool changed = false;
+ const bool is_array = len_local > 0;
+ const int index = is_array ? opop->subitem_reference_index : 0;
+
+ if (!ELEM(opop->operation, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY)) {
+ return changed;
+ }
+
+ /* XXX TODO About range limits.
+ * Ideally, it woudl be great to get rid of RNA range in that specific case.
+ * However, this won't be that easy and will add yet another layer of complexity in generated code,
+ * not to mention that we could most likely *not* bypass custom setters anyway.
+ * So for now, if needed second operand value is not in valid range, we simply fall back
+ * to a mere REPLACE operation.
+ * Time will say whether this is acceptable limitation or not. */
+ switch (RNA_property_type(prop_local)) {
+ case PROP_BOOLEAN:
+ /* TODO support boolean ops? Really doubt this would ever be useful though... */
+ BLI_assert(0 && "Boolean properties support no override diff operation");
+ break;
+ case PROP_INT:
+ {
+ int prop_min, prop_max;
+ RNA_property_int_range(ptr_local, prop_local, &prop_min, &prop_max);
+
+ if (is_array && index == -1) {
+ int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ int *array_a, *array_b;
+
+ array_a = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_local, __func__) : array_stack_a;
+ RNA_property_int_get_array(ptr_reference, prop_reference, array_a);
+
+ switch (opop->operation) {
+ case IDOVERRIDESTATIC_OP_ADD:
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ {
+ const int fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1 : -1;
+ const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
+ bool do_set = true;
+ array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
+ RNA_property_int_get_array(ptr_local, prop_local, array_b);
+ for (int i = len_local; i--;) {
+ array_b[i] = fac * (array_b[i] - array_a[i]);
+ if (array_b[i] < prop_min || array_b[i] > prop_max) {
+ opop->operation = other_op;
+ for (int j = len_local; j--;) {
+ array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
+ if (array_b[j] < prop_min || array_b[j] > prop_max) {
+ /* We failed to find a suitable diff op,
+ * fall back to plain REPLACE one. */
+ opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
+ do_set = false;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if (do_set) {
+ changed = true;
+ RNA_property_int_set_array(ptr_storage, prop_storage, array_b);
+ }
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+ break;
+ }
+ default:
+ BLI_assert(0 && "Unsupported RNA override diff operation on integer");
+ break;
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ }
+ else {
+ const int value = RNA_PROPERTY_GET_SINGLE(int, ptr_reference, prop_reference, index);
+
+ switch (opop->operation) {
+ case IDOVERRIDESTATIC_OP_ADD:
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ {
+ const int fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1 : -1;
+ const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
+ int b = fac * (RNA_PROPERTY_GET_SINGLE(int, ptr_local, prop_local, index) - value);
+ if (b < prop_min || b > prop_max) {
+ opop->operation = other_op;
+ b = -b;
+ if (b < prop_min || b > prop_max) {
+ opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
+ break;
+ }
+ }
+ changed = true;
+ RNA_PROPERTY_SET_SINGLE(int, ptr_storage, prop_storage, index, b);
+ break;
+ }
+ default:
+ BLI_assert(0 && "Unsupported RNA override diff operation on integer");
+ break;
+ }
+ }
+ break;
+ }
+ case PROP_FLOAT:
+ {
+ float prop_min, prop_max;
+ RNA_property_float_range(ptr_local, prop_local, &prop_min, &prop_max);
+
+ if (is_array && index == -1) {
+ float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ float *array_a, *array_b;
+
+ array_a = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_local, __func__) : array_stack_a;
+
+ RNA_property_float_get_array(ptr_reference, prop_reference, array_a);
+ switch (opop->operation) {
+ case IDOVERRIDESTATIC_OP_ADD:
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ {
+ const float fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1.0 : -1.0;
+ const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
+ bool do_set = true;
+ array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
+ RNA_property_float_get_array(ptr_local, prop_local, array_b);
+ for (int i = len_local; i--;) {
+ array_b[i] = fac * (array_b[i] - array_a[i]);
+ if (array_b[i] < prop_min || array_b[i] > prop_max) {
+ opop->operation = other_op;
+ for (int j = len_local; j--;) {
+ array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
+ if (array_b[j] < prop_min || array_b[j] > prop_max) {
+ /* We failed to find a suitable diff op,
+ * fall back to plain REPLACE one. */
+ opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
+ do_set = false;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if (do_set) {
+ changed = true;
+ RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
+ }
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+ break;
+ }
+ case IDOVERRIDESTATIC_OP_MULTIPLY:
+ {
+ bool do_set = true;
+ array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
+ RNA_property_float_get_array(ptr_local, prop_local, array_b);
+ for (int i = len_local; i--;) {
+ array_b[i] = array_a[i] == 0.0f ? array_b[i] : array_b[i] / array_a[i];
+ if (array_b[i] < prop_min || array_b[i] > prop_max) {
+ opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
+ do_set = false;
+ break;
+ }
+ }
+ if (do_set) {
+ changed = true;
+ RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
+ }
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+ break;
+ }
+ default:
+ BLI_assert(0 && "Unsupported RNA override diff operation on float");
+ break;
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ }
+ else {
+ const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_reference, prop_reference, index);
+
+ switch (opop->operation) {
+ case IDOVERRIDESTATIC_OP_ADD:
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ {
+ const float fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1.0f : -1.0f;
+ const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
+ float b = fac * (RNA_PROPERTY_GET_SINGLE(float, ptr_local, prop_local, index) - value);
+ if (b < prop_min || b > prop_max) {
+ opop->operation = other_op;
+ b = -b;
+ if (b < prop_min || b > prop_max) {
+ opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
+ break;
+ }
+ }
+ changed = true;
+ RNA_PROPERTY_SET_SINGLE(float, ptr_storage, prop_storage, index, b);
+ break;
+ }
+ case IDOVERRIDESTATIC_OP_MULTIPLY:
+ {
+ const float b = RNA_property_float_get_index(ptr_local, prop_local, index) / (value == 0.0f ? 1.0f : value);
+ if (b < prop_min || b > prop_max) {
+ opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
+ break;
+ }
+ changed = true;
+ RNA_property_float_set_index(ptr_storage, prop_storage, index, b);
+ break;
+ }
+ default:
+ BLI_assert(0 && "Unsupported RNA override diff operation on float");
+ break;
+ }
+ }
+ return true;
+ }
+ case PROP_ENUM:
+ /* TODO support add/sub, for bitflags? */
+ BLI_assert(0 && "Enum properties support no override diff operation");
+ break;
+ case PROP_POINTER:
+ BLI_assert(0 && "Pointer properties support no override diff operation");
+ break;
+ case PROP_STRING:
+ BLI_assert(0 && "String properties support no override diff operation");
+ break;
+ case PROP_COLLECTION:
+ /* XXX TODO support this of course... */
+ BLI_assert(0 && "Collection properties support no override diff operation");
+ break;
+ default:
+ break;
+ }
+
+ return changed;
+}
+
+bool rna_property_override_apply_default(
+ PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage,
+ PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *prop_storage,
+ const int len_dst, const int len_src, const int len_storage,
+ IDOverrideStaticPropertyOperation *opop)
+{
+ BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage));
+ UNUSED_VARS_NDEBUG(len_src, len_storage);
+
+ const bool is_array = len_dst > 0;
+ const int index = is_array ? opop->subitem_reference_index : 0;
+ const short override_op = opop->operation;
+
+ switch (RNA_property_type(prop_dst)) {
+ case PROP_BOOLEAN:
+ if (is_array && index == -1) {
+ int array_stack_a[RNA_STACK_ARRAY];
+ int *array_a;
+
+ array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
+
+ RNA_property_boolean_get_array(ptr_src, prop_src, array_a);
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_property_boolean_set_array(ptr_dst, prop_dst, array_a);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on boolean");
+ return false;
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ }
+ else {
+ const int value = RNA_PROPERTY_GET_SINGLE(boolean, ptr_src, prop_src, index);
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_PROPERTY_SET_SINGLE(boolean, ptr_dst, prop_dst, index, value);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on boolean");
+ return false;
+ }
+ }
+ return true;
+ case PROP_INT:
+ if (is_array && index == -1) {
+ int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ int *array_a, *array_b;
+
+ array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_property_int_get_array(ptr_src, prop_src, array_a);
+ RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
+ break;
+ case IDOVERRIDESTATIC_OP_ADD:
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ RNA_property_int_get_array(ptr_dst, prop_dst, array_a);
+ array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
+ RNA_property_int_get_array(ptr_storage, prop_storage, array_b);
+ if (override_op == IDOVERRIDESTATIC_OP_ADD) {
+ for (int i = len_dst; i--;) array_a[i] += array_b[i];
+ }
+ else {
+ for (int i = len_dst; i--;) array_a[i] -= array_b[i];
+ }
+ RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on integer");
+ return false;
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ }
+ else {
+ const int storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(int, ptr_storage, prop_storage, index) : 0;
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(int, ptr_src, prop_src, index));
+ break;
+ case IDOVERRIDESTATIC_OP_ADD:
+ RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
+ break;
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on integer");
+ return false;
+ }
+ }
+ return true;
+ case PROP_FLOAT:
+ if (is_array && index == -1) {
+ float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
+ float *array_a, *array_b;
+
+ array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_property_float_get_array(ptr_src, prop_src, array_a);
+ RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
+ break;
+ case IDOVERRIDESTATIC_OP_ADD:
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ case IDOVERRIDESTATIC_OP_MULTIPLY:
+ RNA_property_float_get_array(ptr_dst, prop_dst, array_a);
+ array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
+ RNA_property_float_get_array(ptr_storage, prop_storage, array_b);
+ if (override_op == IDOVERRIDESTATIC_OP_ADD) {
+ for (int i = len_dst; i--;) array_a[i] += array_b[i];
+ }
+ else if (override_op == IDOVERRIDESTATIC_OP_SUBTRACT) {
+ for (int i = len_dst; i--;) array_a[i] -= array_b[i];
+ }
+ else {
+ for (int i = len_dst; i--;) array_a[i] *= array_b[i];
+ }
+ RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
+ if (array_b != array_stack_b) MEM_freeN(array_b);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on float");
+ return false;
+ }
+
+ if (array_a != array_stack_a) MEM_freeN(array_a);
+ }
+ else {
+ const float storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(float, ptr_storage, prop_storage, index) : 0.0f;
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(float, ptr_src, prop_src, index));
+ break;
+ case IDOVERRIDESTATIC_OP_ADD:
+ RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) + storage_value);
+ break;
+ case IDOVERRIDESTATIC_OP_SUBTRACT:
+ RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) - storage_value);
+ break;
+ case IDOVERRIDESTATIC_OP_MULTIPLY:
+ RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
+ RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) * storage_value);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on float");
+ return false;
+ }
+ }
+ return true;
+ case PROP_ENUM:
+ {
+ const int value = RNA_property_enum_get(ptr_src, prop_src);
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_property_enum_set(ptr_dst, prop_dst, value);
+ break;
+ /* TODO support add/sub, for bitflags? */
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on enum");
+ return false;
+ }
+ return true;
+ }
+ case PROP_POINTER:
+ {
+ PointerRNA value = RNA_property_pointer_get(ptr_src, prop_src);
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_property_pointer_set(ptr_dst, prop_dst, value);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on pointer");
+ return false;
+ }
+ return true;
+ }
+ case PROP_STRING:
+ {
+ char buff[256];
+ char *value = RNA_property_string_get_alloc(ptr_src, prop_src, buff, sizeof(buff), NULL);
+
+ switch (override_op) {
+ case IDOVERRIDESTATIC_OP_REPLACE:
+ RNA_property_string_set(ptr_dst, prop_dst, value);
+ break;
+ default:
+ BLI_assert(0 && "Unsupported RNA override operation on string");
+ return false;
+ }
+
+ if (value != buff) MEM_freeN(value);
+ return true;
+ }
+ case PROP_COLLECTION:
+ {
+ BLI_assert(!"You need to define a specific override apply callback for enums.");
+ return false;
+ }
+ default:
+ BLI_assert(0);
+ return false;
+ }
+
+ return false;
+}
+
+#undef RNA_PROPERTY_GET_SINGLE
+#undef RNA_PROPERTY_SET_SINGLE
+
#else
@@ -1283,6 +2408,11 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Property_animatable_get", NULL);
RNA_def_property_ui_text(prop, "Animatable", "Property is animatable through RNA");
+ prop = RNA_def_property(srna, "is_overridable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Property_overridable_get", NULL);
+ RNA_def_property_ui_text(prop, "Overridable", "Property is overridable through RNA");
+
prop = RNA_def_property(srna, "is_required", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Property_is_required_get", NULL);