Add a mechanism to abort a blend file reading on critical error.
This commit introduces a new Main boolean flag that marks is as invalid. Higher-level file reading code does checks on this flag to abort reading process if needed. This is an implementation of the #105083 design task. Given the extense of the change, I do not think this should be considered for 3.5 and previous LTS releases.
This commit is contained in:
@@ -138,6 +138,13 @@ typedef struct Main {
|
|||||||
*/
|
*/
|
||||||
bool is_locked_for_linking;
|
bool is_locked_for_linking;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set, indicates that an unrecoverable error/data corruption was detected.
|
||||||
|
* Should only be set by readfile code, and used by upper-level code (typically #setup_app_data)
|
||||||
|
* to cancel a file reading operation.
|
||||||
|
*/
|
||||||
|
bool is_read_invalid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if this main is the 'GMAIN' of current Blender.
|
* True if this main is the 'GMAIN' of current Blender.
|
||||||
*
|
*
|
||||||
|
@@ -476,6 +476,13 @@ void BKE_blendfile_read_setup_ex(bContext *C,
|
|||||||
const bool startup_update_defaults,
|
const bool startup_update_defaults,
|
||||||
const char *startup_app_template)
|
const char *startup_app_template)
|
||||||
{
|
{
|
||||||
|
if (bfd->main->is_read_invalid) {
|
||||||
|
BKE_reports_prepend(reports->reports,
|
||||||
|
"File could not be read, critical data corruption detected");
|
||||||
|
BLO_blendfiledata_free(bfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (startup_update_defaults) {
|
if (startup_update_defaults) {
|
||||||
if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
||||||
BLO_update_defaults_startup_blend(bfd->main, startup_app_template);
|
BLO_update_defaults_startup_blend(bfd->main, startup_app_template);
|
||||||
@@ -503,6 +510,10 @@ struct BlendFileData *BKE_blendfile_read(const char *filepath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlendFileData *bfd = BLO_read_from_file(filepath, eBLOReadSkip(params->skip_flags), reports);
|
BlendFileData *bfd = BLO_read_from_file(filepath, eBLOReadSkip(params->skip_flags), reports);
|
||||||
|
if (bfd && bfd->main->is_read_invalid) {
|
||||||
|
BLO_blendfiledata_free(bfd);
|
||||||
|
bfd = nullptr;
|
||||||
|
}
|
||||||
if (bfd) {
|
if (bfd) {
|
||||||
handle_subversion_warning(bfd->main, reports);
|
handle_subversion_warning(bfd->main, reports);
|
||||||
}
|
}
|
||||||
@@ -519,6 +530,10 @@ struct BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf,
|
|||||||
{
|
{
|
||||||
BlendFileData *bfd = BLO_read_from_memory(
|
BlendFileData *bfd = BLO_read_from_memory(
|
||||||
filebuf, filelength, eBLOReadSkip(params->skip_flags), reports);
|
filebuf, filelength, eBLOReadSkip(params->skip_flags), reports);
|
||||||
|
if (bfd && bfd->main->is_read_invalid) {
|
||||||
|
BLO_blendfiledata_free(bfd);
|
||||||
|
bfd = nullptr;
|
||||||
|
}
|
||||||
if (bfd) {
|
if (bfd) {
|
||||||
/* Pass. */
|
/* Pass. */
|
||||||
}
|
}
|
||||||
@@ -535,6 +550,10 @@ struct BlendFileData *BKE_blendfile_read_from_memfile(Main *bmain,
|
|||||||
{
|
{
|
||||||
BlendFileData *bfd = BLO_read_from_memfile(
|
BlendFileData *bfd = BLO_read_from_memfile(
|
||||||
bmain, BKE_main_blendfile_path(bmain), memfile, params, reports);
|
bmain, BKE_main_blendfile_path(bmain), memfile, params, reports);
|
||||||
|
if (bfd && bfd->main->is_read_invalid) {
|
||||||
|
BLO_blendfiledata_free(bfd);
|
||||||
|
bfd = nullptr;
|
||||||
|
}
|
||||||
if (bfd) {
|
if (bfd) {
|
||||||
/* Removing the unused workspaces, screens and wm is useless here, setup_app_data will switch
|
/* Removing the unused workspaces, screens and wm is useless here, setup_app_data will switch
|
||||||
* those lists with the ones from old bmain, which freeing is much more efficient than
|
* those lists with the ones from old bmain, which freeing is much more efficient than
|
||||||
|
@@ -288,6 +288,26 @@ struct LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh);
|
|||||||
*/
|
*/
|
||||||
void BLO_blendhandle_close(BlendHandle *bh);
|
void BLO_blendhandle_close(BlendHandle *bh);
|
||||||
|
|
||||||
|
/** Mark the given Main (and the 'root' local one in case of lib-split Mains) as invalid, and
|
||||||
|
* generate an error report containing given `message`. */
|
||||||
|
void BLO_read_invalidate_message(BlendHandle *bh, struct Main *bmain, const char *message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BLI_assert-like macro to check a condition, and if `false`, fail the whole .blend reading
|
||||||
|
* process by marking the Main data-base as invalid, and returning provided `_ret_value`.
|
||||||
|
*
|
||||||
|
* NOTE: About usages:
|
||||||
|
* - #BLI_assert should be used when the error is considered as a bug, but there is some code to
|
||||||
|
* recover from it and produce a valid Main data-base.
|
||||||
|
* - #BLO_read_assert_message should be used when the error is not considered as recoverable.
|
||||||
|
*/
|
||||||
|
#define BLO_read_assert_message(_check_expr, _ret_value, _bh, _bmain, _message) \
|
||||||
|
if (_check_expr) { \
|
||||||
|
BLO_read_invalidate_message((_bh), (_bmain), (_message)); \
|
||||||
|
return _ret_value; \
|
||||||
|
} \
|
||||||
|
(void)0
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
#define BLO_GROUP_MAX 32
|
#define BLO_GROUP_MAX 32
|
||||||
|
@@ -385,6 +385,13 @@ void BLO_blendhandle_close(BlendHandle *bh)
|
|||||||
blo_filedata_free(fd);
|
blo_filedata_free(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BLO_read_invalidate_message(BlendHandle *bh, Main *bmain, const char *message)
|
||||||
|
{
|
||||||
|
FileData *fd = reinterpret_cast<FileData *>(bh);
|
||||||
|
|
||||||
|
blo_readfile_invalidate(fd, bmain, message);
|
||||||
|
}
|
||||||
|
|
||||||
/**********/
|
/**********/
|
||||||
|
|
||||||
BlendFileData *BLO_read_from_file(const char *filepath,
|
BlendFileData *BLO_read_from_file(const char *filepath,
|
||||||
|
@@ -320,6 +320,10 @@ static void add_main_to_main(Main *mainvar, Main *from)
|
|||||||
ListBase *lbarray[INDEX_ID_MAX], *fromarray[INDEX_ID_MAX];
|
ListBase *lbarray[INDEX_ID_MAX], *fromarray[INDEX_ID_MAX];
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
|
if (from->is_read_invalid) {
|
||||||
|
mainvar->is_read_invalid = true;
|
||||||
|
}
|
||||||
|
|
||||||
set_listbasepointers(mainvar, lbarray);
|
set_listbasepointers(mainvar, lbarray);
|
||||||
a = set_listbasepointers(from, fromarray);
|
a = set_listbasepointers(from, fromarray);
|
||||||
while (a--) {
|
while (a--) {
|
||||||
@@ -340,6 +344,9 @@ void blo_join_main(ListBase *mainlist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((tojoin = mainl->next)) {
|
while ((tojoin = mainl->next)) {
|
||||||
|
if (tojoin->is_read_invalid) {
|
||||||
|
mainl->is_read_invalid = true;
|
||||||
|
}
|
||||||
add_main_to_main(mainl, tojoin);
|
add_main_to_main(mainl, tojoin);
|
||||||
BLI_remlink(mainlist, tojoin);
|
BLI_remlink(mainlist, tojoin);
|
||||||
BKE_main_free(tojoin);
|
BKE_main_free(tojoin);
|
||||||
@@ -548,6 +555,21 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blo_readfile_invalidate(FileData *fd, Main *bmain, const char *message)
|
||||||
|
{
|
||||||
|
/* Tag given bmain, and 'root 'local' main one (in case given one is a library one) as invalid.
|
||||||
|
*/
|
||||||
|
bmain->is_read_invalid = true;
|
||||||
|
for (; bmain->prev != nullptr; bmain = bmain->prev)
|
||||||
|
;
|
||||||
|
bmain->is_read_invalid = true;
|
||||||
|
|
||||||
|
BLO_reportf_wrap(fd->reports,
|
||||||
|
RPT_ERROR,
|
||||||
|
"A critical error happened (the blend file is likely corrupted): %s",
|
||||||
|
message);
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -3564,15 +3586,33 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
main->build_hash);
|
main->build_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
blo_do_versions_pre250(fd, lib, main);
|
if (!main->is_read_invalid) {
|
||||||
blo_do_versions_250(fd, lib, main);
|
blo_do_versions_pre250(fd, lib, main);
|
||||||
blo_do_versions_260(fd, lib, main);
|
}
|
||||||
blo_do_versions_270(fd, lib, main);
|
if (!main->is_read_invalid) {
|
||||||
blo_do_versions_280(fd, lib, main);
|
blo_do_versions_250(fd, lib, main);
|
||||||
blo_do_versions_290(fd, lib, main);
|
}
|
||||||
blo_do_versions_300(fd, lib, main);
|
if (!main->is_read_invalid) {
|
||||||
blo_do_versions_400(fd, lib, main);
|
blo_do_versions_260(fd, lib, main);
|
||||||
blo_do_versions_cycles(fd, lib, main);
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
blo_do_versions_270(fd, lib, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
blo_do_versions_280(fd, lib, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
blo_do_versions_290(fd, lib, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
blo_do_versions_300(fd, lib, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
blo_do_versions_400(fd, lib, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
blo_do_versions_cycles(fd, lib, main);
|
||||||
|
}
|
||||||
|
|
||||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||||
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
|
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
|
||||||
@@ -3582,7 +3622,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
main->is_locked_for_linking = false;
|
main->is_locked_for_linking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_versions_after_linking(Main *main, ReportList *reports)
|
static void do_versions_after_linking(FileData *fd, Main *main)
|
||||||
{
|
{
|
||||||
CLOG_INFO(&LOG,
|
CLOG_INFO(&LOG,
|
||||||
2,
|
2,
|
||||||
@@ -3595,13 +3635,27 @@ static void do_versions_after_linking(Main *main, ReportList *reports)
|
|||||||
/* Don't allow versioning to create new data-blocks. */
|
/* Don't allow versioning to create new data-blocks. */
|
||||||
main->is_locked_for_linking = true;
|
main->is_locked_for_linking = true;
|
||||||
|
|
||||||
do_versions_after_linking_250(main);
|
if (!main->is_read_invalid) {
|
||||||
do_versions_after_linking_260(main);
|
do_versions_after_linking_250(main);
|
||||||
do_versions_after_linking_270(main);
|
}
|
||||||
do_versions_after_linking_280(main, reports);
|
if (!main->is_read_invalid) {
|
||||||
do_versions_after_linking_290(main, reports);
|
do_versions_after_linking_260(main);
|
||||||
do_versions_after_linking_300(main, reports);
|
}
|
||||||
do_versions_after_linking_cycles(main);
|
if (!main->is_read_invalid) {
|
||||||
|
do_versions_after_linking_270(main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
do_versions_after_linking_280(fd, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
do_versions_after_linking_290(fd, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
do_versions_after_linking_300(fd, main);
|
||||||
|
}
|
||||||
|
if (!main->is_read_invalid) {
|
||||||
|
do_versions_after_linking_cycles(main);
|
||||||
|
}
|
||||||
|
|
||||||
main->is_locked_for_linking = false;
|
main->is_locked_for_linking = false;
|
||||||
}
|
}
|
||||||
@@ -3810,6 +3864,9 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||||||
static void blo_read_file_checks(Main *bmain)
|
static void blo_read_file_checks(Main *bmain)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
BLI_assert(bmain->next == nullptr);
|
||||||
|
BLI_assert(!bmain->is_read_invalid);
|
||||||
|
|
||||||
LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
|
LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
|
||||||
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
||||||
/* This pointer is deprecated and should always be nullptr. */
|
/* This pointer is deprecated and should always be nullptr. */
|
||||||
@@ -3914,6 +3971,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||||||
bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, nullptr);
|
bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bfd->main->is_read_invalid) {
|
||||||
|
return bfd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do before read_libraries, but skip undo case */
|
/* do before read_libraries, but skip undo case */
|
||||||
@@ -3927,6 +3988,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bfd->main->is_read_invalid) {
|
||||||
|
return bfd;
|
||||||
|
}
|
||||||
|
|
||||||
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
||||||
fd->reports->duration.libraries = PIL_check_seconds_timer();
|
fd->reports->duration.libraries = PIL_check_seconds_timer();
|
||||||
read_libraries(fd, &mainlist);
|
read_libraries(fd, &mainlist);
|
||||||
@@ -3953,7 +4018,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||||||
blo_split_main(&mainlist, bfd->main);
|
blo_split_main(&mainlist, bfd->main);
|
||||||
LISTBASE_FOREACH (Main *, mainvar, &mainlist) {
|
LISTBASE_FOREACH (Main *, mainvar, &mainlist) {
|
||||||
BLI_assert(mainvar->versionfile != 0);
|
BLI_assert(mainvar->versionfile != 0);
|
||||||
do_versions_after_linking(mainvar, fd->reports->reports);
|
do_versions_after_linking(fd, mainvar);
|
||||||
}
|
}
|
||||||
blo_join_main(&mainlist);
|
blo_join_main(&mainlist);
|
||||||
|
|
||||||
@@ -3963,6 +4028,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||||||
BKE_main_id_refcount_recompute(bfd->main, false);
|
BKE_main_id_refcount_recompute(bfd->main, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bfd->main->is_read_invalid) {
|
||||||
|
return bfd;
|
||||||
|
}
|
||||||
|
|
||||||
/* After all data has been read and versioned, uses LIB_TAG_NEW. Theoretically this should
|
/* After all data has been read and versioned, uses LIB_TAG_NEW. Theoretically this should
|
||||||
* not be calculated in the undo case, but it is currently needed even on undo to recalculate
|
* not be calculated in the undo case, but it is currently needed even on undo to recalculate
|
||||||
* a cache. */
|
* a cache. */
|
||||||
@@ -4174,6 +4243,10 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
|
|||||||
{
|
{
|
||||||
FileData *fd = static_cast<FileData *>(fdhandle);
|
FileData *fd = static_cast<FileData *>(fdhandle);
|
||||||
|
|
||||||
|
if (mainvar->is_read_invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BHead *bhead = find_bhead(fd, old);
|
BHead *bhead = find_bhead(fd, old);
|
||||||
if (bhead == nullptr) {
|
if (bhead == nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -4432,7 +4505,16 @@ ID *BLO_library_link_named_part(Main *mainl,
|
|||||||
const LibraryLink_Params *params)
|
const LibraryLink_Params *params)
|
||||||
{
|
{
|
||||||
FileData *fd = (FileData *)(*bh);
|
FileData *fd = (FileData *)(*bh);
|
||||||
return link_named_part(mainl, fd, idcode, name, params->flag);
|
|
||||||
|
ID *ret_id = nullptr;
|
||||||
|
if (!mainl->is_read_invalid) {
|
||||||
|
ret_id = link_named_part(mainl, fd, idcode, name, params->flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainl->is_read_invalid) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ret_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* common routine to append/link something from a library */
|
/* common routine to append/link something from a library */
|
||||||
@@ -4562,6 +4644,10 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
|
|||||||
mainvar = static_cast<Main *>((*fd)->mainlist->first);
|
mainvar = static_cast<Main *>((*fd)->mainlist->first);
|
||||||
mainl = nullptr; /* blo_join_main free's mainl, can't use anymore */
|
mainl = nullptr; /* blo_join_main free's mainl, can't use anymore */
|
||||||
|
|
||||||
|
if (mainvar->is_read_invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lib_link_all(*fd, mainvar);
|
lib_link_all(*fd, mainvar);
|
||||||
after_liblink_merged_bmain_process(mainvar);
|
after_liblink_merged_bmain_process(mainvar);
|
||||||
|
|
||||||
@@ -4582,9 +4668,13 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
|
|||||||
* or they will go again through do_versions - bad, very bad! */
|
* or they will go again through do_versions - bad, very bad! */
|
||||||
split_main_newid(mainvar, main_newid);
|
split_main_newid(mainvar, main_newid);
|
||||||
|
|
||||||
do_versions_after_linking(main_newid, (*fd)->reports->reports);
|
do_versions_after_linking(*fd, main_newid);
|
||||||
|
|
||||||
add_main_to_main(mainvar, main_newid);
|
add_main_to_main(mainvar, main_newid);
|
||||||
|
|
||||||
|
if (mainvar->is_read_invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blo_join_main((*fd)->mainlist);
|
blo_join_main((*fd)->mainlist);
|
||||||
@@ -4631,9 +4721,12 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
|
|||||||
|
|
||||||
void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params)
|
void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params)
|
||||||
{
|
{
|
||||||
FileData *fd = (FileData *)(*bh);
|
FileData *fd = reinterpret_cast<FileData *>(*bh);
|
||||||
library_link_end(mainl, &fd, params->flag);
|
|
||||||
*bh = (BlendHandle *)fd;
|
if (!mainl->is_read_invalid) {
|
||||||
|
library_link_end(mainl, &fd, params->flag);
|
||||||
|
*bh = reinterpret_cast<BlendHandle *>(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
|
void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
|
||||||
|
@@ -219,9 +219,9 @@ void blo_do_versions_cycles(struct FileData *fd, struct Library *lib, struct Mai
|
|||||||
void do_versions_after_linking_250(struct Main *bmain);
|
void do_versions_after_linking_250(struct Main *bmain);
|
||||||
void do_versions_after_linking_260(struct Main *bmain);
|
void do_versions_after_linking_260(struct Main *bmain);
|
||||||
void do_versions_after_linking_270(struct Main *bmain);
|
void do_versions_after_linking_270(struct Main *bmain);
|
||||||
void do_versions_after_linking_280(struct Main *bmain, struct ReportList *reports);
|
void do_versions_after_linking_280(struct FileData *fd, struct Main *bmain);
|
||||||
void do_versions_after_linking_290(struct Main *bmain, struct ReportList *reports);
|
void do_versions_after_linking_290(struct FileData *fd, struct Main *bmain);
|
||||||
void do_versions_after_linking_300(struct Main *bmain, struct ReportList *reports);
|
void do_versions_after_linking_300(struct FileData *fd, struct Main *bmain);
|
||||||
void do_versions_after_linking_cycles(struct Main *bmain);
|
void do_versions_after_linking_cycles(struct Main *bmain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,6 +232,10 @@ void do_versions_after_linking_cycles(struct Main *bmain);
|
|||||||
*/
|
*/
|
||||||
void *blo_read_get_new_globaldata_address(struct FileData *fd, const void *adr);
|
void *blo_read_get_new_globaldata_address(struct FileData *fd, const void *adr);
|
||||||
|
|
||||||
|
/* Mark the Main data as invalid (.blend file reading should be aborted ASAP, and the already read
|
||||||
|
* data should be discarded). Also add an error report to `fd` including given `message`. */
|
||||||
|
void blo_readfile_invalidate(struct FileData *fd, struct Main *bmain, const char *message);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1171,7 +1171,7 @@ static void do_version_fcurve_hide_viewport_fix(struct ID *UNUSED(id),
|
|||||||
fcu->rna_path = BLI_strdupn("hide_viewport", 13);
|
fcu->rna_path = BLI_strdupn("hide_viewport", 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
|
void do_versions_after_linking_280(FileData *UNUSED(fd), Main *bmain)
|
||||||
{
|
{
|
||||||
bool use_collection_compat_28 = true;
|
bool use_collection_compat_28 = true;
|
||||||
|
|
||||||
|
@@ -410,7 +410,7 @@ static void version_node_socket_duplicate(bNodeTree *ntree,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_versions_after_linking_290(Main *bmain, ReportList * /*reports*/)
|
void do_versions_after_linking_290(FileData * /*fd*/, Main *bmain)
|
||||||
{
|
{
|
||||||
if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) {
|
if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) {
|
||||||
/* Patch old grease pencil modifiers material filter. */
|
/* Patch old grease pencil modifiers material filter. */
|
||||||
|
@@ -939,7 +939,7 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/)
|
void do_versions_after_linking_300(FileData * /*fd*/, Main *bmain)
|
||||||
{
|
{
|
||||||
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
|
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
|
||||||
/* Set zero user text objects to have a fake user. */
|
/* Set zero user text objects to have a fake user. */
|
||||||
|
Reference in New Issue
Block a user