Timeline: Reimplemented ::tracked

This commit is contained in:
Paul Beckingham 2016-04-27 22:25:58 -04:00
parent 2e6f2c44c2
commit 59036f7908

View file

@ -64,41 +64,47 @@ void Timeline::exclude (const Exclusion& exclusion)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector <Interval> Timeline::tracked (Rules& rules) const std::vector <Interval> Timeline::tracked (Rules& rules) const
{ {
// Create a range representing the whole timeline. // Get the set of expanded exclusions that overlap the range defined by the
// If no range is defined, then assume the full range of all the inclusions. // timeline. If no range is defined, derive it from the set of all data.
Range overallRange {range}; auto exclusions = excluded (rules);
if (! overallRange.started () &&
! overallRange.ended ())
overallRange = overallRangeFromIntervals (_inclusions);
// Cobmine all the non-trackable time. std::vector <Interval> all;
auto nonTrackable = combineHolidaysAndExclusions (overallRange, rules, _exclusions);
std::vector <Interval> combined;
for (auto& interval : _inclusions) for (auto& interval : _inclusions)
{ {
std::vector <Range> intervalFragments {interval.range}; // Closed intervals are returned as-is.
if (interval.range.ended ())
for (auto& exclusion : nonTrackable)
{ {
std::vector <Range> brokenFragments; all.push_back (interval);
for (auto& fragment : intervalFragments)
for (auto& broken : fragment.subtract (exclusion))
brokenFragments.push_back (broken);
intervalFragments = brokenFragments;
} }
for (auto& fragment : intervalFragments) // Open intervals need to be split according to the exclusions.
else
{ {
// Clone the interval, set the new range.
Interval clipped {interval}; // Start with a single range from the interval, from which to subtract.
clipped.range = fragment; std::vector <Range> intervalFragments {interval.range};
combined.push_back (clipped); for (auto& exclusion : exclusions)
{
std::vector <Range> brokenFragments;
for (auto& fragment : intervalFragments)
for (auto& broken : fragment.subtract (exclusion))
brokenFragments.push_back (broken);
intervalFragments = brokenFragments;
}
// Return all the fragments as intervals.
for (auto& fragment : intervalFragments)
{
// Clone the interval, set the new range.
Interval clipped {interval};
clipped.range = fragment;
all.push_back (clipped);
}
} }
} }
return combined;; return all;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////