Chris@1074
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1074
|
2
|
Chris@1074
|
3 /*
|
Chris@1074
|
4 Sonic Visualiser
|
Chris@1074
|
5 An audio file viewer and annotation editor.
|
Chris@1074
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1074
|
7
|
Chris@1074
|
8 This program is free software; you can redistribute it and/or
|
Chris@1074
|
9 modify it under the terms of the GNU General Public License as
|
Chris@1074
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@1074
|
11 License, or (at your option) any later version. See the file
|
Chris@1074
|
12 COPYING included with this distribution for more information.
|
Chris@1074
|
13 */
|
Chris@1074
|
14
|
Chris@1074
|
15 #ifndef RENDER_TIMER_H
|
Chris@1074
|
16 #define RENDER_TIMER_H
|
Chris@1074
|
17
|
Chris@1074
|
18 #include <chrono>
|
Chris@1074
|
19
|
Chris@1074
|
20 class RenderTimer
|
Chris@1074
|
21 {
|
Chris@1074
|
22 public:
|
Chris@1074
|
23 enum Type {
|
Chris@1074
|
24 /// A normal rendering operation with normal responsiveness demands
|
Chris@1074
|
25 FastRender,
|
Chris@1074
|
26
|
Chris@1074
|
27 /// An operation that the user might accept being slower
|
Chris@1074
|
28 SlowRender,
|
Chris@1074
|
29
|
Chris@1074
|
30 /// An operation that should always complete, i.e. as if there
|
Chris@1074
|
31 /// were no RenderTimer in use, but without having to change
|
Chris@1074
|
32 /// client code structurally
|
Chris@1074
|
33 NoTimeout
|
Chris@1074
|
34 };
|
Chris@1074
|
35
|
Chris@1074
|
36 /**
|
Chris@1074
|
37 * Create a new RenderTimer and start timing. Make one of these
|
Chris@1074
|
38 * before rendering, and then call outOfTime() regularly during
|
Chris@1074
|
39 * rendering. If outOfTime() returns true, abandon rendering! and
|
Chris@1074
|
40 * schedule the rest for after some user responsiveness has
|
Chris@1074
|
41 * happened.
|
Chris@1074
|
42 */
|
Chris@1074
|
43 RenderTimer(Type t) :
|
Chris@1074
|
44 m_start(std::chrono::steady_clock::now()),
|
Chris@1074
|
45 m_haveLimits(true),
|
Chris@1074
|
46 m_minFraction(0.1),
|
Chris@1074
|
47 m_softLimit(0.1),
|
Chris@1074
|
48 m_hardLimit(0.2),
|
Chris@1074
|
49 m_softLimitOverridden(false) {
|
Chris@1074
|
50
|
Chris@1074
|
51 if (t == NoTimeout) {
|
Chris@1074
|
52 m_haveLimits = false;
|
Chris@1074
|
53 } else if (t == SlowRender) {
|
Chris@1074
|
54 m_softLimit = 0.2;
|
Chris@1074
|
55 m_hardLimit = 0.4;
|
Chris@1074
|
56 }
|
Chris@1074
|
57 }
|
Chris@1074
|
58
|
Chris@1074
|
59
|
Chris@1074
|
60 /**
|
Chris@1074
|
61 * Return true if we have run out of time and should suspend
|
Chris@1074
|
62 * rendering and handle user events instead. Call this regularly
|
Chris@1074
|
63 * during rendering work: fractionComplete should be an estimate
|
Chris@1074
|
64 * of how much of the work has been done as of this call, as a
|
Chris@1074
|
65 * number between 0.0 (none of it) and 1.0 (all of it).
|
Chris@1074
|
66 */
|
Chris@1074
|
67 bool outOfTime(double fractionComplete) {
|
Chris@1074
|
68
|
Chris@1074
|
69 if (!m_haveLimits || fractionComplete < m_minFraction) {
|
Chris@1074
|
70 return false;
|
Chris@1074
|
71 }
|
Chris@1074
|
72
|
Chris@1074
|
73 auto t = std::chrono::steady_clock::now();
|
Chris@1074
|
74 double elapsed = std::chrono::duration<double>(t - m_start).count();
|
Chris@1074
|
75
|
Chris@1074
|
76 if (elapsed > m_hardLimit) {
|
Chris@1074
|
77 return true;
|
Chris@1074
|
78 } else if (!m_softLimitOverridden && elapsed > m_softLimit) {
|
Chris@1074
|
79 if (fractionComplete > 0.6) {
|
Chris@1074
|
80 // If we're significantly more than half way by the
|
Chris@1074
|
81 // time we reach the soft limit, ignore it (though
|
Chris@1074
|
82 // always respect the hard limit, above). Otherwise
|
Chris@1074
|
83 // respect the soft limit and report out of time now.
|
Chris@1074
|
84 m_softLimitOverridden = true;
|
Chris@1074
|
85 } else {
|
Chris@1074
|
86 return true;
|
Chris@1074
|
87 }
|
Chris@1074
|
88 }
|
Chris@1074
|
89
|
Chris@1074
|
90 return false;
|
Chris@1074
|
91 }
|
Chris@1074
|
92
|
Chris@1074
|
93 private:
|
Chris@1074
|
94 std::chrono::time_point<std::chrono::steady_clock> m_start;
|
Chris@1074
|
95 bool m_haveLimits;
|
Chris@1074
|
96 double m_minFraction;
|
Chris@1074
|
97 double m_softLimit;
|
Chris@1074
|
98 double m_hardLimit;
|
Chris@1074
|
99 bool m_softLimitOverridden;
|
Chris@1074
|
100 };
|
Chris@1074
|
101
|
Chris@1074
|
102 #endif
|