Revert "DNA: optimize data reconstruction"
[blender.git] / source / blender / makesdna / intern / dna_genfile.c
index 934c75e75c03447e89e3432c5d96c86b295bc213..e25bbdf7d466eba56b3f88c78b4c2aec591397d3 100644 (file)
@@ -144,7 +144,6 @@ void DNA_sdna_free(SDNA *sdna)
        }
 
        MEM_freeN((void *)sdna->names);
-       MEM_freeN((void *)sdna->names_array_len);
        MEM_freeN((void *)sdna->types);
        MEM_freeN(sdna->structs);
 
@@ -182,18 +181,32 @@ static bool ispointer(const char *name)
  */
 static int elementsize(const SDNA *sdna, short type, short name)
 {
-       int len;
-       const char *cp = sdna->names[name];
+       int mul, namelen, len;
+       const char *cp;
+
+       cp = sdna->names[name];
        len = 0;
 
+       namelen = strlen(cp);
        /* is it a pointer or function pointer? */
        if (ispointer(cp)) {
                /* has the name an extra length? (array) */
-               len = sdna->pointer_size * sdna->names_array_len[name];
+               mul = 1;
+               if (cp[namelen - 1] == ']') {
+                       mul = DNA_elem_array_size(cp);
+               }
+
+               len = sdna->pointer_size * mul;
        }
        else if (sdna->types_size[type]) {
                /* has the name an extra length? (array) */
-               len = (int)sdna->types_size[type] * sdna->names_array_len[name];
+               mul = 1;
+               if (cp[namelen - 1] == ']') {
+                       mul = DNA_elem_array_size(cp);
+               }
+
+               len = mul * sdna->types_size[type];
+
        }
 
        return len;
@@ -486,15 +499,6 @@ static bool init_structDNA(
                }
        }
 
-       /* Cache name size. */
-       {
-               short *names_array_len = MEM_mallocN(sizeof(*names_array_len) * sdna->nr_names, __func__);
-               for (int i = 0; i < sdna->nr_names; i++) {
-                       names_array_len[i] = DNA_elem_array_size(sdna->names[i]);
-               }
-               sdna->names_array_len = names_array_len;
-       }
-
        return true;
 }
 
@@ -723,19 +727,21 @@ static eSDNA_Type sdna_type_nr(const char *dna_type)
  *
  * \param ctype: Name of type to convert to
  * \param otype: Name of type to convert from
