OpenShot Audio Library | OpenShotAudio
1.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
juce_TimeSliceThread.cpp
1
/*
2
==============================================================================
3
4
This file is part of the JUCE library.
5
Copyright (c) 2022 - Raw Material Software Limited
6
7
JUCE is an open source library subject to commercial or open-source
8
licensing.
9
10
The code included in this file is provided under the terms of the ISC license
11
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12
To use, copy, modify, and/or distribute this software for any purpose with or
13
without fee is hereby granted provided that the above copyright notice and
14
this permission notice appear in all copies.
15
16
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18
DISCLAIMED.
19
20
==============================================================================
21
*/
22
23
namespace
juce
24
{
25
26
TimeSliceThread::TimeSliceThread
(
const
String
& name) :
Thread
(name)
27
{
28
}
29
30
TimeSliceThread::~TimeSliceThread
()
31
{
32
stopThread
(2000);
33
}
34
35
//==============================================================================
36
void
TimeSliceThread::addTimeSliceClient
(
TimeSliceClient
*
const
client,
int
millisecondsBeforeStarting)
37
{
38
if
(client !=
nullptr
)
39
{
40
const
ScopedLock sl (listLock);
41
client->nextCallTime =
Time::getCurrentTime
() +
RelativeTime::milliseconds
(millisecondsBeforeStarting);
42
clients.addIfNotAlreadyThere (client);
43
notify
();
44
}
45
}
46
47
void
TimeSliceThread::removeTimeSliceClient
(
TimeSliceClient
*
const
client)
48
{
49
const
ScopedLock sl1 (listLock);
50
51
// if there's a chance we're in the middle of calling this client, we need to
52
// also lock the outer lock..
53
if
(clientBeingCalled == client)
54
{
55
const
ScopedUnlock ul (listLock);
// unlock first to get the order right..
56
57
const
ScopedLock sl2 (callbackLock);
58
const
ScopedLock sl3 (listLock);
59
60
clients.removeFirstMatchingValue (client);
61
}
62
else
63
{
64
clients.removeFirstMatchingValue (client);
65
}
66
}
67
68
void
TimeSliceThread::removeAllClients
()
69
{
70
for
(;;)
71
{
72
if
(
auto
* c =
getClient
(0))
73
removeTimeSliceClient
(c);
74
else
75
break
;
76
}
77
}
78
79
void
TimeSliceThread::moveToFrontOfQueue
(
TimeSliceClient
* client)
80
{
81
const
ScopedLock sl (listLock);
82
83
if
(clients.contains (client))
84
{
85
client->nextCallTime =
Time::getCurrentTime
();
86
notify
();
87
}
88
}
89
90
int
TimeSliceThread::getNumClients
()
const
91
{
92
const
ScopedLock sl (listLock);
93
return
clients.size();
94
}
95
96
TimeSliceClient
*
TimeSliceThread::getClient
(
const
int
i)
const
97
{
98
const
ScopedLock sl (listLock);
99
return
clients[i];
100
}
101
102
bool
TimeSliceThread::contains
(
const
TimeSliceClient
* c)
const
103
{
104
const
ScopedLock sl (listLock);
105
return
std::any_of (clients.begin(), clients.end(), [=] (
auto
* registered) { return registered == c; });
106
}
107
108
//==============================================================================
109
TimeSliceClient
* TimeSliceThread::getNextClient (
int
index)
const
110
{
111
Time
soonest;
112
TimeSliceClient
* client =
nullptr
;
113
114
for
(
int
i = clients.size(); --i >= 0;)
115
{
116
auto
* c = clients.getUnchecked ((i + index) % clients.size());
117
118
if
(c !=
nullptr
&& (client ==
nullptr
|| c->nextCallTime < soonest))
119
{
120
client = c;
121
soonest = c->nextCallTime;
122
}
123
}
124
125
return
client;
126
}
127
128
void
TimeSliceThread::run
()
129
{
130
int
index = 0;
131
132
while
(!
threadShouldExit
())
133
{
134
int
timeToWait = 500;
135
136
{
137
Time
nextClientTime;
138
int
numClients = 0;
139
140
{
141
const
ScopedLock sl2 (listLock);
142
143
numClients = clients.size();
144
index = numClients > 0 ? ((index + 1) % numClients) : 0;
145
146
if
(
auto
* firstClient = getNextClient (index))
147
nextClientTime = firstClient->nextCallTime;
148
}
149
150
if
(numClients > 0)
151
{
152
auto
now =
Time::getCurrentTime
();
153
154
if
(nextClientTime > now)
155
{
156
timeToWait = (int) jmin ((int64) 500, (nextClientTime - now).inMilliseconds());
157
}
158
else
159
{
160
timeToWait = index == 0 ? 1 : 0;
161
162
const
ScopedLock sl (callbackLock);
163
164
{
165
const
ScopedLock sl2 (listLock);
166
clientBeingCalled = getNextClient (index);
167
}
168
169
if
(clientBeingCalled !=
nullptr
)
170
{
171
const
int
msUntilNextCall = clientBeingCalled->useTimeSlice();
172
173
const
ScopedLock sl2 (listLock);
174
175
if
(msUntilNextCall >= 0)
176
clientBeingCalled->nextCallTime = now +
RelativeTime::milliseconds
(msUntilNextCall);
177
else
178
clients.removeFirstMatchingValue (clientBeingCalled);
179
180
clientBeingCalled =
nullptr
;
181
}
182
}
183
}
184
}
185
186
if
(timeToWait > 0)
187
wait
(timeToWait);
188
}
189
}
190
191
}
// namespace juce
juce::RelativeTime::milliseconds
static RelativeTime milliseconds(int milliseconds) noexcept
Definition
juce_RelativeTime.cpp:31
juce::String
Definition
juce_String.h:53
juce::Thread::wait
bool wait(double timeOutMilliseconds) const
Definition
juce_Thread.cpp:288
juce::Thread::Thread
Thread(const String &threadName, size_t threadStackSize=osDefaultStackSize)
Definition
juce_Thread.cpp:26
juce::Thread::threadShouldExit
bool threadShouldExit() const
Definition
juce_Thread.cpp:202
juce::Thread::stopThread
bool stopThread(int timeOutMilliseconds)
Definition
juce_Thread.cpp:233
juce::Thread::notify
void notify() const
Definition
juce_Thread.cpp:293
juce::TimeSliceClient
Definition
juce_TimeSliceThread.h:44
juce::TimeSliceThread::getNumClients
int getNumClients() const
Definition
juce_TimeSliceThread.cpp:90
juce::TimeSliceThread::removeTimeSliceClient
void removeTimeSliceClient(TimeSliceClient *clientToRemove)
Definition
juce_TimeSliceThread.cpp:47
juce::TimeSliceThread::addTimeSliceClient
void addTimeSliceClient(TimeSliceClient *clientToAdd, int millisecondsBeforeStarting=0)
Definition
juce_TimeSliceThread.cpp:36
juce::TimeSliceThread::~TimeSliceThread
~TimeSliceThread() override
Definition
juce_TimeSliceThread.cpp:30
juce::TimeSliceThread::getClient
TimeSliceClient * getClient(int index) const
Definition
juce_TimeSliceThread.cpp:96
juce::TimeSliceThread::moveToFrontOfQueue
void moveToFrontOfQueue(TimeSliceClient *clientToMove)
Definition
juce_TimeSliceThread.cpp:79
juce::TimeSliceThread::contains
bool contains(const TimeSliceClient *) const
Definition
juce_TimeSliceThread.cpp:102
juce::TimeSliceThread::removeAllClients
void removeAllClients()
Definition
juce_TimeSliceThread.cpp:68
juce::TimeSliceThread::run
void run() override
Definition
juce_TimeSliceThread.cpp:128
juce::TimeSliceThread::TimeSliceThread
TimeSliceThread(const String &threadName)
Definition
juce_TimeSliceThread.cpp:26
juce::Time
Definition
juce_Time.h:37
juce::Time::getCurrentTime
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Definition
juce_Time.cpp:233
libopenshot-audio
JuceLibraryCode
modules
juce_core
threads
juce_TimeSliceThread.cpp
Generated by
1.18.0