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:
authorBastien Montagne <montagne29@wanadoo.fr>2016-06-07 10:43:56 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-06-07 10:43:56 +0300
commit6f20d64f3a653ba288c68ce08bd88067f7f5d6cc (patch)
tree2dfacbbe76aeb0b908c89a66efed803dc6172d0a /source/blender/blenloader/intern/readfile.c
parent434a851703e0ced983f9e28d9faf2f81d5ffb823 (diff)
parent18f87c8dcb6e6f001eaa2c18ca7206b907a5d3c2 (diff)
Merge branch 'id-remap' into asset-experiments
Conflicts: source/blender/makesdna/DNA_ID.h
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r--source/blender/blenloader/intern/readfile.c134
1 files changed, 70 insertions, 64 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5b2ab76197d..79aba95b632 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -218,14 +218,15 @@
/***/
typedef struct OldNew {
- void *old, *newp;
+ const void *old;
+ void *newp;
int nr;
} OldNew;
typedef struct OldNewMap {
OldNew *entries;
int nentries, entriessize;
- int sorted;
+ bool sorted;
int lasthit;
} OldNewMap;
@@ -291,12 +292,13 @@ static int verg_oldnewmap(const void *v1, const void *v2)
static void oldnewmap_sort(FileData *fd)
{
+ BLI_assert(fd->libmap->sorted == false);
qsort(fd->libmap->entries, fd->libmap->nentries, sizeof(OldNew), verg_oldnewmap);
fd->libmap->sorted = 1;
}
/* nr is zero for data, and ID code for libdata */
-static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr)
+static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
{
OldNew *entry;
@@ -313,7 +315,7 @@ static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int n
entry->nr = nr;
}
-void blo_do_versions_oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr)
+void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
{
oldnewmap_insert(onm, oldaddr, newaddr, nr);
}
@@ -368,7 +370,7 @@ static int oldnewmap_lookup_entry_full(const OldNewMap *onm, const void *addr, i
return -1;
}
-static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_users)
+static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool increase_users)
{
int i;
@@ -398,7 +400,7 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_
}
/* for libdata, nr has ID code, no increment */
-static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
+static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib)
{
if (addr == NULL) {
return NULL;
@@ -406,11 +408,8 @@ static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
/* lasthit works fine for non-libdata, linking there is done in same sequence as writing */
if (onm->sorted) {
- OldNew entry_s, *entry;
-
- entry_s.old = addr;
-
- entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap);
+ const OldNew entry_s = {.old = addr};
+ OldNew *entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap);
if (entry) {
ID *id = entry->newp;
@@ -490,53 +489,57 @@ void blo_join_main(ListBase *mainlist)
}
}
-static void split_libdata(ListBase *lb, Main *first)
+static void split_libdata(ListBase *lb_src, Main **lib_main_array, const unsigned int lib_main_array_len)
{
- ListBase *lbn;
- ID *id, *idnext;
- Main *mainvar;
-
- id = lb->first;
- while (id) {
+ for (ID *id = lb_src->first, *idnext; id; id = idnext) {
idnext = id->next;
+
if (id->lib) {
- mainvar = first;
- while (mainvar) {
- if (mainvar->curlib == id->lib) {
- lbn= which_libbase(mainvar, GS(id->name));
- BLI_remlink(lb, id);
- BLI_addtail(lbn, id);
- break;
- }
- mainvar = mainvar->next;
+ if (((unsigned int)id->lib->temp_index < lib_main_array_len) &&
+ /* this check should never fail, just incase 'id->lib' is a dangling pointer. */
+ (lib_main_array[id->lib->temp_index]->curlib == id->lib))
+ {
+ Main *mainvar = lib_main_array[id->lib->temp_index];
+ ListBase *lb_dst = which_libbase(mainvar, GS(id->name));
+ BLI_remlink(lb_src, id);
+ BLI_addtail(lb_dst, id);
+ }
+ else {
+ printf("%s: invalid library for '%s'\n", __func__, id->name);
+ BLI_assert(0);
}
- if (mainvar == NULL) printf("error split_libdata\n");
}
- id = idnext;
}
}
void blo_split_main(ListBase *mainlist, Main *main)
{
- ListBase *lbarray[MAX_LIBARRAY];
- Library *lib;
- int i;
-
mainlist->first = mainlist->last = main;
main->next = NULL;
if (BLI_listbase_is_empty(&main->library))
return;
- for (lib = main->library.first; lib; lib = lib->id.next) {
+ /* (Library.temp_index -> Main), lookup table */
+ const unsigned int lib_main_array_len = BLI_listbase_count(&main->library);
+ Main **lib_main_array = MEM_mallocN(lib_main_array_len * sizeof(*lib_main_array), __func__);
+
+ int i = 0;
+ for (Library *lib = main->library.first; lib; lib = lib->id.next, i++) {
Main *libmain = BKE_main_new();
libmain->curlib = lib;
BLI_addtail(mainlist, libmain);
+ lib->temp_index = i;
+ lib_main_array[i] = libmain;
}
+ ListBase *lbarray[MAX_LIBARRAY];
i = set_listbasepointers(main, lbarray);
- while (i--)
- split_libdata(lbarray[i], main->next);
+ while (i--) {
+ split_libdata(lbarray[i], lib_main_array, lib_main_array_len);
+ }
+
+ MEM_freeN(lib_main_array);
}
static void read_file_version(FileData *fd, Main *main)
@@ -1417,7 +1420,7 @@ BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
/* ************** OLD POINTERS ******************* */
-static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
+static void *newdataadr(FileData *fd, const void *adr) /* only direct databocks */
{
return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
}
@@ -1434,7 +1437,7 @@ static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
* fcurve group pointer and keeps lasthit optimal for linking all further
* fcurves.
*/
-static void *newdataadr_ex(FileData *fd, void *adr, bool increase_lasthit) /* only direct databocks */
+static void *newdataadr_ex(FileData *fd, const void *adr, bool increase_lasthit) /* only direct databocks */
{
if (increase_lasthit) {
return newdataadr(fd, adr);
@@ -1447,38 +1450,38 @@ static void *newdataadr_ex(FileData *fd, void *adr, bool increase_lasthit) /* o
}
}
-static void *newdataadr_no_us(FileData *fd, void *adr) /* only direct databocks */
+static void *newdataadr_no_us(FileData *fd, const void *adr) /* only direct databocks */
{
return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
}
-static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
+static void *newglobadr(FileData *fd, const void *adr) /* direct datablocks with global linking */
{
return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
}
-static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
+static void *newimaadr(FileData *fd, const void *adr) /* used to restore image data after undo */
{
if (fd->imamap && adr)
return oldnewmap_lookup_and_inc(fd->imamap, adr, true);
return NULL;
}
-static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
+static void *newmclipadr(FileData *fd, const void *adr) /* used to restore movie clip data after undo */
{
if (fd->movieclipmap && adr)
return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true);
return NULL;
}
-static void *newsoundadr(FileData *fd, void *adr) /* used to restore sound data after undo */
+static void *newsoundadr(FileData *fd, const void *adr) /* used to restore sound data after undo */
{
if (fd->soundmap && adr)
return oldnewmap_lookup_and_inc(fd->soundmap, adr, true);
return NULL;
}
-static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
+static void *newpackedadr(FileData *fd, const void *adr) /* used to restore packed data after undo */
{
if (fd->packedmap && adr)
return oldnewmap_lookup_and_inc(fd->packedmap, adr, true);
@@ -1487,17 +1490,17 @@ static void *newpackedadr(FileData *fd, void *adr) /* used to restore packe
}
-static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
+static void *newlibadr(FileData *fd, const void *lib, const void *adr) /* only lib data */
{
return oldnewmap_liblookup(fd->libmap, adr, lib);
}
-void *blo_do_versions_newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
+void *blo_do_versions_newlibadr(FileData *fd, const void *lib, const void *adr) /* only lib data */
{
return newlibadr(fd, lib, adr);
}
-static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user number */
+static void *newlibadr_us(FileData *fd, const void *lib, const void *adr) /* increases user number */
{
ID *id = newlibadr(fd, lib, adr);
@@ -1506,15 +1509,18 @@ static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user
return id;
}
-void *blo_do_versions_newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user number */
+void *blo_do_versions_newlibadr_us(FileData *fd, const void *lib, const void *adr) /* increases user number */
{
return newlibadr_us(fd, lib, adr);
}
-static void change_idid_adr_fd(FileData *fd, void *old, void *new)
+static void change_idid_adr_fd(FileData *fd, const void *old, void *new)
{
int i;
+ /* use a binary search if we have a sorted libmap, for now it's not needed. */
+ BLI_assert(fd->libmap->sorted == false);
+
for (i = 0; i < fd->libmap->nentries; i++) {
OldNew *entry = &fd->libmap->entries[i];
@@ -7889,7 +7895,7 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a
return bhead;
}
-static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **r_id)
+static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short tag, ID **r_id)
{
/* this routine reads a libblock and its direct data. Use link functions to connect it all
*/
@@ -7901,8 +7907,8 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
/* In undo case, most libs and linked data should be kept as is from previous state (see BLO_read_from_memfile).
* However, some needed by the snapshot being read may have been removed in previous one, and would go missing.
* This leads e.g. to desappearing objects in some undo/redo case, see T34446.
- * That means we have to carefully check whether current lib or libdata already exits in old main, if it does
- * we merely copy it over into new main area, otherwise we have to do a full read of that bhead... */
+ * That means we have to carefully check whether current lib or libdata already exits in old main, if it does
+ * we merely copy it over into new main area, otherwise we have to do a full read of that bhead... */
if (fd->memfile && ELEM(bhead->code, ID_LI, ID_ID)) {
const char *idname = bhead_id_name(fd, bhead);
@@ -7975,7 +7981,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
if (!id)
return blo_nextbhead(fd, bhead);
- id->tag = flag | LIB_TAG_NEED_LINK;
+ id->tag = tag | LIB_TAG_NEED_LINK;
id->lib = main->curlib;
id->us = ID_FAKE_USERS(id);
id->icon_id = 0;
@@ -9669,7 +9675,7 @@ static void give_base_to_groups(
}
}
-static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const short flag)
+static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const short tag)
{
ListBase *lb = which_libbase(mainvar, idcode);
ID *ph_id = BKE_libblock_alloc_notest(idcode);
@@ -9678,7 +9684,7 @@ static ID *create_placeholder(Main *mainvar, const short idcode, const char *idn
BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
BKE_libblock_init_empty(ph_id);
ph_id->lib = mainvar->curlib;
- ph_id->tag = flag | LIB_TAG_MISSING;
+ ph_id->tag = tag | LIB_TAG_MISSING;
ph_id->us = ID_FAKE_USERS(ph_id);
ph_id->icon_id = 0;
@@ -10067,21 +10073,22 @@ void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
/* ************* READ LIBRARY ************** */
-static int mainvar_count_libread_blocks(Main *mainvar)
+static int mainvar_id_tag_any_check(Main *mainvar, const short tag)
{
ListBase *lbarray[MAX_LIBARRAY];
- int a, tot = 0;
+ int a;
a = set_listbasepointers(mainvar, lbarray);
while (a--) {
ID *id;
for (id = lbarray[a]->first; id; id = id->next) {
- if (id->tag & LIB_TAG_READ)
- tot++;
+ if (id->tag & tag) {
+ return true;
+ }
}
}
- return tot;
+ return false;
}
static void read_libraries(FileData *basefd, ListBase *mainlist)
@@ -10101,10 +10108,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
/* test 1: read libdata */
mainptr= mainl->next;
while (mainptr) {
- int tot = mainvar_count_libread_blocks(mainptr);
-
- // printf("found LIB_TAG_READ %s\n", mainptr->curlib->name);
- if (tot) {
+ if (mainvar_id_tag_any_check(mainptr, LIB_TAG_READ)) {
+ // printf("found LIB_TAG_READ %s\n", mainptr->curlib->name);
+
FileData *fd = mainptr->curlib->filedata;
if (fd == NULL) {