// timeline.cpp // // Object timelines. // // Copyright (C) 2008, the Celestia Development Team // Initial version by Chris Laurel, claurel@gmail.com // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. #include "celengine/timeline.h" #include "celengine/timelinephase.h" #include "celengine/frametree.h" #include "celengine/frame.h" using namespace std; /*! A Timeline is a list of TimelinePhases that covers a continuous * interval of time. */ Timeline::~Timeline() { for (auto phase : phases) { // Remove the phase from whatever phase tree contains it. phase->getFrameTree()->removeChild(phase); } } bool Timeline::appendPhase(TimelinePhase::SharedConstPtr &phase) { // Validate start and end times. If there are existing phases in the timeline, // startTime must be equal to endTime of the previous phases so that there are // no gaps and no overlaps. if (!phases.empty()) { if (phase->startTime() != phases.back()->endTime()) return false; } phases.push_back(phase); return true; } const TimelinePhase::SharedConstPtr& Timeline::findPhase(double t) const { // Find the phase containing time t. The overwhelming common case is // nPhases = 1, so we special case that. Otherwise, we do a simple linear search, // as the number of phases in a timeline should always be quite small. if (phases.size() == 1) { return phases[0]; } else { for (const auto& phase : phases) { if (t < phase->endTime()) return phase; } // Time is greater than the end time of the final phase. Just return the final phase. return phases.back(); } } /*! Get the phase at the specified index. */ const TimelinePhase::SharedConstPtr& Timeline::getPhase(unsigned int n) const { return phases.at(n); } /*! Get the number of phases in this timeline. */ unsigned int Timeline::phaseCount() const { return phases.size(); } double Timeline::startTime() const { return phases.front()->startTime(); } double Timeline::endTime() const { return phases.back()->endTime(); } /*! Check whether the timeline covers the specified time t. True if * startTime <= t <= endTime. Note that this is deliberately different * than the TimelinePhase::includes function, which is only true if * t is strictly less than the end time. */ bool Timeline::includes(double t) const { return phases.front()->startTime() <= t && t <= phases.back()->endTime(); } void Timeline::markChanged() { if (phases.size() == 1) { phases[0]->getFrameTree()->markChanged(); } else { for (const auto &phase : phases) phase->getFrameTree()->markChanged(); } }