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:
authorCampbell Barton <ideasman42@gmail.com>2019-05-22 02:15:06 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-05-22 02:19:05 +0300
commit73f7ed7ffadcae3795910155d52453650d4e97a4 (patch)
tree0dae8e1a84030afea3afea00faff15c0fe7d344a /source/blender/makesdna/intern
parent8accb5a46f4a498327ddd41ffb6e07972b373422 (diff)
dna_genfile: add SDNA struct/elem queries that use alias names
Allow versioning code to use checks which use run-time naming instead of the old names which are only listed in dna_rename_defs.h. Addresses T64791.
Diffstat (limited to 'source/blender/makesdna/intern')
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c161
1 files changed, 147 insertions, 14 deletions
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 2e89629b05e..82c356ab662 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -39,9 +39,7 @@
#include "BLI_memarena.h"
#include "BLI_string.h"
-#ifdef WITH_DNA_GHASH
-# include "BLI_ghash.h"
-#endif
+#include "BLI_ghash.h"
#include "DNA_genfile.h"
#include "DNA_sdna_types.h" // for SDNA ;-)
@@ -161,6 +159,11 @@ void DNA_sdna_free(SDNA *sdna)
MEM_SAFE_FREE(sdna->alias.names);
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);
}
@@ -222,18 +225,29 @@ static void printstruct(SDNA *sdna, short strnr)
/**
* 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. */
+ const char **types,
+ const int UNUSED(types_len),
+ short **const structs,
+ const int structs_len,
+#ifdef WITH_DNA_GHASH
+ GHash *structs_map,
+#endif
+ /* Regular args. */
+ const char *str,
+ unsigned int *index_last)
{
- if (*index_last < sdna->structs_len) {
- const short *sp = sdna->structs[*index_last];
- if (STREQ(sdna->types[sp[0]], str)) {
+ if (*index_last < structs_len) {
+ const short *sp = structs[*index_last];
+ if (STREQ(types[sp[0]], str)) {
return *index_last;
}
}
#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) {
const int index = POINTER_AS_INT(*index_p);
*index_last = index;
@@ -242,9 +256,9 @@ int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index
}
#else
{
- for (int index = 0; index < sdna->structs_len; index++) {
- const short *sp = sdna->structs[index];
- if (STREQ(sdna->types[sp[0]], str)) {
+ for (int index = 0; index < structs_len; index++) {
+ const short *sp = structs[index];
+ if (STREQ(types[sp[0]], str)) {
*index_last = index;
return index;
}
@@ -254,12 +268,58 @@ int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index
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->types_len,
+ sdna->structs,
+ sdna->structs_len,
+#ifdef WITH_DNA_GHASH
+ sdna->structs_map,
+#endif
+ /* Regular args. */
+ str,
+ index_last);
+}
+
+/** \note requires #DNA_sdna_alias_data_ensure_structs_map to be called. */
+int DNA_struct_alias_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last)
+{
+#ifdef WITH_DNA_GHASH
+ BLI_assert(sdna->alias.structs_map != NULL);
+#endif
+ return dna_struct_find_nr_ex_impl(
+ /* Expand SDNA. */
+ sdna->alias.types,
+ sdna->types_len,
+ sdna->structs,
+ sdna->structs_len,
+#ifdef WITH_DNA_GHASH
+ sdna->alias.structs_map,
+#endif
+ /* Regular args. */
+ str,
+ index_last);
+}
+
int DNA_struct_find_nr(const SDNA *sdna, const char *str)
{
unsigned int index_last_dummy = UINT_MAX;
return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy);
}
+/** \note requires #DNA_sdna_alias_data_ensure_structs_map to be called. */
+int DNA_struct_alias_find_nr(const SDNA *sdna, const char *str)
+{
+ unsigned int index_last_dummy = UINT_MAX;
+ return DNA_struct_alias_find_nr_ex(sdna, str, &index_last_dummy);
+}
+
/* ************************* END DIV ********************** */
/* ************************* READ DNA ********************** */
@@ -909,7 +969,14 @@ static int elem_strcmp(const char *name, const char *oname)
* \param old: Pointer to struct information in sdna
* \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;
const char *otype, *oname;
@@ -918,8 +985,8 @@ static bool elem_exists(const SDNA *sdna, const char *type, const char *name, co
elemcount = old[1];
old += 2;
for (a = 0; a < elemcount; a++, old += 2) {
- otype = sdna->types[old[0]];
- oname = sdna->names[old[1]];
+ otype = types[old[0]];
+ oname = names[old[1]];
if (elem_strcmp(name, oname) == 0) { /* name equal */
return strcmp(type, otype) == 0; /* type equal */
@@ -928,6 +995,33 @@ static bool elem_exists(const SDNA *sdna, const char *type, const char *name, co
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
* according to the struct format pointed to by old, or NULL if no such
@@ -1384,6 +1478,25 @@ bool DNA_struct_elem_find(const SDNA *sdna,
return false;
}
+/** \note requires #DNA_sdna_alias_data_ensure_structs_map to be called. */
+bool DNA_struct_alias_elem_find(const SDNA *sdna,
+ const char *stype,
+ const char *vartype,
+ const char *name)
+{
+ const int SDNAnr = DNA_struct_alias_find_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.
*/
@@ -1629,4 +1742,24 @@ void DNA_sdna_alias_data_ensure(SDNA *sdna)
BLI_ghash_free(elem_map_alias_from_static, MEM_freeN, NULL);
}
+/**
+ * Separated from #DNA_sdna_alias_data_ensure because it's not needed
+ * unless we want to lookup aliased struct names (#DNA_struct_alias_find_nr and friends).
+ */
+void DNA_sdna_alias_data_ensure_structs_map(SDNA *sdna)
+{
+ DNA_sdna_alias_data_ensure(sdna);
+#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;
+#else
+ UNUSED_VARS(sdna);
+#endif
+}
+
/** \} */