13
0

Evoral: extend ControlList API with ::editor_ordered_points()

Much more efficient than adding points 1 by 1
This commit is contained in:
Paul Davis 2023-07-10 11:20:17 -06:00
parent 76ba032d3c
commit 45b02538e6
2 changed files with 83 additions and 0 deletions

View File

@ -713,6 +713,80 @@ ControlList::editor_add (timepos_t const& time, double value, bool with_guard)
return true;
}
bool
ControlList::editor_add_ordered (OrderedPoints const & points, bool with_guard)
{
/* this is for making changes from a graphical line editor */
if (points.empty()) {
return false;
}
{
Glib::Threads::RWLock::WriterLock lm (_lock);
Temporal::timepos_t earliest = points.front().when;
Temporal::timepos_t latest = points.back().when;
if (earliest > latest) {
swap (earliest, latest);
}
(void) erase_range_internal (earliest, latest, _events);
/* Get the iterator where we should start insertion */
timepos_t when = ensure_time_domain (points.front().when);
ControlEvent xp (when, 0.0f);
iterator i = lower_bound (_events.begin (), _events.end (), &xp, time_comparator);
if (i != _events.end () && (*i)->when == when) {
return false;
}
for (auto const & p : points) {
when = ensure_time_domain (p.when);
/* clamp new value to allowed range */
double value = std::min ((double)_desc.upper, std::max ((double)_desc.lower, p.value));
if (_events.empty ()) {
/* as long as the point we're adding is not at zero,
* add an "anchor" point there.
*/
if (when >= 1) {
_events.insert (_events.end (), new ControlEvent (timepos_t (_time_domain), value));
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added value %2 at zero\n", this, value));
}
}
insert_position = when;
if (with_guard) {
add_guard_point (p.when, -GUARD_POINT_DELTA (when));
maybe_add_insert_guard (when);
ControlEvent cp (when, 0.0f);
i = lower_bound (_events.begin (), _events.end (), &cp, time_comparator);
}
iterator result;
DEBUG_TRACE (DEBUG::ControlList, string_compose ("editor_add: actually add when= %1 value= %2\n", when, value));
result = _events.insert (i, new ControlEvent (when, value));
if (i == result) {
/* insertion failed, but we don't really care */
}
}
mark_dirty ();
}
maybe_signal_changed ();
return true;
}
void
ControlList::maybe_add_insert_guard (timepos_t const& time)
{

View File

@ -171,6 +171,15 @@ public:
*/
virtual bool editor_add (Temporal::timepos_t const & when, double value, bool with_guard);
struct OrderedPoint {
Temporal::timepos_t when;
double value;
OrderedPoint (Temporal::timepos_t const & t, double v) : when (t), value (v) {}
};
typedef std::vector<OrderedPoint> OrderedPoints;
virtual bool editor_add_ordered (OrderedPoints const &, bool with_guard);
/* to be used only for loading pre-sorted data from saved state */
void fast_simple_add (Temporal::timepos_t const & when, double value);