More "data types" for the Operator property system.
authorDiego Borghetti <bdiego@gmail.com>
Tue, 15 Jan 2008 04:49:09 +0000 (04:49 +0000)
committerDiego Borghetti <bdiego@gmail.com>
Tue, 15 Jan 2008 04:49:09 +0000 (04:49 +0000)
Now you can set/get: float, arrays (int and float) and string.

The only special function is OP_get_string, it is special
because return a pointer to the IDProperty data, so you can't
change/resize/free the string.

It's possible "fix" this with:
 1) Return a "const char"
 2) Return a duplicate string

All this new function are not in use yet, but i make a simple test
with the "move areas" operator (add a property of every type and then
print the result in the other size) and work fine, more test are welcome.

Other thing to check is the new OP_free_property function, because this
properties are only local to the operator, i choice free all this in the
"exit callback" of every operator (only move areas have property now),
so comment about this are welcome too :)

Also add some notes to the WM_api.h file.

source/blender/editors/screen/screen_edit.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_operators.c

index 1f0bd66062c0a15851b7015e9560920baf1c0ba1..27f623994362e15e118a9f677a6898754df6a352 100644 (file)
@@ -956,7 +956,8 @@ static int move_areas_exit(bContext *C, wmOperator *op)
        /* this makes sure aligned edges will result in aligned grabbing */
        removedouble_scrverts(C->screen);
        removedouble_scredges(C->screen);
-       
+
+       OP_free_property(op);   
        return 1;
 }
 
index 727b228405b148a4671c4b7b432f6a4cd13bbdd3..ae79492fd4977d0fd3918f10214371997182b881 100644 (file)
@@ -86,16 +86,51 @@ void                WM_operatortypelist_append(ListBase *lb);
  *
  * Some notes to take care:
  *
- * OP_set_int try to append a new property to the operator,
- * if the property already exist, just replace it with the
+ * All the OP_set_* functions append a new property to the operator,
+ * if the property already exist, just replace it with the new
  * value in other case make a new property and append it.
  *
- * OP_get_int return 0 on success (found the property) or
- * != 0 if can't found the property in the operator.
+ * The OP_get_string function is a "special case", this function
+ * return a pointer to property data, so don't change/resize/free
+ * the string, because probably we get a segfault.
+ * I really think that is better duplicate the string, so we are
+ * really sure that the property data don't change.
+ *
+ * OP_get_int/float/array return 0 on success (found the property)
+ * or != 0 if can't found the property in the operator.
  * The property value are store in the "value" pointer.
+ *
+ * Both array function copy the property data into the "array"
+ * pointer, but you need init the len pointer to the "array" size.
+ *
+ * For example:
+ *     int vec[] = { 1, 2, 3, 4 };
+ *     OP_set_int_array (op, "vector", vec, 4);
+ *
+ *     ...
+ *
+ *     short len;
+ *     int vec[4];
+ *     len= 4; <---- set the size!!
+ *     OP_get_int_array (op, "vector", vec, &len);
  */
 void OP_set_int(wmOperator *op, char *name, int value);
+void OP_set_float(wmOperator *op, char *name, float value);
+void OP_set_string(wmOperator *op, char *name, char *str);
+void OP_set_int_array(wmOperator *op, char *name, int *array, short len);
+void OP_set_float_array(wmOperator *op, char *name, float *array, short len);
+
 int OP_get_int(wmOperator *op, char *name, int *value);
+int OP_get_float(wmOperator *op, char *name, float *value);
+char *OP_get_string(wmOperator *op, char *name);
+int OP_get_int_array(wmOperator *op, char *name, int *array, short *len);
+int OP_get_float_array(wmOperator *op, char *name, float *array, short *len);
+
+/*
+ * Need call this function in the "exit callback"
+ * of the operator, but only if you use the property system.
+ **/
+void OP_free_property(wmOperator *op);
 
                        /* OpenGL wrappers, mimicing opengl syntax */
 void           wmLoadMatrix            (wmWindow *win, float mat[][4]);
index d0319da593bf2393bde7d7850010df39265341d3..423bcd51c8dde6a850c497a7bde403ed16290eca 100644 (file)
@@ -125,7 +125,6 @@ void wm_add_default(bContext *C)
 /* context is allowed to be NULL, do net free wm itself (library.c) */
 void wm_close_and_free(bContext *C, wmWindowManager *wm)
 {
-       wmOperator *op;
        wmWindow *win;
        
        while((win= wm->windows.first)) {
@@ -133,19 +132,6 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
                wm_window_free(C, win);
        }
        
-       op= wm->operators.first;
-       while(op) {
-               /*
-                * Need this, because if the operator don't have
-                * properties also don't have group.
-                */
-               if(op->properties) {
-                       IDP_FreeGroup(op->properties);
-                       op->properties= NULL;
-               }
-               op= op->next;
-       }
-
        BLI_freelistN(&wm->operators);
        
        BLI_freelistN(&wm->windowkeymap);
index 4c26ef4b11579f870a8fcb8b3a9b04091417fdca..d1fce510433d6c8f5f18d44567b98ed3aae0977d 100644 (file)
@@ -158,6 +158,17 @@ void op_init_property(wmOperator *op)
 }
 
 /* ***** Property API, exported ***** */
