NO-OP session-property comments
[ardour.git] / libs / ardour / ardour / export_multiplication.h
1 /*
2     Copyright (C) 2012 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 /* This file is not used at the moment. It includes code related to export a
21  * multiplication graph system that can be used together with the ExportMultiplicator
22  * class in the gtk2_ardour folder.
23  * - Sakari Bergen 6.8.2008 -
24  */
25
26 /*** Graph classes ***/
27   public:
28
29         /// A node in the hierarchical graph that represents a multiplicatable export item
30         class GraphNode {
31           public:
32                 GraphNode ();
33                 virtual ~GraphNode ();
34
35                 uint32_t id() const { return _id; }
36
37                 /* Children and parents. Note: only children are kept in order! */
38
39                 list<GraphNode *> const & get_parents () const { return parents; }
40
41                 void add_child (GraphNode * child, GraphNode * left_sibling);
42                 void remove_child (GraphNode * child);
43                 GraphNode * first_child () const { return children.front(); }
44                 GraphNode * last_child () const { return children.back(); }
45                 list<GraphNode *> const & get_children () const { return children; }
46
47                 /* Relation functions */
48
49                 bool is_ancestor_of (GraphNode const * node) const;
50                 bool is_descendant_of (GraphNode const * node) const;
51                 bool equals (GraphNode const * node) const { return node == this; }
52
53                 /* Selection functions */
54
55                 bool selected () const { return _selected; }
56                 void select (bool value);
57
58                 PBD::Signal1<void,bool> SelectChanged;
59
60           protected:
61
62                 /* Parent manipulation functions should be used only from child manipulation functions! */
63
64                 void add_parent (GraphNode * parent);
65                 void remove_parent (GraphNode * parent);
66
67                 list<GraphNode *> parents;
68                 list<GraphNode *> children;
69
70                 bool           _selected;
71                 uint32_t       _id;
72                 static uint32_t id_counter;
73         };
74
75         /// A graph node that contains data
76         template <typename T>
77         class DataNode : public GraphNode {
78           private:
79                 typedef boost::shared_ptr<T> DataPtr;
80                 typedef boost::shared_ptr<DataNode<T> > SelfPtr;
81                 typedef boost::weak_ptr<DataNode<T> > WeakSelfPtr;
82
83                 DataNode (DataPtr data) : _data (data) {}
84                 void set_self_ptr (boost::shared_ptr<DataNode<T> > ptr) { _self_ptr = ptr; }
85
86           public:
87                 static SelfPtr create (T * data)
88                 {
89                         SelfPtr ptr = SelfPtr (new DataNode<T> (DataPtr (data)));
90                         ptr->set_self_ptr (ptr);
91                         return ptr;
92                 }
93
94                 static SelfPtr create (DataPtr data)
95                 {
96                         SelfPtr ptr = SelfPtr (new DataNode<T> (data));
97                         ptr->set_self_ptr (ptr);
98                         return ptr;
99                 }
100
101                 DataPtr data() { return _data; }
102                 SelfPtr self_ptr () { return _self_ptr.lock(); }
103
104                 template<typename P> // Parent's data type
105                 void sort_parents (list<boost::shared_ptr<DataNode<P> > > const & sort_list)
106                 {
107                         parents.sort (NodeSorter<P> (sort_list));
108                 }
109
110           private:
111                 DataPtr     _data;
112                 WeakSelfPtr _self_ptr;
113         };
114
115   private:
116         /* Sorts GraphNodes according to a list of DataNodes */
117
118         template<typename T>
119         class NodeSorter {
120           public:
121                 typedef list<boost::shared_ptr<DataNode<T> > > ListType;
122
123                 NodeSorter (ListType const & list) : list (list) {}
124
125                 bool operator() (GraphNode * one, GraphNode * other) // '<' operator
126                 {
127                         if (one == other) { return false; } // Strict weak ordering
128                         for (typename ListType::const_iterator it = list.begin(); it != list.end(); ++it) {
129                                 if (it->get() == one) {
130                                         return true;
131                                 }
132                                 if (it->get() == other) {
133                                         return false;
134                                 }
135                         }
136
137                         std::cerr << "Invalid comparison list given to NodeSorter" << std::endl;
138
139                         abort();
140                 }
141
142           private:
143                 ListType const & list;
144         };
145
146 /*** Multiplication management ***/
147   public:
148
149         typedef DataNode<TimespanState> TimespanNode;
150         typedef boost::shared_ptr<TimespanNode> TimespanNodePtr;
151
152         typedef DataNode<ChannelConfigState> ChannelConfigNode;
153         typedef boost::shared_ptr<ChannelConfigNode> ChannelConfigNodePtr;
154
155         typedef DataNode<FormatState> FormatNode;
156         typedef boost::shared_ptr<FormatNode> FormatNodePtr;
157
158         typedef DataNode<FilenameState> FilenameNode;
159         typedef boost::shared_ptr<FilenameNode> FilenameNodePtr;
160
161         struct MultiplicationGraph {
162                 list<TimespanNodePtr>      timespans;
163                 list<ChannelConfigNodePtr> channel_configs;
164                 list<FormatNodePtr>        formats;
165                 list<FilenameNodePtr>      filenames;
166         };
167
168         MultiplicationGraph const & get_graph () { return graph; }
169
170         void split_node (GraphNode * node, float position);
171         void remove_node (GraphNode * node);
172
173         PBD::Signal0<void> GraphChanged;
174
175   private:
176
177         void purge_graph ();
178
179         template<typename T>
180         static void insert_after (list<T> & the_list, T const & position, T const & element);
181
182         template<typename T>
183         static void remove_by_element (list<T> & the_list, T const & element);
184
185         bool nodes_have_one_common_child (list<GraphNode *> const & the_list);
186         list<GraphNode *>::const_iterator end_of_common_child_range (list<GraphNode *> const & the_list, list<GraphNode *>::const_iterator beginning);
187         void split_node_at_position (GraphNode * old_node, GraphNode * new_node, float position);
188
189         void split_timespan (TimespanNodePtr node, float position = 0.5);
190         void split_channel_config (ChannelConfigNodePtr node, float position = 0.5);
191         void split_format (FormatNodePtr node, float position = 0.5);
192         void split_filename (FilenameNodePtr node, float position = 0.5);
193
194         void duplicate_timespan_children (TimespanNodePtr source, TimespanNodePtr target, GraphNode * insertion_point = 0);
195         void duplicate_channel_config_children (ChannelConfigNodePtr source, ChannelConfigNodePtr target, GraphNode * insertion_point = 0);
196         void duplicate_format_children (FormatNodePtr source, FormatNodePtr target, GraphNode * insertion_point = 0);
197
198         TimespanNodePtr duplicate_timespan_node (TimespanNodePtr node);
199         ChannelConfigNodePtr duplicate_channel_config_node (ChannelConfigNodePtr node);
200         FormatNodePtr duplicate_format_node (FormatNodePtr node);
201         FilenameNodePtr duplicate_filename_node (FilenameNodePtr node);
202
203         void remove_timespan (TimespanNodePtr node);
204         void remove_channel_config (ChannelConfigNodePtr node);
205         void remove_format (FormatNodePtr node);
206         void remove_filename (FilenameNodePtr node);
207
208         MultiplicationGraph graph;