Changeset View
Changeset View
Standalone View
Standalone View
source/blender/makesdna/intern/dna_genfile.c
| Show First 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| if (sdna->mem_arena) { | if (sdna->mem_arena) { | ||||
| BLI_memarena_free(sdna->mem_arena); | BLI_memarena_free(sdna->mem_arena); | ||||
| } | } | ||||
| MEM_SAFE_FREE(sdna->alias.names); | MEM_SAFE_FREE(sdna->alias.names); | ||||
| MEM_SAFE_FREE(sdna->alias.types); | MEM_SAFE_FREE(sdna->alias.types); | ||||
| #ifdef WITH_DNA_GHASH | |||||
| if (sdna->alias.structs_map) { | |||||
| BLI_ghash_free(sdna->alias.structs_map, NULL, NULL); | |||||
| } | |||||
| #endif | |||||
| MEM_freeN(sdna); | MEM_freeN(sdna); | ||||
| } | } | ||||
| /** | /** | ||||
| * Return true if the name indicates a pointer of some kind. | * Return true if the name indicates a pointer of some kind. | ||||
| */ | */ | ||||
| static bool ispointer(const char *name) | static bool ispointer(const char *name) | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | for (b = 0; b < nr; b++, sp += 2) { | ||||
| printf(" %s %s\n", sdna->types[sp[0]], sdna->names[sp[1]]); | printf(" %s %s\n", sdna->types[sp[0]], sdna->names[sp[1]]); | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| /** | /** | ||||
| * Returns the index of the struct info for the struct with the specified name. | * Returns the index of the struct info for the struct with the specified name. | ||||
| */ | */ | ||||
| int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last) | static int dna_struct_find_nr_ex_impl( | ||||
| { | /* From SDNA struct. */ | ||||
| if (*index_last < sdna->structs_len) { | const char **types, | ||||
| const short *sp = sdna->structs[*index_last]; | short **const structs, | ||||
| if (STREQ(sdna->types[sp[0]], str)) { | const int structs_len, | ||||
| GHash *structs_map, | |||||
| /* Regular args. */ | |||||
| const char *str, | |||||
| unsigned int *index_last) | |||||
| { | |||||
| if (*index_last < structs_len) { | |||||
| const short *sp = structs[*index_last]; | |||||
| if (STREQ(types[sp[0]], str)) { | |||||
| return *index_last; | return *index_last; | ||||
| } | } | ||||
| } | } | ||||
| #ifdef WITH_DNA_GHASH | #ifdef WITH_DNA_GHASH | ||||
| { | { | ||||
| void **index_p = BLI_ghash_lookup_p(sdna->structs_map, str); | void **index_p = BLI_ghash_lookup_p(structs_map, str); | ||||
| if (index_p) { | if (index_p) { | ||||
| const int index = POINTER_AS_INT(*index_p); | const int index = POINTER_AS_INT(*index_p); | ||||
| *index_last = index; | *index_last = index; | ||||
| return index; | return index; | ||||
| } | } | ||||
| } | } | ||||
| #else | #else | ||||
| { | { | ||||
| for (int index = 0; index < sdna->structs_len; index++) { | UNUSED_VARS(structs_map); | ||||
| const short *sp = sdna->structs[index]; | for (int index = 0; index < structs_len; index++) { | ||||
| if (STREQ(sdna->types[sp[0]], str)) { | const short *sp = structs[index]; | ||||
| if (STREQ(types[sp[0]], str)) { | |||||
| *index_last = index; | *index_last = index; | ||||
| return index; | return index; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| /** | |||||
| * Returns the index of the struct info for the struct with the specified name. | |||||
| */ | |||||
| int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last) | |||||
| { | |||||
| return dna_struct_find_nr_ex_impl( | |||||
| /* Expand SDNA. */ | |||||
| sdna->types, | |||||
| sdna->structs, | |||||
| sdna->structs_len, | |||||
| sdna->structs_map, | |||||
| /* Regular args. */ | |||||
| str, | |||||
| index_last); | |||||
| } | |||||
| int DNA_struct_find_alias_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last) | |||||
| { | |||||
| return dna_struct_find_nr_ex_impl( | |||||
| /* Expand SDNA. */ | |||||
| sdna->alias.types, | |||||
| sdna->structs, | |||||
| sdna->structs_len, | |||||
| sdna->alias.structs_map, | |||||
| /* Regular args. */ | |||||
| str, | |||||
| index_last); | |||||
| } | |||||
| int DNA_struct_find_nr(const SDNA *sdna, const char *str) | int DNA_struct_find_nr(const SDNA *sdna, const char *str) | ||||
| { | { | ||||
| unsigned int index_last_dummy = UINT_MAX; | unsigned int index_last_dummy = UINT_MAX; | ||||
| return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy); | return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy); | ||||
| } | } | ||||
| int DNA_struct_find_alias_nr(const SDNA *sdna, const char *str) | |||||
| { | |||||
| unsigned int index_last_dummy = UINT_MAX; | |||||
| return DNA_struct_find_alias_nr_ex(sdna, str, &index_last_dummy); | |||||
| } | |||||
| /* ************************* END DIV ********************** */ | /* ************************* END DIV ********************** */ | ||||
| /* ************************* READ DNA ********************** */ | /* ************************* READ DNA ********************** */ | ||||
| BLI_INLINE const char *pad_up_4(const char *ptr) | BLI_INLINE const char *pad_up_4(const char *ptr) | ||||
| { | { | ||||
| return (const char *)((((uintptr_t)ptr) + 3) & ~3); | return (const char *)((((uintptr_t)ptr) + 3) & ~3); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 633 Lines • ▼ Show 20 Lines | |||||
| * pointed to by old. | * pointed to by old. | ||||
| * | * | ||||
| * \param sdna: Old SDNA | * \param sdna: Old SDNA | ||||
| * \param type: Current field type name | * \param type: Current field type name | ||||
| * \param name: Current field name | * \param name: Current field name | ||||
| * \param old: Pointer to struct information in sdna | * \param old: Pointer to struct information in sdna | ||||
| * \return true when existing, false otherwise. | * \return true when existing, false otherwise. | ||||
| */ | */ | ||||
| static bool elem_exists(const SDNA *sdna, const char *type, const char *name, const short *old) | static bool elem_exists_impl( | ||||
| /* Expand SDNA. */ | |||||
| const char **types, | |||||
| const char **names, | |||||
| /* Regular args. */ | |||||
| const char *type, | |||||
| const char *name, | |||||
| const short *old) | |||||
| { | { | ||||
| int a, elemcount; | int a, elemcount; | ||||
| const char *otype, *oname; | const char *otype, *oname; | ||||
| /* in old is the old struct */ | /* in old is the old struct */ | ||||
| elemcount = old[1]; | elemcount = old[1]; | ||||
| old += 2; | old += 2; | ||||
| for (a = 0; a < elemcount; a++, old += 2) { | for (a = 0; a < elemcount; a++, old += 2) { | ||||
| otype = sdna->types[old[0]]; | otype = types[old[0]]; | ||||
| oname = sdna->names[old[1]]; | oname = names[old[1]]; | ||||
| if (elem_strcmp(name, oname) == 0) { /* name equal */ | if (elem_strcmp(name, oname) == 0) { /* name equal */ | ||||
| return strcmp(type, otype) == 0; /* type equal */ | return strcmp(type, otype) == 0; /* type equal */ | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static bool elem_exists(const SDNA *sdna, const char *type, const char *name, const short *old) | |||||
| { | |||||
| return elem_exists_impl( | |||||
| /* Expand SDNA. */ | |||||
| sdna->types, | |||||
| sdna->names, | |||||
| /* Regular args. */ | |||||
| type, | |||||
| name, | |||||
| old); | |||||
| } | |||||
| static bool elem_exists_alias(const SDNA *sdna, | |||||
| const char *type, | |||||
| const char *name, | |||||
| const short *old) | |||||
| { | |||||
| return elem_exists_impl( | |||||
| /* Expand SDNA. */ | |||||
| sdna->alias.types, | |||||
| sdna->alias.names, | |||||
| /* Regular args. */ | |||||
| type, | |||||
| name, | |||||
| old); | |||||
| } | |||||
| /** | /** | ||||
| * Returns the address of the data for the specified field within olddata | * Returns the address of the data for the specified field within olddata | ||||
| * according to the struct format pointed to by old, or NULL if no such | * according to the struct format pointed to by old, or NULL if no such | ||||
| * field can be found. | * field can be found. | ||||
| * | * | ||||
| * Passing olddata=NULL doesn't work reliably for existence checks; it will | * Passing olddata=NULL doesn't work reliably for existence checks; it will | ||||
| * return NULL both when the field is found at offset 0 and when it is not | * return NULL both when the field is found at offset 0 and when it is not | ||||
| * found at all. For field existence checks, use #elem_exists() instead. | * found at all. For field existence checks, use #elem_exists() instead. | ||||
| ▲ Show 20 Lines • Show All 440 Lines • ▼ Show 20 Lines | if (SDNAnr != -1) { | ||||
| if (found) { | if (found) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool DNA_struct_elem_find_alias(const SDNA *sdna, | |||||
| const char *stype, | |||||
| const char *vartype, | |||||
| const char *name) | |||||
| { | |||||
| const int SDNAnr = DNA_struct_find_alias_nr(sdna, stype); | |||||
| if (SDNAnr != -1) { | |||||
| const short *const spo = sdna->structs[SDNAnr]; | |||||
| const bool found = elem_exists_alias(sdna, vartype, name, spo); | |||||
| if (found) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| /** | /** | ||||
| * Returns the size in bytes of a primitive type. | * Returns the size in bytes of a primitive type. | ||||
| */ | */ | ||||
| int DNA_elem_type_size(const eSDNA_Type elem_nr) | int DNA_elem_type_size(const eSDNA_Type elem_nr) | ||||
| { | { | ||||
| /* should contain all enum types */ | /* should contain all enum types */ | ||||
| switch (elem_nr) { | switch (elem_nr) { | ||||
| case SDNA_TYPE_CHAR: | case SDNA_TYPE_CHAR: | ||||
| ▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | for (int struct_nr = 0; struct_nr < sdna->structs_len; struct_nr++) { | ||||
| else { | else { | ||||
| sdna->alias.names[sp[1]] = sdna->names[sp[1]]; | sdna->alias.names[sp[1]] = sdna->names[sp[1]]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_ghash_free(struct_map_alias_from_static, NULL, NULL); | BLI_ghash_free(struct_map_alias_from_static, NULL, NULL); | ||||
| BLI_ghash_free(elem_map_alias_from_static, MEM_freeN, NULL); | BLI_ghash_free(elem_map_alias_from_static, MEM_freeN, NULL); | ||||
| #ifdef WITH_DNA_GHASH | |||||
| { | |||||
| /* create a ghash lookup to speed up */ | |||||
| struct GHash *structs_map = BLI_ghash_str_new_ex(__func__, sdna->structs_len); | |||||
| for (intptr_t nr = 0; nr < sdna->structs_len; nr++) { | |||||
| const short *sp = sdna->structs[nr]; | |||||
| BLI_ghash_insert(structs_map, (void *)sdna->alias.types[sp[0]], POINTER_FROM_INT(nr)); | |||||
| } | |||||
| sdna->alias.structs_map = structs_map; | |||||
| } | |||||
| #endif | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||