1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 */ 16 17 #pragma once 18 19 /** \file 20 * \ingroup bke 21 */ 22 23 #include "DNA_ID.h" 24 25 #include "BLI_compiler_attrs.h" 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 struct BlendDataReader; 32 struct BlendExpander; 33 struct BlendLibReader; 34 struct BlendWriter; 35 struct ID; 36 struct IDProperty; 37 38 typedef union IDPropertyTemplate { 39 int i; 40 float f; 41 double d; 42 struct { 43 const char *str; 44 int len; 45 char subtype; 46 } string; 47 struct ID *id; 48 struct { 49 int len; 50 char type; 51 } array; 52 struct { 53 int matvec_size; 54 const float *example; 55 } matrix_or_vector; 56 } IDPropertyTemplate; 57 58 /* ----------- Property Array Type ---------- */ 59 60 IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); 61 IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag) ATTR_WARN_UNUSED_RESULT 62 ATTR_NONNULL(); 63 64 /* shallow copies item */ 65 void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL(); 66 struct IDProperty *IDP_GetIndexArray(struct IDProperty *prop, int index) ATTR_WARN_UNUSED_RESULT 67 ATTR_NONNULL(); 68 void IDP_AppendArray(struct IDProperty *prop, struct IDProperty *item); 69 void IDP_ResizeIDPArray(struct IDProperty *prop, int len); 70 71 /* ----------- Numeric Array Type ----------- */ 72 /*this function works for strings too!*/ 73 void IDP_ResizeArray(struct IDProperty *prop, int newlen); 74 void IDP_FreeArray(struct IDProperty *prop); 75 76 /* ---------- String Type ------------ */ 77 IDProperty *IDP_NewString(const char *st, const char *name, int maxlen) ATTR_WARN_UNUSED_RESULT 78 ATTR_NONNULL(2 /* 'name 'arg */); /* maxlen excludes '\0' */ 79 void IDP_AssignString(struct IDProperty *prop, const char *st, int maxlen) 80 ATTR_NONNULL(); /* maxlen excludes '\0' */ 81 void IDP_ConcatStringC(struct IDProperty *prop, const char *st) ATTR_NONNULL(); 82 void IDP_ConcatString(struct IDProperty *str1, struct IDProperty *append) ATTR_NONNULL(); 83 void IDP_FreeString(struct IDProperty *prop) ATTR_NONNULL(); 84 85 /*-------- ID Type -------*/ 86 87 typedef void (*IDPWalkFunc)(void *userData, IDProperty *idp); 88 89 void IDP_AssignID(IDProperty *prop, ID *id, const int flag); 90 91 /*-------- Group Functions -------*/ 92 93 /** Sync values from one group to another, only where they match */ 94 void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL(); 95 void IDP_SyncGroupTypes(struct IDProperty *dest, 96 const struct IDProperty *src, 97 const bool do_arraylen) ATTR_NONNULL(); 98 void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL(); 99 void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); 100 void IDP_ReplaceInGroup_ex(struct IDProperty *group, 101 struct IDProperty *prop, 102 struct IDProperty *prop_exist); 103 void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) 104 ATTR_NONNULL(); 105 void IDP_MergeGroup_ex(IDProperty *dest, 106 const IDProperty *src, 107 const bool do_overwrite, 108 const int flag) ATTR_NONNULL(); 109 bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); 110 bool IDP_InsertToGroup(struct IDProperty *group, 111 struct IDProperty *previous, 112 struct IDProperty *pnew) ATTR_NONNULL(1 /* group */, 3 /* pnew */); 113 void IDP_RemoveFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); 114 void IDP_FreeFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); 115 116 IDProperty *IDP_GetPropertyFromGroup(const struct IDProperty *prop, 117 const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); 118 IDProperty *IDP_GetPropertyTypeFromGroup(const struct IDProperty *prop, 119 const char *name, 120 const char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); 121 122 /*-------- Main Functions --------*/ 123 struct IDProperty *IDP_GetProperties(struct ID *id, 124 const bool create_if_needed) ATTR_WARN_UNUSED_RESULT 125 ATTR_NONNULL(); 126 struct IDProperty *IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT 127 ATTR_NONNULL(); 128 struct IDProperty *IDP_CopyProperty_ex(const struct IDProperty *prop, 129 const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); 130 void IDP_CopyPropertyContent(IDProperty *dst, IDProperty *src) ATTR_NONNULL(); 131 132 bool IDP_EqualsProperties_ex(IDProperty *prop1, 133 IDProperty *prop2, 134 const bool is_strict) ATTR_WARN_UNUSED_RESULT; 135 136 bool IDP_EqualsProperties(struct IDProperty *prop1, 137 struct IDProperty *prop2) ATTR_WARN_UNUSED_RESULT; 138 139 struct IDProperty *IDP_New(const char type, 140 const IDPropertyTemplate *val, 141 const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); 142 143 void IDP_FreePropertyContent_ex(struct IDProperty *prop, const bool do_id_user); 144 void IDP_FreePropertyContent(struct IDProperty *prop); 145 void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user); 146 void IDP_FreeProperty(struct IDProperty *prop); 147 148 void IDP_ClearProperty(IDProperty *prop); 149 150 void IDP_RelinkProperty(struct IDProperty *prop); 151 152 void IDP_Reset(IDProperty *prop, const IDProperty *reference); 153 154 #define IDP_Int(prop) ((prop)->data.val) 155 #define IDP_Array(prop) ((prop)->data.pointer) 156 /* C11 const correctness for casts */ 157 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) 158 # define IDP_Float(prop) \ 159 _Generic((prop), \ 160 IDProperty *: (*(float *)&(prop)->data.val), \ 161 const IDProperty *: (*(const float *)&(prop)->data.val)) 162 # define IDP_Double(prop) \ 163 _Generic((prop), \ 164 IDProperty *: (*(double *)&(prop)->data.val), \ 165 const IDProperty *: (*(const double *)&(prop)->data.val)) 166 # define IDP_String(prop) \ 167 _Generic((prop), \ 168 IDProperty *: ((char *) (prop)->data.pointer), \ 169 const IDProperty *: ((const char *) (prop)->data.pointer)) 170 # define IDP_IDPArray(prop) \ 171 _Generic((prop), \ 172 IDProperty *: ((IDProperty *) (prop)->data.pointer), \ 173 const IDProperty *: ((const IDProperty *) (prop)->data.pointer)) 174 # define IDP_Id(prop) \ 175 _Generic((prop), \ 176 IDProperty *: ((ID *) (prop)->data.pointer), \ 177 const IDProperty *: ((const ID *) (prop)->data.pointer)) 178 #else 179 # define IDP_Float(prop) (*(float *)&(prop)->data.val) 180 # define IDP_Double(prop) (*(double *)&(prop)->data.val) 181 # define IDP_String(prop) ((char *)(prop)->data.pointer) 182 # define IDP_IDPArray(prop) ((IDProperty *)(prop)->data.pointer) 183 # define IDP_Id(prop) ((ID *)(prop)->data.pointer) 184 #endif 185 186 /** 187 * Call a callback for each idproperty in the hierarchy under given root one (included). 188 * 189 */ 190 typedef void (*IDPForeachPropertyCallback)(IDProperty *id_property, void *user_data); 191 192 void IDP_foreach_property(struct IDProperty *id_property_root, 193 const int type_filter, 194 IDPForeachPropertyCallback callback, 195 void *user_data); 196 197 /* Format IDProperty as strings */ 198 char *IDP_reprN(const struct IDProperty *prop, uint *r_len); 199 void IDP_repr_fn(const IDProperty *prop, 200 void (*str_append_fn)(void *user_data, const char *str, uint str_len), 201 void *user_data); 202 void IDP_print(const struct IDProperty *prop); 203 204 void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop); 205 void IDP_BlendReadData_impl(struct BlendDataReader *reader, 206 IDProperty **prop, 207 const char *caller_func_id); 208 #define IDP_BlendDataRead(reader, prop) IDP_BlendReadData_impl(reader, prop, __func__) 209 void IDP_BlendReadLib(struct BlendLibReader *reader, IDProperty *prop); 210 void IDP_BlendReadExpand(struct BlendExpander *expander, IDProperty *prop); 211 212 #ifdef __cplusplus 213 } 214 #endif 215