Anim: rename action_slot_name to last_slot_identifier

`AnimData`, NLA strips, and action constraints all have an `action_slot_name`
field in RNA. The purpose of this field is to store the identifier of the most
recently assigned slot, so that it can be used for auto-assignment when later
assigning different actions.

However, this field name is misleading in two ways:

1. In accordance with #130740, it's actually the slot *identifier*, not name.
2. It could be mistaken as a way to rename the currently assigned slot, which it
   is not.

To resolve both of those issues, we're renaming the field to
`last_slot_identifier`, which better communicates its actual nature.

As a bonus, this also ends up decluttering Python autocomplete when looking
for things related to action_slot.

Ref: #130892
Pull Request: https://projects.blender.org/blender/blender/pulls/130911
This commit is contained in:
Nathan Vegdahl
2024-11-26 16:05:40 +01:00
committed by Nathan Vegdahl
parent cbc185dbbd
commit 409697a962
17 changed files with 95 additions and 77 deletions

View File

@@ -171,7 +171,7 @@ class Action : public ::bAction {
void slot_identifier_define(Slot &slot, StringRefNull new_identifier);
/**
* Update the `AnimData::action_slot_name` field of any ID that is animated by
* Update the `AnimData::last_slot_identifier` field of any ID that is animated by
* this Slot.
*
* Should be called after `slot_identifier_define(slot)`. This is implemented as a separate
@@ -245,7 +245,7 @@ class Action : public ::bAction {
* Action's slots with (in order):
*
* - `animated_id.adt->slot_handle`,
* - `animated_id.adt->slot_name`,
* - `animated_id.adt->last_slot_identifier`,
* - `animated_id.name`.
*
* Note that this is different from #slot_for_id, which does not use the
@@ -626,8 +626,8 @@ class Slot : public ::ActionSlot {
constexpr static int identifier_length_min = 3;
constexpr static int identifier_length_max = MAX_ID_NAME;
static_assert(sizeof(AnimData::slot_name) == identifier_length_max);
static_assert(sizeof(NlaStrip::action_slot_name) == identifier_length_max);
static_assert(sizeof(AnimData::last_slot_identifier) == identifier_length_max);
static_assert(sizeof(NlaStrip::last_slot_identifier) == identifier_length_max);
/**
* Return the identifier prefix for the Slot's type.

View File

@@ -443,7 +443,7 @@ void Action::slot_identifier_propagate(Main &bmain, const Slot &slot)
}
/* Ensure the Slot identifier on the AnimData is correct. */
STRNCPY_UTF8(adt->slot_name, slot.identifier);
STRNCPY_UTF8(adt->last_slot_identifier, slot.identifier);
}
FOREACH_MAIN_LISTBASE_ID_END;
}
@@ -574,8 +574,8 @@ Slot *Action::find_suitable_slot_for(const ID &animated_id)
}
/* Try the slot identifier from the AnimData, if it is set. */
if (adt && adt->slot_name[0]) {
Slot *slot = this->slot_find_by_identifier(adt->slot_name);
if (adt && adt->last_slot_identifier[0]) {
Slot *slot = this->slot_find_by_identifier(adt->last_slot_identifier);
if (slot && slot->is_suitable_for(animated_id)) {
return slot;
}
@@ -1186,7 +1186,7 @@ bool assign_action(bAction *action, const OwnedAnimData owned_adt)
action,
owned_adt.adt.action,
owned_adt.adt.slot_handle,
owned_adt.adt.slot_name);
owned_adt.adt.last_slot_identifier);
}
bool assign_tmpaction(bAction *action, const OwnedAnimData owned_adt)
@@ -1195,7 +1195,7 @@ bool assign_tmpaction(bAction *action, const OwnedAnimData owned_adt)
action,
owned_adt.adt.tmpact,
owned_adt.adt.tmp_slot_handle,
owned_adt.adt.tmp_slot_name);
owned_adt.adt.tmp_last_slot_identifier);
}
bool unassign_action(ID &animated_id)
@@ -1226,8 +1226,8 @@ Slot *assign_action_ensure_slot_for_keying(Action &action, ID &animated_id)
}
else {
/* Try the slot identifier from the AnimData, if it is set. */
if (adt && adt->slot_name[0]) {
slot = action.slot_find_by_identifier(adt->slot_name);
if (adt && adt->last_slot_identifier[0]) {
slot = action.slot_find_by_identifier(adt->last_slot_identifier);
}
else {
/* Search for the ID name (which includes the ID type). */
@@ -1456,7 +1456,7 @@ ActionSlotAssignmentResult assign_action_slot(Slot *slot_to_assign, ID &animated
}
return generic_assign_action_slot(
slot_to_assign, animated_id, adt->action, adt->slot_handle, adt->slot_name);
slot_to_assign, animated_id, adt->action, adt->slot_handle, adt->last_slot_identifier);
}
ActionSlotAssignmentResult assign_action_and_slot(Action *action,
@@ -1480,7 +1480,7 @@ ActionSlotAssignmentResult assign_tmpaction_and_slot_handle(bAction *action,
owned_adt.owner_id,
owned_adt.adt.tmpact,
owned_adt.adt.tmp_slot_handle,
owned_adt.adt.tmp_slot_name);
owned_adt.adt.tmp_last_slot_identifier);
}
Action *get_action(ID &animated_id)

