annotate base/Scavenger.h @ 5:31c4ed2d5da6

* Hook up SV file i/o. You can now save and load sessions. Some problems -- gain is not reloaded correctly for waveforms, reloaded panes are not properly reconnected to the panner, and no doubt plenty of others.
author Chris Cannam
date Tue, 17 Jan 2006 17:45:55 +0000
parents d86891498eef
children b101cc2ae1ab
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@2 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 /*
Chris@0 11 This is a modified version of a source file from the
Chris@0 12 Rosegarden MIDI and audio sequencer and notation editor.
Chris@0 13 This file copyright 2000-2005 Chris Cannam.
Chris@0 14 */
Chris@0 15
Chris@0 16 #ifndef _SCAVENGER_H_
Chris@0 17 #define _SCAVENGER_H_
Chris@0 18
Chris@0 19 #include "System.h"
Chris@0 20
Chris@0 21 #include <vector>
Chris@0 22 #include <sys/time.h>
Chris@0 23
Chris@0 24 /**
Chris@0 25 * A very simple class that facilitates running things like plugins
Chris@0 26 * without locking, by collecting unwanted objects and deleting them
Chris@0 27 * after a delay so as to be sure nobody's in the middle of using
Chris@0 28 * them. Requires scavenge() to be called regularly from a non-RT
Chris@0 29 * thread.
Chris@0 30 *
Chris@0 31 * This is currently not at all suitable for large numbers of objects
Chris@0 32 * -- it's just a quick hack for use with things like plugins.
Chris@0 33 */
Chris@0 34
Chris@0 35 template <typename T>
Chris@0 36 class Scavenger
Chris@0 37 {
Chris@0 38 public:
Chris@0 39 Scavenger(int sec = 2, int defaultObjectListSize = 200);
Chris@0 40
Chris@0 41 /**
Chris@0 42 * Call from an RT thread etc., to pass ownership of t to us.
Chris@0 43 * Only one thread should be calling this on any given scavenger.
Chris@0 44 */
Chris@0 45 void claim(T *t);
Chris@0 46
Chris@0 47 /**
Chris@0 48 * Call from a non-RT thread.
Chris@0 49 * Only one thread should be calling this on any given scavenger.
Chris@0 50 */
Chris@0 51 void scavenge();
Chris@0 52
Chris@0 53 protected:
Chris@0 54 typedef std::pair<T *, int> ObjectTimePair;
Chris@0 55 typedef std::vector<ObjectTimePair> ObjectTimeList;
Chris@0 56 ObjectTimeList m_objects;
Chris@0 57 int m_sec;
Chris@0 58
Chris@0 59 unsigned int m_claimed;
Chris@0 60 unsigned int m_scavenged;
Chris@0 61 };
Chris@0 62
Chris@0 63 /**
Chris@0 64 * A wrapper to permit arrays to be scavenged.
Chris@0 65 */
Chris@0 66
Chris@0 67 template <typename T>
Chris@0 68 class ScavengerArrayWrapper
Chris@0 69 {
Chris@0 70 public:
Chris@0 71 ScavengerArrayWrapper(T *array) : m_array(array) { }
Chris@0 72 ~ScavengerArrayWrapper() { delete[] m_array; }
Chris@0 73
Chris@0 74 private:
Chris@0 75 T *m_array;
Chris@0 76 };
Chris@0 77
Chris@0 78
Chris@0 79 template <typename T>
Chris@0 80 Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) :
Chris@0 81 m_objects(ObjectTimeList(defaultObjectListSize)),
Chris@0 82 m_sec(sec),
Chris@0 83 m_claimed(0),
Chris@0 84 m_scavenged(0)
Chris@0 85 {
Chris@0 86 }
Chris@0 87
Chris@0 88 template <typename T>
Chris@0 89 void
Chris@0 90 Scavenger<T>::claim(T *t)
Chris@0 91 {
Chris@0 92 // std::cerr << "Scavenger::claim(" << t << ")" << std::endl;
Chris@0 93
Chris@0 94 struct timeval tv;
Chris@0 95 (void)gettimeofday(&tv, 0);
Chris@0 96 int sec = tv.tv_sec;
Chris@0 97
Chris@0 98 for (size_t i = 0; i < m_objects.size(); ++i) {
Chris@0 99 ObjectTimePair &pair = m_objects[i];
Chris@0 100 if (pair.first == 0) {
Chris@0 101 pair.second = sec;
Chris@0 102 pair.first = t;
Chris@0 103 ++m_claimed;
Chris@0 104 return;
Chris@0 105 }
Chris@0 106 }
Chris@0 107
Chris@0 108 // Oh no -- run out of slots! Warn and discard something at
Chris@0 109 // random (without deleting it -- it's probably safer to leak).
Chris@0 110
Chris@0 111 for (size_t i = 0; i < m_objects.size(); ++i) {
Chris@0 112 ObjectTimePair &pair = m_objects[i];
Chris@0 113 if (pair.first != 0) {
Chris@0 114 pair.second = sec;
Chris@0 115 pair.first = t;
Chris@0 116 ++m_claimed;
Chris@0 117 ++m_scavenged;
Chris@0 118 }
Chris@0 119 }
Chris@0 120 }
Chris@0 121
Chris@0 122 template <typename T>
Chris@0 123 void
Chris@0 124 Scavenger<T>::scavenge()
Chris@0 125 {
Chris@0 126 // std::cerr << "Scavenger::scavenge: scavenged " << m_scavenged << ", claimed " << m_claimed << std::endl;
Chris@0 127
Chris@0 128 if (m_scavenged >= m_claimed) return;
Chris@0 129
Chris@0 130 struct timeval tv;
Chris@0 131 (void)gettimeofday(&tv, 0);
Chris@0 132 int sec = tv.tv_sec;
Chris@0 133
Chris@0 134 for (size_t i = 0; i < m_objects.size(); ++i) {
Chris@0 135 ObjectTimePair &pair = m_objects[i];
Chris@0 136 if (pair.first != 0 && pair.second + m_sec < sec) {
Chris@0 137 T *ot = pair.first;
Chris@0 138 pair.first = 0;
Chris@0 139 delete ot;
Chris@0 140 ++m_scavenged;
Chris@0 141 }
Chris@0 142 }
Chris@0 143 }
Chris@0 144
Chris@0 145 #endif