*** NEW CODING POLICY ***
[ardour.git] / libs / ardour / port_set.cc
1 /*
2     Copyright (C) 2006 Paul Davis 
3     
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8     
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     for more details.
13     
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include "ardour/port_set.h"
20 #include "ardour/midi_port.h"
21 #include "ardour/audio_port.h"
22
23 namespace ARDOUR {
24
25 PortSet::PortSet()
26 {
27         for (size_t i=0; i < DataType::num_types; ++i)
28                 _ports.push_back( PortVec() );
29 }
30
31 static bool sort_ports_by_name (Port* a, Port* b)
32 {
33         return (a->name() < b->name());
34 }
35
36 void
37 PortSet::add(Port* port)
38 {
39         PortVec& v = _ports[port->type()];
40         
41         v.push_back(port);
42         sort(v.begin(), v.end(), sort_ports_by_name);
43
44         _count.set(port->type(), _count.get(port->type()) + 1);
45
46         assert(_count.get(port->type()) == _ports[port->type()].size());
47 }
48
49 bool
50 PortSet::remove(Port* port)
51 {
52         for (std::vector<PortVec>::iterator l = _ports.begin(); l != _ports.end(); ++l) {
53                 PortVec::iterator i = find(l->begin(), l->end(), port);
54                 if (i != l->end()) {
55                         l->erase(i);
56                         _count.set(port->type(), _count.get(port->type()) - 1);
57                         return true;
58                 }
59         }
60
61         return false;
62 }
63
64 /** Get the total number of ports (of all types) in the PortSet
65  */
66 size_t
67 PortSet::num_ports() const
68 {
69         size_t ret = 0;
70
71         for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l)
72                 ret += (*l).size();
73
74         return ret;
75 }
76
77 bool
78 PortSet::contains(const Port* port) const
79 {
80         for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l)
81                 if (find((*l).begin(), (*l).end(), port) != (*l).end())
82                         return true;
83
84         return false;
85 }
86
87 Port*
88 PortSet::port(size_t n) const
89 {
90         // This is awesome.  Awesomely slow.
91         
92         size_t size_so_far = 0;
93
94         for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) {
95                 if (n < size_so_far + (*l).size())
96                         return (*l)[n - size_so_far];
97                 else
98                         size_so_far += (*l).size();
99         }
100
101         return NULL; // n out of range
102 }
103
104 Port*
105 PortSet::port(DataType type, size_t n) const
106 {
107         if (type == DataType::NIL) {
108                 return port(n);
109         } else {
110                 const PortVec& v = _ports[type];
111                 assert(n < v.size());
112                 return v[n];
113         }
114 }
115
116 AudioPort*
117 PortSet::nth_audio_port(size_t n) const
118 {
119         return dynamic_cast<AudioPort*>(port(DataType::AUDIO, n));
120 }
121
122 MidiPort*
123 PortSet::nth_midi_port(size_t n) const
124 {
125         return dynamic_cast<MidiPort*>(port(DataType::MIDI, n));
126 }
127
128 } // namepace ARDOUR