tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_AsyncFunctionUtils.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
18{
20 AsyncCaller() = default;
21
24 {
25 function = std::move (f);
26 }
27
29 ~AsyncCaller() override
30 {
32 }
33
35 void setFunction (std::function<void()> f)
36 {
37 function = std::move (f);
38 }
39
41 void handleAsyncUpdate() override
42 {
43 jassert (function);
44 function();
45 }
46
47 std::function<void()> function;
48};
49
50//==============================================================================
55{
58
61 {
63 }
64
66 void addFunction (int functionID, const std::function<void()>& f)
67 {
68 functions[functionID] = { false, f };
69 }
70
72 void updateAsync (int functionID)
73 {
74 auto found = functions.find (functionID);
75
76 if (found != functions.end())
77 {
78 found->second.first = true;
80 }
81 }
82
97
99 void handleAsyncUpdate() override
100 {
101 auto compareAndReset = [] (bool& flag) -> bool
102 {
103 if (! flag)
104 return false;
105
106 flag = false;
107 return true;
108 };
109
110 for (auto&& f : functions)
111 if (compareAndReset (f.second.first))
112 f.second.second();
113 }
114
115 std::map<int, std::pair<bool, std::function<void (void)>>> functions;
116};
117
118//==============================================================================
120{
121public:
122 LambdaTimer() = default;
123
124 LambdaTimer (std::function<void()> newCallback)
125 {
126 callback = std::move (newCallback);
127 }
128
129 void setCallback (std::function<void()> newCallback)
130 {
131 callback = std::move (newCallback);
132 }
133
134 template<typename DurationType>
135 void startTimer (std::chrono::duration<DurationType> interval)
136 {
137 juce::Timer::startTimer (static_cast<int> (std::chrono::duration_cast<std::chrono::milliseconds> (interval).count()));
138 }
139
141
142 void timerCallback() override
143 {
144 if (callback)
145 callback();
146 }
147
148private:
149 std::function<void()> callback;
150
152};
153
154//==============================================================================
157{
158public:
159 MessageThreadCallback() = default;
161
163 bool hasFinished() const noexcept { return finished; }
164
169 {
170 if (juce::MessageManager::getInstance()->isThisTheMessageThread())
171 {
172 handleAsyncUpdate();
173 return;
174 }
175
177
179 {
180 while (! (job->shouldExit() || hasFinished()))
181 waiter.wait (50);
182
183 if (job->shouldExit())
184 {
185 hasBeenCancelled = true;
187 }
188
189 return;
190 }
191
192 if (auto thread = juce::Thread::getCurrentThread())
193 {
194 while (! (thread->threadShouldExit() || hasFinished()))
195 waiter.wait (50);
196
197 if (thread->threadShouldExit())
198 {
199 hasBeenCancelled = true;
201 }
202
203 return;
204 }
205
206 TRACKTION_LOG_ERROR ("Rogue call to triggerAndWaitForCallback()");
208 waiter.wait (50);
209
210 if (! hasFinished())
211 {
213 TRACKTION_LOG_ERROR ("triggerAndWaitForCallback() unable to complete");
214 }
215 }
216
217 virtual void performAction() = 0;
218
219private:
220 std::atomic<bool> finished { false }, hasBeenCancelled { false };
221 juce::WaitableEvent waiter;
222
223 void handleAsyncUpdate() override
224 {
226 TRACKTION_ASSERT_MESSAGE_THREAD
227
228 if (hasBeenCancelled)
229 return;
230
231 performAction();
232 finished = true;
233 waiter.signal();
234 }
235
237};
238
239//==============================================================================
241{
242 BlockingFunction (std::function<void()> f) : fn (f) {}
243
244private:
245 std::function<void()> fn;
246 void performAction() override { fn(); }
247
249};
250
251inline bool callBlocking (std::function<void()> f)
252{
253 BlockingFunction bf (f);
254 bf.triggerAndWaitForCallback();
255 return bf.hasFinished();
256}
257
258}} // namespace tracktion { inline namespace engine
void handleUpdateNowIfNeeded()
void cancelPendingUpdate() noexcept
static ThreadPoolJob * getCurrentThreadPoolJob()
void startTimer(int intervalInMilliseconds) noexcept
void signal() const
bool wait(double timeOutMilliseconds=-1.0) const
Calls a function on the message thread checking a calling thread for an exit signal.
void triggerAndWaitForCallback()
Triggers the callback to happen on the message thread and blocks until it has returned or the thread ...
bool hasFinished() const noexcept
Returns true if the callback has completed.
T end(T... args)
T find(T... args)
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
#define jassertfalse
typedef int
Asyncronously call a function.
void setFunction(std::function< void()> f)
Sets the function to call.
AsyncCaller(std::function< void()> f)
Creates an AsyncCaller with a given callback function.
AsyncCaller()=default
Creates an empty AsyncCaller.
Holds a list of function objects and enables you to call them asyncronously.
void updateAsync(int functionID)
Triggers an asyncronous call to one of the functions.
void handleUpdateNowIfNeeded()
If an update has been triggered and is pending, this will invoke it synchronously.
AsyncFunctionCaller()=default
Creates an empty AsyncFunctionCaller.
void addFunction(int functionID, const std::function< void()> &f)
Adds a function and associates a functionID with it.
#define CRASH_TRACER
This macro adds the current location to a stack which gets logged if a crash happens.