=ID Properties Python Update=
authorJoseph Eagar <joeedh@gmail.com>
Fri, 17 Nov 2006 08:19:58 +0000 (08:19 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Fri, 17 Nov 2006 08:19:58 +0000 (08:19 +0000)
IDProperties now have a sanity check to prevent different ID properties
in the same group from having the same name.  The appropriate code has been
added to the python bindings to catch this and raise an error.

source/blender/blenkernel/BKE_idprop.h
source/blender/blenkernel/intern/idprop.c
source/blender/python/api2_2x/IDProp.c

index d61d274dd36b491f0a523de97dfc275932806a60..09083364fd9bb5e3eb19de25067782f9f6444562 100644 (file)
@@ -48,7 +48,22 @@ void IDP_LinkID(struct IDProperty *prop, ID *id);
 void IDP_UnlinkID(struct IDProperty *prop);
 
 /*-------- Group Functions -------*/
-void IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop);
+/*
+This function has a sanity check to make sure ID properties with the same name don't
+get added to the group.
+
+The sanity check just means the property is not added to the group if another property
+exists with the same name; the client code using ID properties then needs to detect this 
+(the function that adds new properties to groups, IDP_AddToGroup, returns 0 if a property can't
+be added to the group, and 1 if it can) and free the property.
+
+Currently the code to free ID properties is designesd to leave the actual struct
+you pass it un-freed, this is needed for how the system works.  This means
+to free an ID property, you first call IDP_FreeProperty then MEM_freeN the
+struct.  In the future this will just be IDP_FreeProperty and the code will
+be reorganized to work properly.
+*/
+int IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop);
 void IDP_RemFromGroup(struct IDProperty *group, struct IDProperty *prop);
 IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, char *name);
 
index 66feaffadb7116d532b621e6f0b004dedf55cb70..6a748a295b98e484ff3cd6ff641911b54b1eede6 100644 (file)
@@ -14,6 +14,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#define BSTR_EQ(a, b)  (*(a) == *(b) && !strcmp(a, b))
+
 /* IDPropertyTemplate is a union in DNA_ID.h */
 static char idp_size_table[] = {
        0, /*strings don't have fixed sizes :)*/
@@ -135,10 +137,19 @@ void IDP_UnlinkID(IDProperty *prop)
 }
 
 /*-------- Group Functions -------*/
-void IDP_AddToGroup(IDProperty *group, IDProperty *prop)
+/*returns 0 if an id property with the same name exists and it failed,
+  or 1 if it succeeded in adding to the group.*/
+int IDP_AddToGroup(IDProperty *group, IDProperty *prop)
 {
+       IDProperty *loop;
+       for (loop=group->data.group.first; loop; loop=loop->next) {
+               if (BSTR_EQ(loop->name, prop->name)) return 0;
+       }
+
        group->len++;
        BLI_addtail(&group->data.group, prop);
+
+       return 1;
 }
 
 void IDP_RemFromGroup(IDProperty *group, IDProperty *prop)
index 06a8d75b549e104f3b0a9980625c7aca871567fa..ff785c4d93dfdcd275b3d5fb468c8891db5b079b 100644 (file)
@@ -264,7 +264,11 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
                Py_XDECREF(vals);
        }
        
-       IDP_AddToGroup(group, prop);
+       if (!IDP_AddToGroup(group, prop)) {
+               IDP_FreeProperty(prop);
+               MEM_freeN(prop);
+               return "property name already exists in group";
+       }
        return NULL;
 }
 
@@ -848,7 +852,10 @@ PyObject *BPy_IDGroup_NewProperty(BPy_IDProperty *self, PyObject *args)
                                "invalid id property type");
        }
 
-       IDP_AddToGroup(self->prop, prop);
+       if (!IDP_AddToGroup(self->prop, prop)) {
+               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                               "property name already exists in group");
+       }
        pyprop = BPy_Wrap_IDProperty(self->id, prop);
        //Py_XINCREF(pyprop);
        return pyprop;