+void OP_free_property(wmOperator *op)
+{
+       IDP_FreeProperty(op->properties);
+       /*
+        * This need change, when the idprop code only
+        * need call IDP_FreeProperty. (check BKE_idprop.h)
+        */
+       MEM_freeN(op->properties);
+       op->properties= NULL;
+}
+
 void OP_set_int(wmOperator *op, char *name, int value)
 {
        IDPropertyTemplate val;
@@ -171,6 +182,72 @@ void OP_set_int(wmOperator *op, char *name, int value)
        IDP_ReplaceInGroup(op->properties, prop);
 }
 
+void OP_set_float(wmOperator *op, char *name, float value)
+{
+       IDPropertyTemplate val;
+       IDProperty *prop;
+
+       if(!op->properties)
+               op_init_property(op);
+
+       val.f= value;
+       prop= IDP_New(IDP_FLOAT, val, name);
+       IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_int_array(wmOperator *op, char *name, int *array, short len)
+{
+       IDPropertyTemplate val;
+       IDProperty *prop;
+       short i;
+       int *pointer;
+
+       if(!op->properties)
+               op_init_property(op);
+
+       val.array.len= len;
+       val.array.type= IDP_INT;
+       prop= IDP_New(IDP_ARRAY, val, name);
+
+       pointer= (int *)prop->data.pointer;
+       for(i= 0; i < len; i++)
+               pointer[i]= array[i];
+       IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_float_array(wmOperator *op, char *name, float *array, short len)
+{
+       IDPropertyTemplate val;
+       IDProperty *prop;
+       short i;
+       float *pointer;
+
+       if(!op->properties)
+               op_init_property(op);
+
+       val.array.len= len;
+       val.array.type= IDP_FLOAT;
+       prop= IDP_New(IDP_ARRAY, val, name);
+
+       pointer= (float *) prop->data.pointer;
+       for(i= 0; i < len; i++)
+               pointer[i]= array[i];
+       IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_string(wmOperator *op, char *name, char *str)
+{
+       IDPropertyTemplate val;
+       IDProperty *prop;
+
+       if(!op->properties)
+               op_init_property(op);
+
+       val.str= str;
+       prop= IDP_New(IDP_STRING, val, name);
+       IDP_ReplaceInGroup(op->properties, prop);
+}
+
 int OP_get_int(wmOperator *op, char *name, int *value)
 {
        IDProperty *prop= op_get_property(op, name);
@@ -182,3 +259,61 @@ int OP_get_int(wmOperator *op, char *name, int *value)
        }
        return (status);
 }
+
+int OP_get_float(wmOperator *op, char *name, float *value)
+{
+       IDProperty *prop= op_get_property(op, name);
+       int status= 1;
+
+       if ((prop) && (prop->type == IDP_FLOAT)) {
+               (*value)= *(float*)&prop->data.val;
+               status= 0;
+       }
+       return (status);
+}
+
+int OP_get_int_array(wmOperator *op, char *name, int *array, short *len)
+{
+       IDProperty *prop= op_get_property(op, name);
+       short i;
+       int status= 1;
+       int *pointer;
+
+       if ((prop) && (prop->type == IDP_ARRAY)) {
+               pointer= (int *) prop->data.pointer;
+
+               for(i= 0; (i < prop->len) && (i < *len); i++)
+                       array[i]= pointer[i];
+
+               (*len)= i;
+               status= 0;
+       }
+       return (status);
+}
+
+int OP_get_float_array(wmOperator *op, char *name, float *array, short *len)
+{
+       IDProperty *prop= op_get_property(op, name);
+       short i;
+       float *pointer;
+       int status= 1;
+
+       if ((prop) && (prop->type == IDP_ARRAY)) {
+               pointer= (float *) prop->data.pointer;
+
+               for(i= 0; (i < prop->len) && (i < *len); i++)
+                       array[i]= pointer[i];
+
+               (*len)= i;
+               status= 0;
+       }
+       return (status);
+}
+
+char *OP_get_string(wmOperator *op, char *name)
+{
+       IDProperty *prop= op_get_property(op, name);
+       if ((prop) && (prop->type == IDP_STRING))
+               return ((char *) prop->data.pointer);
+       return (NULL);
+}