1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Sonic Visualiser
5     An audio file viewer and annotation editor.
6     Centre for Digital Music, Queen Mary, University of London.
7 
8     This program is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License as
10     published by the Free Software Foundation; either version 2 of the
11     License, or (at your option) any later version.  See the file
12     COPYING included with this distribution for more information.
13 */
14 
15 #ifndef SV_DEFERRED_NOTIFIER_H
16 #define SV_DEFERRED_NOTIFIER_H
17 
18 #include "Model.h"
19 
20 #include "base/Extents.h"
21 
22 #include <QMutex>
23 #include <QMutexLocker>
24 
25 class DeferredNotifier
26 {
27 public:
28     enum Mode {
29         NOTIFY_ALWAYS,
30         NOTIFY_DEFERRED
31     };
32 
DeferredNotifier(Model * m,ModelId id,Mode mode)33     DeferredNotifier(Model *m, ModelId id, Mode mode) :
34         m_model(m), m_modelId(id), m_mode(mode) { }
35 
getMode()36     Mode getMode() const {
37         return m_mode;
38     }
switchMode(Mode newMode)39     void switchMode(Mode newMode) {
40         m_mode = newMode;
41     }
42 
update(sv_frame_t frame,sv_frame_t duration)43     void update(sv_frame_t frame, sv_frame_t duration) {
44         if (m_mode == NOTIFY_ALWAYS) {
45             m_model->modelChangedWithin(m_modelId, frame, frame + duration);
46         } else {
47             QMutexLocker locker(&m_mutex);
48             m_extents.sample(frame);
49             m_extents.sample(frame + duration);
50         }
51     }
52 
makeDeferredNotifications()53     void makeDeferredNotifications() {
54         bool shouldEmit = false;
55         sv_frame_t from, to;
56         {   QMutexLocker locker(&m_mutex);
57             if (m_extents.isSet()) {
58                 shouldEmit = true;
59                 from = m_extents.getMin();
60                 to = m_extents.getMax();
61             }
62         }
63         if (shouldEmit) {
64             m_model->modelChangedWithin(m_modelId, from, to);
65             QMutexLocker locker(&m_mutex);
66             m_extents.reset();
67         }
68     }
69 
70 private:
71     Model *m_model;
72     ModelId m_modelId;
73     Mode m_mode;
74     QMutex m_mutex;
75     Extents<sv_frame_t> m_extents;
76 };
77 
78 #endif
79