* Fixed crash on closing MIDI automation tracks, because ARDOUR::Parameter::operator...
authorHans Baier <hansfbaier@googlemail.com>
Fri, 16 May 2008 20:54:24 +0000 (20:54 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Fri, 16 May 2008 20:54:24 +0000 (20:54 +0000)
  which is necessary for std::set to work correctly
* few small style guide corrections

git-svn-id: svn://localhost/ardour2/branches/3.0@3363 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/route_time_axis.cc
libs/ardour/ardour/midi_ring_buffer.h
libs/ardour/ardour/parameter.h

index 1977858f0fc2beeba4bcd52ef1c36cd46619d9a1..a5619b8ae9bc613a2f8a0bed84b8255ac5000a5b 100644 (file)
@@ -1619,8 +1619,9 @@ void
 RouteTimeAxisView::automation_track_hidden (Parameter param)
 {
        RouteAutomationNode* ran = automation_track(param);
-       if (!ran)
+       if (!ran) {
                return;
+       }
 
        _show_automation.erase(param);
        ran->track->get_state_node()->add_property (X_("shown"), X_("no"));
index baa8e9d94868a203e3f8f173d0e965759c41261a..76cefd57a1823d81c0356b9bf12f3479dbe29178 100644 (file)
@@ -141,13 +141,15 @@ template<typename T>
 bool
 MidiRingBufferBase<T>::full_peek(size_t size, T* dst)
 {
-       if (read_space() < size)
+       if (read_space() < size) {
                return false;
+       }
 
        const size_t read_size = peek(size, dst);
        
-       if (read_size < size)
+       if (read_size < size) {
                peek(size - read_size, dst + read_size);
+       }
 
        return true;
 }
@@ -181,13 +183,15 @@ template<typename T>
 bool
 MidiRingBufferBase<T>::full_read(size_t size, T* dst)
 {
-       if (read_space() < size)
+       if (read_space() < size) {
                return false;
+       }
 
        const size_t read_size = read(size, dst);
        
-       if (read_size < size)
+       if (read_size < size) {
                read(size - read_size, dst + read_size);
+       }
 
        return true;
 }
@@ -292,11 +296,14 @@ inline bool
 MidiRingBuffer::read(double* time, size_t* size, Byte* buf)
 {
        bool success = MidiRingBufferBase<Byte>::full_read(sizeof(double), (Byte*)time);
-       if (success)
+       
+       if (success) {
                success = MidiRingBufferBase<Byte>::full_read(sizeof(size_t), (Byte*)size);
-       if (success)
+       }
+       if (success) {
                success = MidiRingBufferBase<Byte>::full_read(*size, buf);
-
+       }
+       
        return success;
 }
 
@@ -308,8 +315,9 @@ inline bool
 MidiRingBuffer::read_prefix(double* time, size_t* size)
 {
        bool success = MidiRingBufferBase<Byte>::full_read(sizeof(double), (Byte*)time);
-       if (success)
+       if (success) {
                success = MidiRingBufferBase<Byte>::full_read(sizeof(size_t), (Byte*)size);
+       }
 
        return success;
 }
@@ -338,8 +346,9 @@ MidiRingBuffer::write(double time, size_t size, const Byte* buf)
        // Don't write event if it doesn't match channel filter
        if (is_channel_event(buf[0]) && get_channel_mode() == FilterChannels) {
                Byte channel = buf[0] & 0x0F;
-               if ( !(get_channel_mask() & (1L << channel)) )
+               if ( !(get_channel_mask() & (1L << channel)) ) {
                        return 0;
+               }
        }
 
        if (write_space() < (sizeof(double) + sizeof(size_t) + size)) {
@@ -388,8 +397,9 @@ MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t
        
                full_peek(sizeof(double), (Byte*)&ev_time);
        
-               if (ev_time > end)
+               if (ev_time > end) {
                        break;
+               }
                
                bool success = MidiRingBufferBase<Byte>::full_read(sizeof(double), (Byte*)&ev_time);
                if (success) {
index a795ee0eaae9a01ddb226bff272792cd77479ba7..b86174aa0a819c700ea71e1e23fdd50ed5280365 100644 (file)
@@ -58,17 +58,61 @@ public:
        inline uint32_t       id()      const { return _id; }
        inline uint8_t        channel() const { return _channel; }
 
+       /**
+        * Equivalence operator
+        * It is obvious from the definition that this operator
+        * is transitive, as required by stict weak ordering
+        * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)
+        */
        inline bool operator==(const Parameter& id) const {
                return (_type == id._type && _id == id._id && _channel == id._channel);
        }
        
-       /** Arbitrary but fixed ordering (for use in e.g. std::map) */
+       /** Strict weak ordering 
+        * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)  
+        * This is necessary so that std::set works): 
+        * Sort Parameters first according to type then to id and lastly to channel.
+        *  
+        * Proof:
+        * <ol>
+        * <li>Irreflexivity: f(x, x) is false because of the irreflexivity of \c < in each branch.</li>
+        * 
+        * <li>Antisymmetry: given x != y, f(x, y) implies !f(y, x) because of the same 
+        *     property of \c < in each branch and the symmetry of operator==. </li>
+        * 
+        * <li>Transitivity: let f(x, y) and f(y, z) be true. We prove by assuming the contrary,
+        *     that f(x, z) does not hold. 
+        *    That would imply exactly one of the following:
+        *        <ol>
+        *      <li> x == z which contradicts the assumption f(x, y) and f(y, x)
+        *                 because of antisymmetry.
+        *      </li>
+        *      <li> f(z, x) is true. That would imply that one of the ivars (we call it i) 
+        *           of x is greater than the same ivar in z while all "previous" ivars
+        *           are equal. That would imply that also in y all those "previous"
+        *           ivars are equal and because if x.i > z.i it is impossible
+        *           that there is an y that satisfies x.i < y.i < z.i at the same
+        *           time which contradicts the assumption.
+        *      </li>
+        *    </ol> 
+        * </li>
+        * </ol>
+        */
+       
        inline bool operator<(const Parameter& id) const {
 #ifndef NDEBUG
                if (_type == NullAutomation)
                        PBD::warning << "Uninitialized Parameter compared." << endmsg;
 #endif
-               return (_channel < id._channel || _type < id._type || _id < id._id);
+               if (_type < id._type) {
+                       return true;
+               } else if (_type == id._type && _id < id._id) {
+                       return true;
+               } else if (_id == id._id && _channel < id._channel) {
+                       return true;
+               }
+               
+               return false;
        }
        
        inline operator bool() const { return (_type != 0); }