Refactor/enhance BKE_action_make_local().

Now using modern features from libquery/libremap areas.

Provides same kind of fixes/improvements as for BKE_object_make_local() (see rBd1a4ae3f395a6).
This commit is contained in:
Bastien Montagne 2016-07-10 17:07:27 +02:00
parent 406309cd8c
commit 8df92988cf
4 changed files with 33 additions and 64 deletions

@ -63,8 +63,7 @@ struct bAction *BKE_action_copy(struct Main *bmain, struct bAction *src);
/* Deallocate all of the Action's data, but not the Action itself */
void BKE_action_free(struct bAction *act);
// XXX is this needed?
void BKE_action_make_local(struct bAction *act);
void BKE_action_make_local(struct Main *bmain, struct bAction *act);
/* Action API ----------------- */

@ -59,6 +59,8 @@
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
#include "BKE_main.h"
#include "BKE_object.h"
@ -92,68 +94,36 @@ bAction *add_empty_action(Main *bmain, const char name[])
/* .................................. */
/* temp data for BKE_action_make_local */
typedef struct tMakeLocalActionContext {
bAction *act; /* original action */
bAction *act_new; /* new action */
bool is_lib; /* some action users were libraries */
bool is_local; /* some action users were not libraries */
} tMakeLocalActionContext;
/* helper function for BKE_action_make_local() - local/lib init step */
static void make_localact_init_cb(ID *id, AnimData *adt, void *mlac_ptr)
{
tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
if (adt->action == mlac->act) {
if (ID_IS_LINKED_DATABLOCK(id)) mlac->is_lib = true;
else mlac->is_local = true;
}
}
/* helper function for BKE_action_make_local() - change references */
static void make_localact_apply_cb(ID *id, AnimData *adt, void *mlac_ptr)
{
tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
if (adt->action == mlac->act) {
if (!ID_IS_LINKED_DATABLOCK(id)) {
adt->action = mlac->act_new;
id_us_plus(&mlac->act_new->id);
id_us_min(&mlac->act->id);
}
}
}
// does copy_fcurve...
void BKE_action_make_local(bAction *act)
void BKE_action_make_local(Main *bmain, bAction *act)
{
tMakeLocalActionContext mlac = {act, NULL, false, false};
Main *bmain = G.main;
bool is_local = false, is_lib = false;
if (!ID_IS_LINKED_DATABLOCK(act))
return;
/* - only lib users: do nothing
* - only local users: set flag
* - mixed: make copy
*/
/* XXX: double-check this; it used to be just single-user check, but that was when fake-users were still default */
if ((act->id.flag & LIB_FAKEUSER) && (act->id.us <= 1)) {
id_clear_lib_data(bmain, &act->id);
if (!ID_IS_LINKED_DATABLOCK(act)) {
return;
}
BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac);
BKE_library_ID_test_usages(bmain, act, &is_local, &is_lib);
if (mlac.is_local && mlac.is_lib == false) {
if (is_local) {
if (!is_lib) {
id_clear_lib_data(bmain, &act->id);
}
else if (mlac.is_local && mlac.is_lib) {
mlac.act_new = BKE_action_copy(bmain, act);
mlac.act_new->id.us = 0;
else {
bAction *act_new = BKE_action_copy(bmain, act);
BKE_id_lib_local_paths(bmain, act->id.lib, &mlac.act_new->id);
act_new->id.us = 0;
BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac);
/* Remap paths of new ID using old library as base. */
BKE_id_lib_local_paths(bmain, act->id.lib, &act_new->id);
BKE_libblock_remap(bmain, act, act_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
}
}

@ -400,8 +400,8 @@ static void make_local_strips(ListBase *strips)
NlaStrip *strip;
for (strip = strips->first; strip; strip = strip->next) {
if (strip->act) BKE_action_make_local(strip->act);
if (strip->remap && strip->remap->target) BKE_action_make_local(strip->remap->target);
if (strip->act) BKE_action_make_local(G.main, strip->act);
if (strip->remap && strip->remap->target) BKE_action_make_local(G.main, strip->remap->target);
make_local_strips(&strip->strips);
}
@ -413,10 +413,10 @@ void BKE_animdata_make_local(AnimData *adt)
NlaTrack *nlt;
/* Actions - Active and Temp */
if (adt->action) BKE_action_make_local(adt->action);
if (adt->tmpact) BKE_action_make_local(adt->tmpact);
if (adt->action) BKE_action_make_local(G.main, adt->action);
if (adt->tmpact) BKE_action_make_local(G.main, adt->tmpact);
/* Remaps */
if (adt->remap && adt->remap->target) BKE_action_make_local(adt->remap->target);
if (adt->remap && adt->remap->target) BKE_action_make_local(G.main, adt->remap->target);
/* Drivers */
/* TODO: need to remap the ID-targets too? */

@ -318,7 +318,7 @@ bool id_make_local(Main *bmain, ID *id, bool test)
if (!test) BKE_armature_make_local(bmain, (bArmature *)id);
return true;
case ID_AC:
if (!test) BKE_action_make_local((bAction *)id);
if (!test) BKE_action_make_local(bmain, (bAction *)id);
return true;
case ID_NT:
if (!test) ntreeMakeLocal(bmain, (bNodeTree *)id, true);