Anim: add functions for asserting Project Baklava phase-1 invariants
This is implemented as an overloaded function, `assert_baklava_phase_1_invariants()`, with variants for `Action`, `Layer`, and `Strip`. The invariants asserted are those that are specific to phase 1 and which will later be lifted as more features (such as animation layers, additional strip types, etc.) are added. The intention is for this to serve as a kind of todo marker for later phases *and* to help ensure that the phase-1 invariants currently hold at runtime. In addition to adding the overloaded function itself, this commit also uses it in a couple of places in the keyframing code. Upcoming work on the keyframing code will be using it more. This is based on a discussion with @dr.sybren. Pull Request: https://projects.blender.org/blender/blender/pulls/123830
This commit is contained in:
committed by
Nathan Vegdahl
parent
cae1faec12
commit
c83727f0bd
@@ -672,6 +672,37 @@ FCurve *action_fcurve_ensure(Main *bmain,
|
||||
*/
|
||||
FCurve *action_fcurve_find(bAction *act, FCurveDescriptor fcurve_descriptor);
|
||||
|
||||
/**
|
||||
* Assert the invariants of Project Baklava phase 1.
|
||||
*
|
||||
* For an action the invariants are that it:
|
||||
* - Is a legacy action.
|
||||
* - OR has zero layers.
|
||||
* - OR has a single layer that adheres to the phase 1 invariants for layers.
|
||||
*
|
||||
* For a layer the invariants are that it:
|
||||
* - Has zero strips.
|
||||
* - OR has a single strip that adheres to the phase 1 invariants for strips.
|
||||
*
|
||||
* For a strip the invariants are that it:
|
||||
* - Is a keyframe strip.
|
||||
* - AND is infinite.
|
||||
* - AND has no time offset (i.e. aligns with scene time).
|
||||
*
|
||||
* This simultaneously serves as a todo marker for later phases of Project
|
||||
* Baklava and ensures that the phase-1 invariants hold at runtime.
|
||||
*
|
||||
* TODO: these functions should be changed to assert fewer and fewer assumptions
|
||||
* as we progress through the phases of Project Baklava and more and more of the
|
||||
* new animation system is implemented. Finally, they should be removed entirely
|
||||
* when the full system is completely implemented.
|
||||
*/
|
||||
void assert_baklava_phase_1_invariants(const Action &action);
|
||||
/** \copydoc assert_baklava_phase_1_invariants(const Action &) */
|
||||
void assert_baklava_phase_1_invariants(const Layer &layer);
|
||||
/** \copydoc assert_baklava_phase_1_invariants(const Action &) */
|
||||
void assert_baklava_phase_1_invariants(const Strip &strip);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
/* Wrap functions for the DNA structs. */
|
||||
|
||||
@@ -434,15 +434,11 @@ bool Action::is_binding_animated(const binding_handle_t binding_handle) const
|
||||
|
||||
Layer *Action::get_layer_for_keyframing()
|
||||
{
|
||||
/* TODO: handle multiple layers. */
|
||||
assert_baklava_phase_1_invariants(*this);
|
||||
|
||||
if (this->layers().is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (this->layers().size() > 1) {
|
||||
std::fprintf(stderr,
|
||||
"Action '%s' has multiple layers, which isn't handled by keyframing code yet.",
|
||||
this->id.name);
|
||||
}
|
||||
|
||||
return this->layer(0);
|
||||
}
|
||||
@@ -1238,4 +1234,35 @@ FCurve *action_fcurve_ensure(Main *bmain,
|
||||
|
||||
return fcu;
|
||||
}
|
||||
|
||||
void assert_baklava_phase_1_invariants(const Action &action)
|
||||
{
|
||||
if (action.is_action_legacy()) {
|
||||
return;
|
||||
}
|
||||
if (action.layers().is_empty()) {
|
||||
return;
|
||||
}
|
||||
BLI_assert(action.layers().size() == 1);
|
||||
|
||||
assert_baklava_phase_1_invariants(*action.layer(0));
|
||||
}
|
||||
|
||||
void assert_baklava_phase_1_invariants(const Layer &layer)
|
||||
{
|
||||
if (layer.strips().is_empty()) {
|
||||
return;
|
||||
}
|
||||
BLI_assert(layer.strips().size() == 1);
|
||||
|
||||
assert_baklava_phase_1_invariants(*layer.strip(0));
|
||||
}
|
||||
|
||||
void assert_baklava_phase_1_invariants(const Strip &strip)
|
||||
{
|
||||
BLI_assert(strip.type() == Strip::Type::Keyframe);
|
||||
BLI_assert(strip.is_infinite());
|
||||
BLI_assert(strip.frame_offset == 0.0);
|
||||
}
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
@@ -862,14 +862,10 @@ static SingleKeyingResult insert_key_layer(Layer &layer,
|
||||
const KeyframeSettings &key_settings,
|
||||
const eInsertKeyFlags insert_key_flags)
|
||||
{
|
||||
/* TODO: we currently assume there will always be precisely one strip, which
|
||||
* is infinite and has no time offset. This will not hold true in the future
|
||||
* when we add support for multiple strips. */
|
||||
assert_baklava_phase_1_invariants(layer);
|
||||
BLI_assert(layer.strips().size() == 1);
|
||||
Strip *strip = layer.strip(0);
|
||||
BLI_assert(strip->is_infinite());
|
||||
BLI_assert(strip->frame_offset == 0.0);
|
||||
|
||||
Strip *strip = layer.strip(0);
|
||||
return strip->as<KeyframeStrip>().keyframe_insert(binding,
|
||||
{rna_path, key_data.array_index, prop_subtype},
|
||||
key_data.position,
|
||||
|
||||
Reference in New Issue
Block a user