- * \param name_array_len: Result of #DNA_elem_array_size for this element.
+ * \param name: Field name to extract array-size information
  * \param curdata: Where to put converted data
  * \param olddata: Data of type otype to convert
  */
 static void cast_elem(
-        const char *ctype, const char *otype, int name_array_len,
+        const char *ctype, const char *otype, const char *name,
         char *curdata, const char *olddata)
 {
        double val = 0.0;
-       int curlen = 1, oldlen = 1;
+       int arrlen, curlen = 1, oldlen = 1;
 
        eSDNA_Type ctypenr, otypenr;
 
+       arrlen = DNA_elem_array_size(name);
+
        if ( (otypenr = sdna_type_nr(otype)) == -1 ||
             (ctypenr = sdna_type_nr(ctype)) == -1)
        {
@@ -746,7 +752,7 @@ static void cast_elem(
        oldlen = DNA_elem_type_size(otypenr);
        curlen = DNA_elem_type_size(ctypenr);
 
-       while (name_array_len > 0) {
+       while (arrlen > 0) {
                switch (otypenr) {
                        case SDNA_TYPE_CHAR:
                                val = *olddata; break;
@@ -793,7 +799,7 @@ static void cast_elem(
 
                olddata += oldlen;
                curdata += curlen;
-               name_array_len--;
+               arrlen--;
        }
 }
 
@@ -804,15 +810,18 @@ static void cast_elem(
  *
  * \param curlen: Pointer length to conver to
  * \param oldlen: Length of pointers in olddata
- * \param name_array_len: Result of #DNA_elem_array_size for this element.
+ * \param name: Field name to extract array-size information
  * \param curdata: Where to put converted data
  * \param olddata: Data to convert
  */
-static void cast_pointer(int curlen, int oldlen, int name_array_len, char *curdata, const char *olddata)
+static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata, const char *olddata)
 {
        int64_t lval;
+       int arrlen;
+
+       arrlen = DNA_elem_array_size(name);
 
-       while (name_array_len > 0) {
+       while (arrlen > 0) {
 
                if (curlen == oldlen) {
                        memcpy(curdata, olddata, curlen);
@@ -835,7 +844,7 @@ static void cast_pointer(int curlen, int oldlen, int name_array_len, char *curda
 
                olddata += oldlen;
                curdata += curlen;
-               name_array_len--;
+               arrlen--;
 
        }
 }
@@ -950,7 +959,7 @@ static const char *find_elem(
  * \param newsdna: SDNA of current Blender
  * \param oldsdna: SDNA of Blender that saved file
  * \param type: current field type name
- * \param new_name_nr: current field name number.
+ * \param name: current field name
  * \param curdata: put field data converted to newsdna here
  * \param old: pointer to struct info in oldsdna
  * \param olddata: struct contents laid out according to oldsdna
@@ -959,7 +968,7 @@ static void reconstruct_elem(
         const SDNA *newsdna,
         const SDNA *oldsdna,
         const char *type,
-        const int new_name_nr,
+        const char *name,
         char *curdata,
         const short *old,
         const char *olddata)
@@ -973,11 +982,10 @@ static void reconstruct_elem(
         * (nzc 2-4-2001 I want the 'unsigned' bit to be parsed as well. Where
         * can I force this?)
         */
-       int a, elemcount, len, countpos, mul;
+       int a, elemcount, len, countpos, oldsize, cursize, mul;
        const char *otype, *oname, *cp;
 
        /* is 'name' an array? */
-       const char *name = newsdna->names[new_name_nr];
        cp = name;
        countpos = 0;
        while (*cp && *cp != '[') {
@@ -989,7 +997,6 @@ static void reconstruct_elem(
        elemcount = old[1];
        old += 2;
        for (a = 0; a < elemcount; a++, old += 2) {
-               const int old_name_nr = old[1];
                otype = oldsdna->types[old[0]];
                oname = oldsdna->names[old[1]];
                len = elementsize(oldsdna, old[0], old[1]);
@@ -997,17 +1004,13 @@ static void reconstruct_elem(
                if (strcmp(name, oname) == 0) { /* name equal */
 
                        if (ispointer(name)) {  /* pointer of functionpointer afhandelen */
-                               cast_pointer(newsdna->pointer_size, oldsdna->pointer_size,
-                                            newsdna->names_array_len[new_name_nr],
-                                            curdata, olddata);
+                               cast_pointer(newsdna->pointer_size, oldsdna->pointer_size, name, curdata, olddata);
                        }
                        else if (strcmp(type, otype) == 0) {    /* type equal */
                                memcpy(curdata, olddata, len);
                        }
                        else {
-                               cast_elem(type, otype,
-                                         newsdna->names_array_len[new_name_nr],
-                                         curdata, olddata);
+                               cast_elem(type, otype, name, curdata, olddata);
                        }
 
                        return;
@@ -1015,31 +1018,31 @@ static void reconstruct_elem(
                else if (countpos != 0) {  /* name is an array */
 
                        if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) {  /* basis equal */
-                               const int new_name_array_len = newsdna->names_array_len[new_name_nr];
-                               const int old_name_array_len = oldsdna->names_array_len[old_name_nr];
-                               const int min_name_array_len = MIN2(new_name_array_len, old_name_array_len);
+
+                               cursize = DNA_elem_array_size(name);
+                               oldsize = DNA_elem_array_size(oname);
 
                                if (ispointer(name)) {  /* handle pointer or functionpointer */
                                        cast_pointer(newsdna->pointer_size, oldsdna->pointer_size,
-                                                    min_name_array_len,
+                                                    cursize > oldsize ? oname : name,
                                                     curdata, olddata);
                                }
                                else if (strcmp(type, otype) == 0) {  /* type equal */
                                        /* size of single old array element */
-                                       mul = len / old_name_array_len;
+                                       mul = len / oldsize;
                                        /* smaller of sizes of old and new arrays */
-                                       mul *= min_name_array_len;
+                                       mul *= (cursize < oldsize) ? cursize : oldsize;
 
                                        memcpy(curdata, olddata, mul);
 
-                                       if (old_name_array_len > new_name_array_len && strcmp(type, "char") == 0) {
+                                       if (oldsize > cursize && strcmp(type, "char") == 0) {
                                                /* string had to be truncated, ensure it's still null-terminated */
                                                curdata[mul - 1] = '\0';
                                        }
                                }
                                else {
                                        cast_elem(type, otype,
-                                                 min_name_array_len,
+                                                 cursize > oldsize ? oname : name,
                                                  curdata, olddata);
                                }
                                return;
@@ -1081,7 +1084,7 @@ static void reconstruct_struct(
        const char *type;
        const char *cpo;
        char *cpc;
-       const char *name;
+       const char *name, *nameo;
 
        unsigned int oldsdna_index_last = UINT_MAX;
        unsigned int cursdna_index_last = UINT_MAX;
@@ -1114,13 +1117,9 @@ static void reconstruct_struct(
 
                elen = elementsize(newsdna, spc[0], spc[1]);
 
-               /* Skip pad bytes. */
-               if (name[0] == '_' || (name[0] == '*' && name[1] == '_')) {
-                       cpc += elen;
-               }
-               else if (spc[0] >= firststructtypenr && !ispointer(name)) {
+               /* test: is type a struct? */
+               if (spc[0] >= firststructtypenr && !ispointer(name)) {
                        /* struct field type */
-
                        /* where does the old struct data start (and is there an old one?) */
                        cpo = (char *)find_elem(oldsdna, type, name, spo, data, &sppo);
 
@@ -1129,8 +1128,9 @@ static void reconstruct_struct(
                                curSDNAnr = DNA_struct_find_nr_ex(newsdna, type, &cursdna_index_last);
 
                                /* array! */
-                               mul = newsdna->names_array_len[spc[1]];
-                               mulo = oldsdna->names_array_len[sppo[1]];
+                               mul = DNA_elem_array_size(name);
+                               nameo = oldsdna->names[sppo[1]];
+                               mulo = DNA_elem_array_size(nameo);
 
                                eleno = elementsize(oldsdna, sppo[0], sppo[1]);
 
@@ -1153,7 +1153,7 @@ static void reconstruct_struct(
                }
                else {
                        /* non-struct field type */
-                       reconstruct_elem(newsdna, oldsdna, type, spc[1], cpc, spo, data);
+                       reconstruct_elem(newsdna, oldsdna, type, name, cpc, spo, data);
                        cpc += elen;
                }
        }
@@ -1190,7 +1190,6 @@ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data)
        for (a = 0; a < elemcount; a++, spc += 2) {
                type = oldsdna->types[spc[0]];
                name = oldsdna->names[spc[1]];
-               const int old_name_array_len = oldsdna->names_array_len[spc[1]];
 
                /* elementsize = including arraysize */
                elen = elementsize(oldsdna, spc[0], spc[1]);
@@ -1203,7 +1202,7 @@ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data)
                        if (cpo) {
                                oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last);
 
-                               mul = old_name_array_len;
+                               mul = DNA_elem_array_size(name);
                                elena = elen / mul;
 
                                while (mul--) {
@@ -1216,7 +1215,7 @@ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data)
                        /* non-struct field type */
                        if (ispointer(name)) {
                                if (oldsdna->pointer_size == 8) {
-                                       BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len);
+                                       BLI_endian_switch_int64_array((int64_t *)cur, DNA_elem_array_size(name));
                                }
                        }
                        else {
@@ -1229,7 +1228,7 @@ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data)
                                        }
 
                                        if (skip == false) {
-                                               BLI_endian_switch_int16_array((int16_t *)cur, old_name_array_len);
+                                               BLI_endian_switch_int16_array((int16_t *)cur, DNA_elem_array_size(name));
                                        }
                                }
                                else if (ELEM(spc[0], SDNA_TYPE_INT, SDNA_TYPE_FLOAT)) {
@@ -1237,10 +1236,10 @@ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data)
                                         * but turns out we only used for runtime vars and
                                         * only once for a struct type that's no longer used. */
 
-                                       BLI_endian_switch_int32_array((int32_t *)cur, old_name_array_len);
+                                       BLI_endian_switch_int32_array((int32_t *)cur, DNA_elem_array_size(name));
                                }
                                else if (ELEM(spc[0], SDNA_TYPE_INT64, SDNA_TYPE_UINT64, SDNA_TYPE_DOUBLE)) {
-                                       BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len);
+                                       BLI_endian_switch_int64_array((int64_t *)cur, DNA_elem_array_size(name));
                                }
                        }
                }