View File

@@ -100,7 +100,7 @@ bool foreach_action_slot_use_with_references(ID &animated_id,
if (adt) {
if (adt->action) {
/* Direct assignment. */
if (!callback(animated_id, adt->action, adt->slot_handle, adt->slot_name)) {
if (!callback(animated_id, adt->action, adt->slot_handle, adt->last_slot_identifier)) {
return false;
}
}
@@ -108,7 +108,8 @@ bool foreach_action_slot_use_with_references(ID &animated_id,
/* NLA strips. */
const bool looped_until_last_strip = bke::nla::foreach_strip_adt(*adt, [&](NlaStrip *strip) {
if (strip->act) {
if (!callback(animated_id, strip->act, strip->action_slot_handle, strip->action_slot_name))
if (!callback(
animated_id, strip->act, strip->action_slot_handle, strip->last_slot_identifier))
{
return false;
}
@@ -144,7 +145,7 @@ bool foreach_action_slot_use_with_references(ID &animated_id,
return callback(animated_id,
constraint_data->act,
constraint_data->action_slot_handle,
constraint_data->action_slot_name);
constraint_data->last_slot_identifier);
};
/* Visit Object constraints. */

View File

@@ -430,7 +430,7 @@ TEST_F(ActionLayersTest, action_assign_id)
EXPECT_EQ(slot_cube.handle, cube->adt->slot_handle);
EXPECT_STREQ(slot_cube.identifier, "OBSlot");
EXPECT_STREQ(slot_cube.identifier, cube->adt->slot_name)
EXPECT_STREQ(slot_cube.identifier, cube->adt->last_slot_identifier)
<< "The slot identifier should be copied to the adt";
EXPECT_TRUE(slot_cube.users(*bmain).contains(&cube->id))
@@ -440,7 +440,7 @@ TEST_F(ActionLayersTest, action_assign_id)
ASSERT_EQ(assign_action_and_slot(action, &slot_cube, suzanne->id),
ActionSlotAssignmentResult::OK);
EXPECT_STREQ(slot_cube.identifier, "OBSlot");
EXPECT_STREQ(slot_cube.identifier, cube->adt->slot_name)
EXPECT_STREQ(slot_cube.identifier, cube->adt->last_slot_identifier)
<< "The slot identifier should be copied to the adt";
EXPECT_TRUE(slot_cube.users(*bmain).contains(&cube->id))
@@ -493,7 +493,8 @@ TEST_F(ActionLayersTest, action_assign_id)
ActionSlotAssignmentResult::OK);
EXPECT_EQ(another_slot_cube.handle, cube->adt->slot_handle);
EXPECT_STREQ("OBSlot.002", another_slot_cube.identifier) << "The slot should be uniquely named";
EXPECT_STREQ("OBSlot.002", cube->adt->slot_name) << "The slot name should be copied to the adt";
EXPECT_STREQ("OBSlot.002", cube->adt->last_slot_identifier)
<< "The slot identifier should be copied to the adt";
EXPECT_TRUE(another_slot_cube.users(*bmain).contains(&cube->id))
<< "Expecting Cube to be registered as animated by the 'another_slot_cube' slot.";
@@ -513,7 +514,7 @@ TEST_F(ActionLayersTest, rename_slot)
ASSERT_EQ(assign_action_and_slot(action, &slot_cube, cube->id), ActionSlotAssignmentResult::OK);
EXPECT_EQ(slot_cube.handle, cube->adt->slot_handle);
EXPECT_STREQ("OBSlot", slot_cube.identifier);
EXPECT_STREQ(slot_cube.identifier, cube->adt->slot_name)
EXPECT_STREQ(slot_cube.identifier, cube->adt->last_slot_identifier)
<< "The slot identifier should be copied to the adt";
action->slot_identifier_define(slot_cube, "New Slot Name");
@@ -524,14 +525,14 @@ TEST_F(ActionLayersTest, rename_slot)
* implementation. */
action->slot_identifier_propagate(*bmain, slot_cube);
EXPECT_STREQ("New Slot Name", cube->adt->slot_name);
EXPECT_STREQ("New Slot Name", cube->adt->last_slot_identifier);
/* Finally, do another rename, do NOT call the propagate function, then
* unassign. This should still result in the correct slot name being stored
* on the ADT. */
action->slot_identifier_define(slot_cube, "Even Newer Name");
EXPECT_TRUE(unassign_action(cube->id));
EXPECT_STREQ("Even Newer Name", cube->adt->slot_name);
EXPECT_STREQ("Even Newer Name", cube->adt->last_slot_identifier);
}
TEST_F(ActionLayersTest, slot_identifier_ensure_prefix)
@@ -619,7 +620,7 @@ TEST_F(ActionLayersTest, find_suitable_slot)
adt->action = nullptr;
/* Configure adt to use the handle of one slot, and the identifier of the other. */
adt->slot_handle = other_slot.handle;
STRNCPY_UTF8(adt->slot_name, slot.identifier);
STRNCPY_UTF8(adt->last_slot_identifier, slot.identifier);
EXPECT_EQ(&slot, action->find_suitable_slot_for(cube->id));
/* ===
@@ -634,7 +635,7 @@ TEST_F(ActionLayersTest, find_suitable_slot)
* A slot exists, but doesn't match anything in the action data of the cube. This should fall
* back to using the ID name. */
adt->slot_handle = 161;
STRNCPY_UTF8(adt->slot_name, "¿¿What's this??");
STRNCPY_UTF8(adt->last_slot_identifier, "¿¿What's this??");
EXPECT_EQ(&slot, action->find_suitable_slot_for(cube->id));
}

View File

@@ -206,7 +206,7 @@ TEST_F(KeyframingTest, insert_keyframes__layered_action__non_array_property)
ASSERT_EQ(1, action.slots().size());
Slot *slot = action.slot(0);
EXPECT_STREQ(object->id.name, slot->identifier);
EXPECT_STREQ(object->adt->slot_name, slot->identifier);
EXPECT_STREQ(object->adt->last_slot_identifier, slot->identifier);
EXPECT_EQ(object->adt->slot_handle, slot->handle);
/* We have the default layer and strip. */
@@ -616,7 +616,7 @@ TEST_F(KeyframingTest, insert_keyframes__layered_action__multiple_ids)
Slot *slot_1 = action.slot_for_handle(object->adt->slot_handle);
ASSERT_NE(nullptr, slot_1);
EXPECT_STREQ(object->id.name, slot_1->identifier);
EXPECT_STREQ(object->adt->slot_name, slot_1->identifier);
EXPECT_STREQ(object->adt->last_slot_identifier, slot_1->identifier);
/* Get the keyframe strip. */
ASSERT_TRUE(action.is_action_layered());
@@ -649,7 +649,7 @@ TEST_F(KeyframingTest, insert_keyframes__layered_action__multiple_ids)
Slot *slot_2 = action.slot_for_handle(armature_object->adt->slot_handle);
ASSERT_NE(nullptr, slot_2);
EXPECT_STREQ(armature_object->id.name, slot_2->identifier);
EXPECT_STREQ(armature_object->adt->slot_name, slot_2->identifier);
EXPECT_STREQ(armature_object->adt->last_slot_identifier, slot_2->identifier);
ASSERT_EQ(2, strip_data->channelbags().size());
ChannelBag *channel_bag_2 = strip_data->channelbag_for_slot(*slot_2);

View File

@@ -19,7 +19,7 @@ namespace blender::animrig::nla {
bool assign_action(NlaStrip &strip, Action &action, ID &animated_id)
{
if (!generic_assign_action(
animated_id, &action, strip.act, strip.action_slot_handle, strip.action_slot_name))
animated_id, &action, strip.act, strip.action_slot_handle, strip.last_slot_identifier))
{
return false;
}
@@ -56,7 +56,7 @@ bool assign_action(NlaStrip &strip, Action &action, ID &animated_id)
void unassign_action(NlaStrip &strip, ID &animated_id)
{
const bool ok = generic_assign_action(
animated_id, nullptr, strip.act, strip.action_slot_handle, strip.action_slot_name);
animated_id, nullptr, strip.act, strip.action_slot_handle, strip.last_slot_identifier);
BLI_assert_msg(ok, "Un-assigning an Action from an NLA strip should always work.");
UNUSED_VARS_NDEBUG(ok);
}
@@ -67,8 +67,11 @@ ActionSlotAssignmentResult assign_action_slot(NlaStrip &strip,
{
BLI_assert(strip.act);
return generic_assign_action_slot(
slot_to_assign, animated_id, strip.act, strip.action_slot_handle, strip.action_slot_name);
return generic_assign_action_slot(slot_to_assign,
animated_id,
strip.act,
strip.action_slot_handle,
strip.last_slot_identifier);
}
ActionSlotAssignmentResult assign_action_slot_handle(NlaStrip &strip,

View File

@@ -74,7 +74,7 @@ TEST_F(NLASlottedActionTest, assign_slot_to_nla_strip)
BKE_nlatrack_add_strip(track, strip, false);
EXPECT_EQ(strip->action_slot_handle, Slot::unassigned);
EXPECT_STREQ(strip->action_slot_name, "");
EXPECT_STREQ(strip->last_slot_identifier, "");
/* Unassign the Action that was automatically assigned via BKE_nlastrip_new(). */
nla::unassign_action(*strip, cube->id);
@@ -87,7 +87,7 @@ TEST_F(NLASlottedActionTest, assign_slot_to_nla_strip)
/* Assign the Action. */
EXPECT_TRUE(nla::assign_action(*strip, *action, cube->id));
EXPECT_EQ(strip->action_slot_handle, virgin_slot.handle);
EXPECT_STREQ(strip->action_slot_name, virgin_slot.identifier);
EXPECT_STREQ(strip->last_slot_identifier, virgin_slot.identifier);
EXPECT_EQ(action->id.us, 1);
EXPECT_EQ(strip->act, action);
EXPECT_EQ(virgin_slot.idtype, GS(cube->id.name));
@@ -101,7 +101,7 @@ TEST_F(NLASlottedActionTest, assign_slot_to_nla_strip)
Slot &slot = action->slot_add_for_id(cube->id);
EXPECT_TRUE(nla::assign_action(*strip, *action, cube->id));
EXPECT_EQ(strip->action_slot_handle, slot.handle);
EXPECT_STREQ(strip->action_slot_name, slot.identifier);
EXPECT_STREQ(strip->last_slot_identifier, slot.identifier);
EXPECT_EQ(action->id.us, 1);
EXPECT_EQ(strip->act, action);
EXPECT_TRUE(slot.runtime_users().contains(&cube->id));
@@ -109,7 +109,7 @@ TEST_F(NLASlottedActionTest, assign_slot_to_nla_strip)
/* Unassign the slot, but keep the Action assigned. */
EXPECT_EQ(nla::assign_action_slot(*strip, nullptr, cube->id), ActionSlotAssignmentResult::OK);
EXPECT_EQ(strip->action_slot_handle, Slot::unassigned);
EXPECT_STREQ(strip->action_slot_name, slot.identifier);
EXPECT_STREQ(strip->last_slot_identifier, slot.identifier);
EXPECT_EQ(action->id.us, 1);
EXPECT_EQ(strip->act, action);
EXPECT_FALSE(slot.runtime_users().contains(&cube->id));
@@ -146,7 +146,7 @@ TEST_F(NLASlottedActionTest, assign_slot_to_multiple_strips)
Slot &slot = action->slot_add();
EXPECT_TRUE(nla::assign_action(*strip1, *action, cube->id));
EXPECT_EQ(strip1->action_slot_handle, slot.handle);
EXPECT_STREQ(strip1->action_slot_name, slot.identifier);
EXPECT_STREQ(strip1->last_slot_identifier, slot.identifier);
EXPECT_EQ(slot.idtype, ID_OB);
/* Assign another slot slot 'manually'. */

View File

@@ -545,8 +545,8 @@ void BKE_animdata_merge_copy(
}
dst->slot_handle = src->slot_handle;
dst->tmp_slot_handle = src->tmp_slot_handle;
STRNCPY(dst->slot_name, src->slot_name);
STRNCPY(dst->tmp_slot_name, src->tmp_slot_name);
STRNCPY(dst->last_slot_identifier, src->last_slot_identifier);
STRNCPY(dst->tmp_last_slot_identifier, src->tmp_last_slot_identifier);
/* duplicate NLA data */
if (src->nla_tracks.first) {

View File

@@ -6696,4 +6696,4 @@ void BKE_constraint_blend_read_data(BlendDataReader *reader, ID *id_owner, ListB
static_assert(
std::is_same_v<decltype(ActionSlot::handle), decltype(bActionConstraint::action_slot_handle)>);
static_assert(std::is_same_v<decltype(ActionSlot::identifier),
decltype(bActionConstraint::action_slot_name)>);
decltype(bActionConstraint::last_slot_identifier)>);

View File

@@ -2469,7 +2469,7 @@ static void nla_tweakmode_exit_nofollowptr(AnimData *adt)
adt->tmpact = nullptr;
adt->tmp_slot_handle = animrig::Slot::unassigned;
STRNCPY(adt->slot_name, adt->tmp_slot_name);
STRNCPY(adt->last_slot_identifier, adt->tmp_last_slot_identifier);
adt->act_track = nullptr;
adt->actstrip = nullptr;
@@ -2502,7 +2502,7 @@ void BKE_nla_tweakmode_exit(const OwnedAnimData owned_adt)
nullptr,
owned_adt.adt.action,
owned_adt.adt.slot_handle,
owned_adt.adt.slot_name);
owned_adt.adt.last_slot_identifier);
BLI_assert_msg(unassign_ok,
"When exiting tweak mode, unassigning the tweaked Action should work");
UNUSED_VARS_NDEBUG(unassign_ok);

View File

@@ -762,7 +762,7 @@ typedef struct NlaStrip {
* \note Most code should not write to this field directly, but use functions from
* `blender::animrig::nla` instead, see ANIM_nla.hh.
*/
char action_slot_name[66]; /* MAX_ID_NAME */
char last_slot_identifier[66]; /* MAX_ID_NAME */
char _pad0[2];
/** F-Curves for controlling this strip's influence and timing */ /* TODO: move out? */
@@ -1164,7 +1164,7 @@ typedef struct AnimData {
*
* \see #ActionSlot::name
*/
char slot_name[66]; /* MAX_ID_NAME */
char last_slot_identifier[66]; /* MAX_ID_NAME */
uint8_t _pad0[2];
/**
@@ -1173,7 +1173,7 @@ typedef struct AnimData {
*/
bAction *tmpact;
int32_t tmp_slot_handle;
char tmp_slot_name[66]; /* MAX_ID_NAME */
char tmp_last_slot_identifier[66]; /* MAX_ID_NAME */
uint8_t _pad1[2];
/* nla-tracks */
@@ -1219,7 +1219,8 @@ typedef struct AnimData {
#ifdef __cplusplus
/* Some static assertions that things that should have the same type actually do. */
static_assert(std::is_same_v<decltype(ActionSlot::handle), decltype(AnimData::slot_handle)>);
static_assert(std::is_same_v<decltype(ActionSlot::identifier), decltype(AnimData::slot_name)>);
static_assert(
std::is_same_v<decltype(ActionSlot::identifier), decltype(AnimData::last_slot_identifier)>);
#endif
/* Animation Data settings (mostly for NLA) */

View File

@@ -336,7 +336,7 @@ typedef struct bActionConstraint {
float eval_time; /* Only used when flag ACTCON_USE_EVAL_TIME is set. */
struct bAction *act;
int32_t action_slot_handle;
char action_slot_name[66]; /* MAX_ID_NAME */
char last_slot_identifier[66]; /* MAX_ID_NAME */
char _pad1[2];
/** MAX_ID_NAME-2. */
char subtarget[64];

View File

@@ -48,6 +48,9 @@ DNA_STRUCT_RENAME(SpaceButs, SpaceProperties)
DNA_STRUCT_RENAME(SpaceIpo, SpaceGraph)
DNA_STRUCT_RENAME(SpaceOops, SpaceOutliner)
DNA_STRUCT_RENAME_MEMBER(ActionSlot, name, identifier)
DNA_STRUCT_RENAME_MEMBER(AnimData, slot_name, last_slot_identifier)
DNA_STRUCT_RENAME_MEMBER(AnimData, tmp_slot_name, tmp_last_slot_identifier)
DNA_STRUCT_RENAME_MEMBER(bActionConstraint, action_slot_name, last_slot_identifier)
DNA_STRUCT_RENAME_MEMBER(BPoint, alfa, tilt)
DNA_STRUCT_RENAME_MEMBER(BezTriple, alfa, tilt)
DNA_STRUCT_RENAME_MEMBER(Bone, curveInX, curve_in_x)
@@ -156,6 +159,7 @@ DNA_STRUCT_RENAME_MEMBER(MovieTrackingTrack, pat_max, pat_max_legacy)
DNA_STRUCT_RENAME_MEMBER(MovieTrackingTrack, pat_min, pat_min_legacy)
DNA_STRUCT_RENAME_MEMBER(MovieTrackingTrack, search_max, search_max_legacy)
DNA_STRUCT_RENAME_MEMBER(MovieTrackingTrack, search_min, search_min_legacy)
DNA_STRUCT_RENAME_MEMBER(NlaStrip, action_slot_name, last_slot_identifier)
DNA_STRUCT_RENAME_MEMBER(NodeCryptomatte, num_inputs, inputs_num)
DNA_STRUCT_RENAME_MEMBER(NodeGeometryAttributeCapture, data_type, data_type_legacy)
DNA_STRUCT_RENAME_MEMBER(NodesModifierData, simulation_bake_directory, bake_directory)

View File

@@ -264,7 +264,7 @@ static void rna_AnimData_action_slot_handle_set(
AnimData *adt = BKE_animdata_from_id(&animated_id);
rna_generic_action_slot_handle_set(
new_slot_handle, animated_id, adt->action, adt->slot_handle, adt->slot_name);
new_slot_handle, animated_id, adt->action, adt->slot_handle, adt->last_slot_identifier);
}
static AnimData &rna_animdata(const PointerRNA *ptr)
@@ -343,7 +343,7 @@ static void rna_AnimData_action_slot_set(PointerRNA *ptr, PointerRNA value, Repo
}
rna_generic_action_slot_set(
value, *animated_id, adt->action, adt->slot_handle, adt->slot_name, reports);
value, *animated_id, adt->action, adt->slot_handle, adt->last_slot_identifier, reports);
}
static void rna_AnimData_action_slot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -997,8 +997,8 @@ bool rna_AnimaData_override_apply(Main *bmain, RNAPropertyOverrideApplyContext &
adt_dst->slot_handle = adt_src->slot_handle;
adt_dst->tmp_slot_handle = adt_src->tmp_slot_handle;
STRNCPY(adt_dst->slot_name, adt_src->slot_name);
STRNCPY(adt_dst->tmp_slot_name, adt_src->tmp_slot_name);
STRNCPY(adt_dst->last_slot_identifier, adt_src->last_slot_identifier);
STRNCPY(adt_dst->tmp_last_slot_identifier, adt_src->tmp_last_slot_identifier);
adt_dst->tmpact = adt_src->tmpact;
id_us_plus(reinterpret_cast<ID *>(adt_dst->tmpact));
adt_dst->act_blendmode = adt_src->act_blendmode;
@@ -1693,14 +1693,14 @@ static void rna_def_animdata(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
prop = RNA_def_property(srna, "action_slot_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "slot_name");
prop = RNA_def_property(srna, "last_slot_identifier", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "last_slot_identifier");
RNA_def_property_ui_text(
prop,
"Action Slot Name",
"The name of the action slot. The slot identifies which sub-set of the Action "
"is considered to be for this data-block, and its name is used to find the right slot "
"when assigning an Action.");
"Last Action Slot Identifier",
"The identifier of the most recently assigned action slot. The slot identifies which "
"sub-set of the Action is considered to be for this data-block, and its identifier is used "
"to find the right slot when assigning an Action.");
prop = RNA_def_property(srna, "action_slot", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ActionSlot");

View File

@@ -724,14 +724,14 @@ static void rna_ActionConstraint_action_set(PointerRNA *ptr, PointerRNA value, R
if (!action) {
const bool ok = generic_assign_action(
animated_id, nullptr, acon->act, acon->action_slot_handle, acon->action_slot_name);
animated_id, nullptr, acon->act, acon->action_slot_handle, acon->last_slot_identifier);
BLI_assert_msg(ok, "Un-assigning an Action from an Action Constraint should always work.");
UNUSED_VARS_NDEBUG(ok);
return;
}
const bool ok = generic_assign_action(
animated_id, action, acon->act, acon->action_slot_handle, acon->action_slot_name);
animated_id, action, acon->act, acon->action_slot_handle, acon->last_slot_identifier);
if (!ok) {
BKE_reportf(reports,
RPT_ERROR,
@@ -764,7 +764,11 @@ static void rna_ActionConstraint_action_set(PointerRNA *ptr, PointerRNA value, R
Slot *first_slot = action->slot(0);
if (first_slot->is_suitable_for(animated_id)) {
const ActionSlotAssignmentResult result = generic_assign_action_slot(
first_slot, animated_id, acon->act, acon->action_slot_handle, acon->action_slot_name);
first_slot,
animated_id,
acon->act,
acon->action_slot_handle,
acon->last_slot_identifier);
BLI_assert(result == ActionSlotAssignmentResult::OK);
UNUSED_VARS_NDEBUG(result);
}
@@ -781,7 +785,7 @@ static void rna_ActionConstraint_action_slot_handle_set(
*ptr->owner_id,
acon->act,
acon->action_slot_handle,
acon->action_slot_name);
acon->last_slot_identifier);
}
static PointerRNA rna_ActionConstraint_action_slot_get(PointerRNA *ptr)
@@ -799,8 +803,12 @@ static void rna_ActionConstraint_action_slot_set(PointerRNA *ptr,
bConstraint *con = (bConstraint *)ptr->data;
bActionConstraint *acon = (bActionConstraint *)con->data;
rna_generic_action_slot_set(
value, *ptr->owner_id, acon->act, acon->action_slot_handle, acon->action_slot_name, reports);
rna_generic_action_slot_set(value,
*ptr->owner_id,
acon->act,
acon->action_slot_handle,
acon->last_slot_identifier,
reports);
}
static void rna_iterator_ActionConstraint_action_suitable_slots_begin(
@@ -1979,14 +1987,14 @@ static void rna_def_constraint_action(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_Constraint_update");
prop = RNA_def_property(srna, "action_slot_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "action_slot_name");
prop = RNA_def_property(srna, "last_slot_identifier", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "last_slot_identifier");
RNA_def_property_ui_text(
prop,
"Action Slot Name",
"The name of the action slot. The slot identifies which sub-set of the Action "
"is considered to be for this constraint, and its name is used to find the right slot "
"when assigning an Action.");
"Last Action Slot Identifier",
"The identifier of the most recently assigned action slot. The slot identifies which "
"sub-set of the Action is considered to be for this constraint, and its identifier is used "
"to find the right slot when assigning an Action.");
prop = RNA_def_property(srna, "action_slot", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ActionSlot");

View File

@@ -490,7 +490,7 @@ static void rna_NlaStrip_action_slot_handle_set(
*ptr->owner_id,
strip->act,
strip->action_slot_handle,
strip->action_slot_name);
strip->last_slot_identifier);
}
static PointerRNA rna_NlaStrip_action_slot_get(PointerRNA *ptr)
@@ -506,7 +506,7 @@ static void rna_NlaStrip_action_slot_set(PointerRNA *ptr, PointerRNA value, Repo
*ptr->owner_id,
strip->act,
strip->action_slot_handle,
strip->action_slot_name,
strip->last_slot_identifier,
reports);
}
@@ -916,14 +916,14 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_NlaStrip_dependency_update");
prop = RNA_def_property(srna, "action_slot_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "action_slot_name");
prop = RNA_def_property(srna, "last_slot_identifier", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, nullptr, "last_slot_identifier");
RNA_def_property_ui_text(
prop,
"Action Slot Name",
"The name of the action slot. The slot identifies which sub-set of the Action "
"is considered to be for this strip, and its name is used to find the right slot "
"when assigning an Action.");
"Last Action Slot Identifier",
"The identifier of the most recently assigned action slot. The slot identifies which "
"sub-set of the Action is considered to be for this strip, and its identifier is used to "
"find the right slot when assigning an Action.");
prop = RNA_def_property(srna, "action_slot", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ActionSlot");

View File

@@ -66,7 +66,7 @@ class ActionSlotAssignmentTest(unittest.TestCase):
# Unassigning should keep the slot identifier.
cube_adt.action = None
self.assertEqual(cube_adt.action_slot_name, slot_cube.identifier)
self.assertEqual(cube_adt.last_slot_identifier, slot_cube.identifier)
# It should not be possible to set the slot handle while the Action is unassigned.
slot_extra = action.slots.new()