summaryrefslogtreecommitdiffstats
path: root/src/base/CompositionTimeSliceAdapter.h
blob: 01307e394341f8263e6541977b424d0a740fa138 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// -*- c-basic-offset: 4 -*-

/*
    Rosegarden
    A sequencer and musical notation editor.

    This program is Copyright 2000-2008
        Guillaume Laurent   <glaurent@telegraph-road.org>,
        Chris Cannam        <cannam@all-day-breakfast.com>,
        Richard Bown        <bownie@bownie.com>

    This file is Copyright 2002
        Randall Farmer      <rfarme@simons-rock.edu>
        with additional work by Chris Cannam.

    The moral right of the authors to claim authorship of this work
    has been asserted.

    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.  See the file
    COPYING included with this distribution for more information.
*/

#ifndef _COMPOSITION_TIMESLICE_ADAPTER_H_
#define _COMPOSITION_TIMESLICE_ADAPTER_H_

#include <list>
#include <utility>

#include "Segment.h"

namespace Rosegarden {

class Event;
class Composition;
class SegmentSelection;

/**
 * CompositionTimeSliceAdapter provides the ability to iterate through
 * all the events in a Composition in time order, across many segments
 * at once.
 *
 * The CompositionTimeSliceAdapter is suitable for use as the backing
 * container for the Set classes, notably GenericChord (see Sets.h).
 * This combination enables you to iterate through a Composition as a
 * sequence of chords composed of all Events on a set of Segments that
 * lie within a particular quantize range of one another.
 */

class CompositionTimeSliceAdapter
{
public:
    class iterator;
    typedef std::set<TrackId> TrackSet;

    /**
     * Construct a CompositionTimeSliceAdapter that operates on the
     * given section in time of the given composition.  If begin and
     * end are equal, the whole composition will be used.
     */
    CompositionTimeSliceAdapter(Composition* c,
                                timeT begin = 0,
                                timeT end = 0);

    /**
     * Construct a CompositionTimeSliceAdapter that operates on the
     * given section in time of the given set of segments within the
     * given composition.  If begin and end are equal, the whole
     * duration of the composition will be used.
     */
    CompositionTimeSliceAdapter(Composition* c,
                                SegmentSelection* s,
                                timeT begin = 0,
                                timeT end = 0);

    /**
     * Construct a CompositionTimeSliceAdapter that operates on the
     * given section in time of all the segments in the given set of
     * tracks within the given composition.  If begin and end are
     * equal, the whole duration of the composition will be used.
     */
    CompositionTimeSliceAdapter(Composition *c,
                                const TrackSet &trackIDs,
                                timeT begin = 0,
                                timeT end = 0);

    ~CompositionTimeSliceAdapter() { };

    // bit sloppy -- we don't have a const_iterator
    iterator begin() const;
    iterator end() const;

    typedef std::vector<Segment *> segmentlist;
    typedef std::vector<Segment::iterator> segmentitrlist;

    Composition *getComposition() { return m_composition; }

    class iterator {
        friend class CompositionTimeSliceAdapter;

    public:
        iterator() :
            m_a(0), m_curEvent(0), m_curTrack(-1), m_needFill(true) { }
        iterator(const CompositionTimeSliceAdapter *a) :
            m_a(a), m_curEvent(0), m_curTrack(-1), m_needFill(true) { }
        iterator(const iterator &);
        iterator &operator=(const iterator &);
        ~iterator() { };

        iterator &operator++();
        iterator &operator--();

        bool operator==(const iterator& other) const;
        bool operator!=(const iterator& other) const;

        Event *operator*() const;
        Event &operator->() const;

        int getTrack() const;

    private:
        segmentitrlist m_segmentItrList;
        const CompositionTimeSliceAdapter *m_a;
        Event*  m_curEvent;
        int     m_curTrack;
        bool    m_needFill;

        static bool strictLessThan(Event *, Event *);
    };


private:
    friend class iterator;

    Composition* m_composition;
    mutable iterator m_beginItr;
    timeT m_begin;
    timeT m_end;

    segmentlist m_segmentList;

    void fill(iterator &, bool atEnd) const;
};

}

#endif