Celestia
1// timeline.cpp
2//
3// Object timelines.
4//
5// Copyright (C) 2008, the Celestia Development Team
6// Initial version by Chris Laurel, claurel@gmail.com
7//
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU General Public License
10// as published by the Free Software Foundation; either version 2
11// of the License, or (at your option) any later version.
12
13#include "celengine/timeline.h"14#include "celengine/timelinephase.h"15#include "celengine/frametree.h"16#include "celengine/frame.h"17
18using namespace std;19
20
21/*! A Timeline is a list of TimelinePhases that covers a continuous
22* interval of time.
23*/
24
25Timeline::~Timeline()26{
27for (auto phase : phases)28{29// Remove the phase from whatever phase tree contains it.30phase->getFrameTree()->removeChild(phase);31}32}
33
34
35bool
36Timeline::appendPhase(TimelinePhase::SharedConstPtr &phase)37{
38// Validate start and end times. If there are existing phases in the timeline,39// startTime must be equal to endTime of the previous phases so that there are40// no gaps and no overlaps.41if (!phases.empty())42{43if (phase->startTime() != phases.back()->endTime())44return false;45}46
47phases.push_back(phase);48
49return true;50}
51
52
53const TimelinePhase::SharedConstPtr&54Timeline::findPhase(double t) const55{
56// Find the phase containing time t. The overwhelming common case is57// nPhases = 1, so we special case that. Otherwise, we do a simple linear search,58// as the number of phases in a timeline should always be quite small.59if (phases.size() == 1)60{61return phases[0];62}63else64{65for (const auto& phase : phases)66{67if (t < phase->endTime())68return phase;69}70
71// Time is greater than the end time of the final phase. Just return the final phase.72return phases.back();73}74}
75
76
77/*! Get the phase at the specified index.
78*/
79const TimelinePhase::SharedConstPtr&80Timeline::getPhase(unsigned int n) const81{
82return phases.at(n);83}
84
85
86/*! Get the number of phases in this timeline.
87*/
88unsigned int89Timeline::phaseCount() const90{
91return phases.size();92}
93
94
95double
96Timeline::startTime() const97{
98return phases.front()->startTime();99}
100
101
102double
103Timeline::endTime() const104{
105return phases.back()->endTime();106}
107
108
109/*! Check whether the timeline covers the specified time t. True if
110* startTime <= t <= endTime. Note that this is deliberately different
111* than the TimelinePhase::includes function, which is only true if
112* t is strictly less than the end time.
113*/
114bool
115Timeline::includes(double t) const116{
117return phases.front()->startTime() <= t && t <= phases.back()->endTime();118}
119
120
121void
122Timeline::markChanged()123{
124if (phases.size() == 1)125{126phases[0]->getFrameTree()->markChanged();127}128else129{130for (const auto &phase : phases)131phase->getFrameTree()->markChanged();132}133}
134