X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fport_set.h;h=cd76f75ee3be691ecbf700db33515e8a9f8aebbb;hb=6584a89c4eb5024fe89a15acd8e4fa4697e606be;hp=34967831e7c7f1e18c4e18a1f8b9809b8d0065a2;hpb=9a4a9cbb63958484553ed981822ca97ceb1dc4f5;p=ardour.git diff --git a/libs/ardour/ardour/port_set.h b/libs/ardour/ardour/port_set.h index 34967831e7..cd76f75ee3 100644 --- a/libs/ardour/ardour/port_set.h +++ b/libs/ardour/ardour/port_set.h @@ -1,16 +1,16 @@ /* - Copyright (C) 2006 Paul Davis - + Copyright (C) 2006 Paul Davis + 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. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -20,112 +20,101 @@ #define __ardour_port_set_h__ #include -#include -#include -#include -#include +#include "ardour/chan_count.h" +#include namespace ARDOUR { +class Port; +class AudioPort; +class MidiPort; /** An ordered list of Ports, possibly of various types. * * This allows access to all the ports as a list, ignoring type, or accessing * the nth port of a given type. Note that port(n) and nth_audio_port(n) may * NOT return the same port. + * + * Each port is held twice; once in a per-type vector of vectors (_ports) + * and once in a vector of all port (_all_ports). This is to speed up the + * fairly common case of iterating over all ports. */ -class PortSet { +class LIBARDOUR_API PortSet : public boost::noncopyable { public: PortSet(); size_t num_ports() const; - size_t num_ports(DataType type) const { return _ports[type.to_index()].size(); } + size_t num_ports(DataType type) const { return _ports[type].size(); } - void add(Port* port); - bool remove(Port* port); + void add (boost::shared_ptr port); + bool remove (boost::shared_ptr port); /** nth port */ - Port* port(size_t index) const; - + boost::shared_ptr port(size_t index) const; + /** nth port of type @a t, or nth port if t = NIL */ - Port* port(DataType t, size_t index) const; + boost::shared_ptr port(DataType t, size_t index) const; + + boost::shared_ptr nth_audio_port(size_t n) const; - AudioPort* nth_audio_port(size_t n) const; - - MidiPort* nth_midi_port(size_t n) const; + boost::shared_ptr nth_midi_port(size_t n) const; + + bool contains (boost::shared_ptr port) const; - bool contains(const Port* port) const; - /** Remove all ports from the PortSet. Ports are not deregistered with * the engine, it's the caller's responsibility to not leak here! */ - void clear() { _ports.clear(); } + void clear(); const ChanCount& count() const { return _count; } - bool empty() const { return (_count.get_total() == 0); } + bool empty() const { return (_count.n_total() == 0); } - // ITERATORS - - // FIXME: this is a filthy copy-and-paste mess - - class iterator { + template + class iterator_base { public: - - Port& operator*() { return *_set.port(_type, _index); } - Port* operator->() { return _set.port(_type, _index); } - iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const iterator& other) { return (_index == other._index); } - bool operator!=(const iterator& other) { return (_index != other._index); } + boost::shared_ptr

operator*() { return _set.port(_type, _index); } + boost::shared_ptr

operator->() { return _set.port(_type, _index); } + iterator_base& operator++() { ++_index; return *this; } // yes, prefix only + bool operator==(const iterator_base& other) { return (_index == other._index); } + bool operator!=(const iterator_base& other) { return (_index != other._index); } private: friend class PortSet; - iterator(PortSet& list, DataType type, size_t index) + iterator_base(PS& list, DataType type, size_t index) : _set(list), _type(type), _index(index) {} - PortSet& _set; + PS& _set; DataType _type; ///< Ignored if NIL (to iterator over entire set) size_t _index; }; - iterator begin(DataType type = DataType::NIL) - { return iterator(*this, type, 0); } - - iterator end(DataType type = DataType::NIL) - { - return iterator(*this, type, - (type == DataType::NIL) ? _count.get_total() : _count.get(type)); - } - - // FIXME: typeify - class const_iterator { - public: - - const Port& operator*() { return *_set.port(_index); } - const Port* operator->() { return _set.port(_index); } - const_iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const const_iterator& other) { return (_index == other._index); } - bool operator!=(const const_iterator& other) { return (_index != other._index); } - - private: - friend class PortSet; + typedef iterator_base iterator; + typedef iterator_base const_iterator; - const_iterator(const PortSet& list, size_t index) : _set(list), _index(index) {} + iterator begin(DataType type = DataType::NIL) { + return iterator(*this, type, 0); + } - const PortSet& _set; - size_t _index; - }; + iterator end(DataType type = DataType::NIL) { + return iterator(*this, type, + (type == DataType::NIL) ? _count.n_total() : _count.get(type)); + } - const_iterator begin() const { return const_iterator(*this, 0); } - const_iterator end() const { return const_iterator(*this, _count.get_total()); } + const_iterator begin(DataType type = DataType::NIL) const { + return const_iterator(*this, type, 0); + } + const_iterator end(DataType type = DataType::NIL) const { + return const_iterator(*this, type, + (type == DataType::NIL) ? _count.n_total() : _count.get(type)); + } class audio_iterator { public: - - AudioPort& operator*() { return *_set.nth_audio_port(_index); } - AudioPort* operator->() { return _set.nth_audio_port(_index); } + boost::shared_ptr operator*() { return _set.nth_audio_port(_index); } + boost::shared_ptr operator->() { return _set.nth_audio_port(_index); } audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only bool operator==(const audio_iterator& other) { return (_index == other._index); } bool operator!=(const audio_iterator& other) { return (_index != other._index); } @@ -136,21 +125,19 @@ public: audio_iterator(PortSet& list, size_t index) : _set(list), _index(index) {} PortSet& _set; - size_t _index; + size_t _index; }; audio_iterator audio_begin() { return audio_iterator(*this, 0); } audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); } -private: - // Prevent copies (undefined) - PortSet(const PortSet& copy); - void operator=(const PortSet& other); +private: + typedef std::vector > PortVec; - typedef std::vector PortVec; - // Vector of vectors, indexed by DataType::to_index() std::vector _ports; + // All ports in _ports in one vector, to speed some operations + PortVec _all_ports; ChanCount _count; };