mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-11 23:54:18 +00:00
Correction to String::copyToUTF8. Millisecond timer rollover fix. Added channel count to BufferingAudioSource. Hashmap speed-up. Added Identifier::isValidIdentifier.
This commit is contained in:
parent
f307045b92
commit
b820ec4567
21 changed files with 264 additions and 270 deletions
|
|
@ -646,6 +646,10 @@
|
|||
#include <dwrite.h>
|
||||
#endif
|
||||
|
||||
#ifndef WM_APPCOMMAND
|
||||
#define WM_APPCOMMAND 0x0319
|
||||
#endif
|
||||
|
||||
/** A simple COM smart pointer.
|
||||
Avoids having to include ATL just to get one of these.
|
||||
*/
|
||||
|
|
@ -1716,20 +1720,6 @@ const String SystemStats::getJUCEVersion()
|
|||
static JuceVersionPrinter juceVersionPrinter;
|
||||
#endif
|
||||
|
||||
#ifdef JUCE_DLL
|
||||
void* juce_Malloc (int size) { return malloc (size); }
|
||||
void* juce_Calloc (int size) { return calloc (1, size); }
|
||||
void* juce_Realloc (void* block, int size) { return realloc (block, size); }
|
||||
void juce_Free (void* block) { free (block); }
|
||||
|
||||
#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
|
||||
void* juce_DebugMalloc (int size, const char* file, int line) { return _malloc_dbg (size, _NORMAL_BLOCK, file, line); }
|
||||
void* juce_DebugCalloc (int size, const char* file, int line) { return _calloc_dbg (1, size, _NORMAL_BLOCK, file, line); }
|
||||
void* juce_DebugRealloc (void* block, int size, const char* file, int line) { return _realloc_dbg (block, size, _NORMAL_BLOCK, file, line); }
|
||||
void juce_DebugFree (void* block) { _free_dbg (block, _NORMAL_BLOCK); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
/*** End of inlined file: juce_SystemStats.cpp ***/
|
||||
|
|
@ -2032,7 +2022,9 @@ uint32 Time::getMillisecondCounter() noexcept
|
|||
|
||||
uint32 Time::getApproximateMillisecondCounter() noexcept
|
||||
{
|
||||
jassert (TimeHelpers::lastMSCounterValue != 0);
|
||||
if (TimeHelpers::lastMSCounterValue == 0)
|
||||
getMillisecondCounter();
|
||||
|
||||
return TimeHelpers::lastMSCounterValue;
|
||||
}
|
||||
|
||||
|
|
@ -4164,7 +4156,7 @@ Identifier::Identifier (const String& name_)
|
|||
{
|
||||
/* An Identifier string must be suitable for use as a script variable or XML
|
||||
attribute, so it can only contain this limited set of characters.. */
|
||||
jassert (name_.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name_.isNotEmpty());
|
||||
jassert (isValidIdentifier (name_));
|
||||
}
|
||||
|
||||
Identifier::Identifier (const char* const name_)
|
||||
|
|
@ -4172,13 +4164,19 @@ Identifier::Identifier (const char* const name_)
|
|||
{
|
||||
/* An Identifier string must be suitable for use as a script variable or XML
|
||||
attribute, so it can only contain this limited set of characters.. */
|
||||
jassert (toString().containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && toString().isNotEmpty());
|
||||
jassert (isValidIdentifier (toString()));
|
||||
}
|
||||
|
||||
Identifier::~Identifier()
|
||||
{
|
||||
}
|
||||
|
||||
bool Identifier::isValidIdentifier (const String& possibleIdentifier) noexcept
|
||||
{
|
||||
return possibleIdentifier.isNotEmpty()
|
||||
&& possibleIdentifier.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
/*** End of inlined file: juce_Identifier.cpp ***/
|
||||
|
|
@ -4740,7 +4738,7 @@ const var NamedValueSet::getWithDefault (const Identifier& name, const var& defa
|
|||
return v != nullptr ? *v : defaultReturnValue;
|
||||
}
|
||||
|
||||
var* NamedValueSet::getVarPointer (const Identifier& name) const
|
||||
var* NamedValueSet::getVarPointer (const Identifier& name) const noexcept
|
||||
{
|
||||
for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
|
||||
if (i->name == name)
|
||||
|
|
@ -13550,7 +13548,7 @@ struct StringCopier
|
|||
jassert (maxBufferSizeBytes >= 0); // keep this value positive, or no characters will be copied!
|
||||
|
||||
if (buffer == nullptr)
|
||||
return (int) CharPointerType_Dest::getBytesRequiredFor (source);
|
||||
return (int) (CharPointerType_Dest::getBytesRequiredFor (source) + sizeof (typename CharPointerType_Dest::CharType));
|
||||
|
||||
return CharPointerType_Dest (buffer).writeWithDestByteLimit (source, maxBufferSizeBytes);
|
||||
}
|
||||
|
|
@ -24596,7 +24594,7 @@ void AudioTransportSource::setSource (PositionableAudioSource* const newSource,
|
|||
|
||||
if (readAheadBufferSize_ > 0)
|
||||
newPositionableSource = newBufferingSource
|
||||
= new BufferingAudioSource (newPositionableSource, false, readAheadBufferSize_);
|
||||
= new BufferingAudioSource (newPositionableSource, false, readAheadBufferSize_, maxNumChannels);
|
||||
|
||||
newPositionableSource->setNextReadPosition (0);
|
||||
|
||||
|
|
@ -24897,11 +24895,13 @@ juce_ImplementSingleton (SharedBufferingAudioSourceThread)
|
|||
|
||||
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* source_,
|
||||
const bool deleteSourceWhenDeleted_,
|
||||
int numberOfSamplesToBuffer_)
|
||||
const int numberOfSamplesToBuffer_,
|
||||
const int numberOfChannels_)
|
||||
: source (source_),
|
||||
deleteSourceWhenDeleted (deleteSourceWhenDeleted_),
|
||||
numberOfSamplesToBuffer (jmax (1024, numberOfSamplesToBuffer_)),
|
||||
buffer (2, 0),
|
||||
numberOfChannels (numberOfChannels_),
|
||||
buffer (numberOfChannels_, 0),
|
||||
bufferValidStart (0),
|
||||
bufferValidEnd (0),
|
||||
nextPlayPos (0),
|
||||
|
|
@ -24930,7 +24930,7 @@ void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sa
|
|||
|
||||
sampleRate = sampleRate_;
|
||||
|
||||
buffer.setSize (2, jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer));
|
||||
buffer.setSize (numberOfChannels, jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer));
|
||||
buffer.clear();
|
||||
|
||||
bufferValidStart = 0;
|
||||
|
|
@ -24953,7 +24953,7 @@ void BufferingAudioSource::releaseResources()
|
|||
if (thread != nullptr)
|
||||
thread->removeSource (this);
|
||||
|
||||
buffer.setSize (2, 0);
|
||||
buffer.setSize (numberOfChannels, 0);
|
||||
source->releaseResources();
|
||||
}
|
||||
|
||||
|
|
@ -24980,7 +24980,7 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
|
|||
|
||||
if (validStart < validEnd)
|
||||
{
|
||||
for (int chan = jmin (2, info.buffer->getNumChannels()); --chan >= 0;)
|
||||
for (int chan = jmin (numberOfChannels, info.buffer->getNumChannels()); --chan >= 0;)
|
||||
{
|
||||
const int startBufferIndex = (validStart + nextPlayPos) % buffer.getNumSamples();
|
||||
const int endBufferIndex = (validEnd + nextPlayPos) % buffer.getNumSamples();
|
||||
|
|
@ -40070,13 +40070,14 @@ public:
|
|||
{
|
||||
const uint32 now = Time::getMillisecondCounter();
|
||||
|
||||
if (now <= lastTime)
|
||||
if (now == lastTime)
|
||||
{
|
||||
wait (2);
|
||||
wait (1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const int elapsed = now - lastTime;
|
||||
const int elapsed = now >= lastTime ? (now - lastTime)
|
||||
: (std::numeric_limits<uint32>::max() - (lastTime - now));
|
||||
lastTime = now;
|
||||
|
||||
const int timeUntilFirstTimer = getTimeUntilFirstTimer (elapsed);
|
||||
|
|
@ -70513,20 +70514,22 @@ public:
|
|||
{
|
||||
if (isVisible())
|
||||
{
|
||||
WeakReference<Component> deletionChecker (this);
|
||||
|
||||
activeSubMenu = nullptr;
|
||||
currentChild = nullptr;
|
||||
|
||||
exitModalState (item != nullptr ? item->itemId : 0);
|
||||
|
||||
if (makeInvisible)
|
||||
setVisible (false);
|
||||
|
||||
if (item != nullptr
|
||||
&& item->commandManager != nullptr
|
||||
&& item->itemId != 0)
|
||||
{
|
||||
*managerOfChosenCommand = item->commandManager;
|
||||
}
|
||||
|
||||
exitModalState (item != nullptr ? item->itemId : 0);
|
||||
|
||||
if (makeInvisible && (deletionChecker != nullptr))
|
||||
setVisible (false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79046,9 +79049,7 @@ void ComponentPeer::addMaskedRegion (int x, int y, int w, int h)
|
|||
|
||||
const StringArray ComponentPeer::getAvailableRenderingEngines()
|
||||
{
|
||||
StringArray s;
|
||||
s.add ("Software Renderer");
|
||||
return s;
|
||||
return StringArray ("Software Renderer");
|
||||
}
|
||||
|
||||
int ComponentPeer::getCurrentRenderingEngine() const
|
||||
|
|
@ -79701,12 +79702,12 @@ void ResizableWindow::resized()
|
|||
{
|
||||
if (resizableBorder != nullptr)
|
||||
{
|
||||
#if JUCE_WINDOWS || JUCE_LINUX
|
||||
#if JUCE_WINDOWS || JUCE_LINUX
|
||||
// hide the resizable border if the OS already provides one..
|
||||
resizableBorder->setVisible (! (isFullScreen() || isUsingNativeTitleBar()));
|
||||
#else
|
||||
#else
|
||||
resizableBorder->setVisible (! isFullScreen());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
resizableBorder->setBorderThickness (getBorderThickness());
|
||||
resizableBorder->setSize (getWidth(), getHeight());
|
||||
|
|
@ -79715,12 +79716,12 @@ void ResizableWindow::resized()
|
|||
|
||||
if (resizableCorner != nullptr)
|
||||
{
|
||||
#if JUCE_MAC
|
||||
#if JUCE_MAC
|
||||
// hide the resizable border if the OS already provides one..
|
||||
resizableCorner->setVisible (! (isFullScreen() || isUsingNativeTitleBar()));
|
||||
#else
|
||||
#else
|
||||
resizableCorner->setVisible (! isFullScreen());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const int resizerSize = 18;
|
||||
resizableCorner->setBounds (getWidth() - resizerSize,
|
||||
|
|
@ -79733,9 +79734,9 @@ void ResizableWindow::resized()
|
|||
|
||||
updateLastPos();
|
||||
|
||||
#if JUCE_DEBUG
|
||||
#if JUCE_DEBUG
|
||||
hasBeenResized = true;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void ResizableWindow::childBoundsChanged (Component* child)
|
||||
|
|
@ -79862,7 +79863,7 @@ void ResizableWindow::paint (Graphics& g)
|
|||
getBorderThickness(), *this);
|
||||
}
|
||||
|
||||
#if JUCE_DEBUG
|
||||
#if JUCE_DEBUG
|
||||
/* If this fails, then you've probably written a subclass with a resized()
|
||||
callback but forgotten to make it call its parent class's resized() method.
|
||||
|
||||
|
|
@ -79875,7 +79876,7 @@ void ResizableWindow::paint (Graphics& g)
|
|||
layout.
|
||||
*/
|
||||
jassert (hasBeenResized || (getWidth() == 0 && getHeight() == 0));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void ResizableWindow::lookAndFeelChanged()
|
||||
|
|
@ -243769,6 +243770,11 @@ void Logger::outputDebugString (const String& text)
|
|||
OutputDebugString ((text + "\n").toWideCharPointer());
|
||||
}
|
||||
|
||||
#ifdef JUCE_DLL
|
||||
JUCE_API void* juceDLL_malloc (size_t sz) { return ::malloc (sz); }
|
||||
JUCE_API void juceDLL_free (void* block) { ::free (block); }
|
||||
#endif
|
||||
|
||||
#if JUCE_USE_INTRINSICS || JUCE_64BIT
|
||||
|
||||
// CPU info functions using intrinsics...
|
||||
|
|
@ -244191,10 +244197,10 @@ void JUCE_API juce_threadEntryPoint (void*);
|
|||
|
||||
static unsigned int __stdcall threadEntryProc (void* userData)
|
||||
{
|
||||
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0),
|
||||
GetCurrentThreadId(), TRUE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
juce_threadEntryPoint (userData);
|
||||
|
||||
|
|
@ -244220,16 +244226,16 @@ void Thread::killThread()
|
|||
{
|
||||
if (threadHandle_ != 0)
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
#if JUCE_DEBUG
|
||||
OutputDebugString (_T("** Warning - Forced thread termination **\n"));
|
||||
#endif
|
||||
#endif
|
||||
TerminateThread (threadHandle_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::setCurrentThreadName (const String& name)
|
||||
{
|
||||
#if JUCE_DEBUG && JUCE_MSVC
|
||||
#if JUCE_DEBUG && JUCE_MSVC
|
||||
struct
|
||||
{
|
||||
DWORD dwType;
|
||||
|
|
@ -244249,9 +244255,9 @@ void Thread::setCurrentThreadName (const String& name)
|
|||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION)
|
||||
{}
|
||||
#else
|
||||
#else
|
||||
(void) name;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
Thread::ThreadID Thread::getCurrentThreadId()
|
||||
|
|
@ -244397,7 +244403,7 @@ void PlatformUtilities::freeDynamicLibrary (void* h)
|
|||
{
|
||||
JUCE_TRY
|
||||
{
|
||||
if (h != 0)
|
||||
if (h != nullptr)
|
||||
FreeLibrary ((HMODULE) h);
|
||||
}
|
||||
JUCE_CATCH_ALL
|
||||
|
|
@ -244405,7 +244411,7 @@ void PlatformUtilities::freeDynamicLibrary (void* h)
|
|||
|
||||
void* PlatformUtilities::getProcedureEntryPoint (void* h, const String& name)
|
||||
{
|
||||
return (h != 0) ? (void*) GetProcAddress ((HMODULE) h, name.toUTF8()) : nullptr; // (void* cast is required for mingw)
|
||||
return (h != nullptr) ? (void*) GetProcAddress ((HMODULE) h, name.toUTF8()) : nullptr; // (void* cast is required for mingw)
|
||||
}
|
||||
|
||||
class InterProcessLock::Pimpl
|
||||
|
|
@ -245366,11 +245372,11 @@ void NamedPipe::cancelPendingReads()
|
|||
#if JUCE_INCLUDED_FILE
|
||||
|
||||
#ifndef INTERNET_FLAG_NEED_FILE
|
||||
#define INTERNET_FLAG_NEED_FILE 0x00000010
|
||||
#define INTERNET_FLAG_NEED_FILE 0x00000010
|
||||
#endif
|
||||
|
||||
#ifndef INTERNET_OPTION_DISABLE_AUTODIAL
|
||||
#define INTERNET_OPTION_DISABLE_AUTODIAL 70
|
||||
#define INTERNET_OPTION_DISABLE_AUTODIAL 70
|
||||
#endif
|
||||
|
||||
#ifndef WORKAROUND_TIMEOUT_BUG
|
||||
|
|
@ -246040,10 +246046,6 @@ HWND juce_messageWindowHandle = 0;
|
|||
|
||||
extern long improbableWindowNumber; // defined in windowing.cpp
|
||||
|
||||
#ifndef WM_APPCOMMAND
|
||||
#define WM_APPCOMMAND 0x0319
|
||||
#endif
|
||||
|
||||
static LRESULT CALLBACK juce_MessageWndProc (HWND h,
|
||||
const UINT message,
|
||||
const WPARAM wParam,
|
||||
|
|
@ -247570,7 +247572,6 @@ private:
|
|||
#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12
|
||||
#define APPCOMMAND_MEDIA_STOP 13
|
||||
#define APPCOMMAND_MEDIA_PLAY_PAUSE 14
|
||||
#define WM_APPCOMMAND 0x0319
|
||||
#endif
|
||||
|
||||
extern void juce_repeatLastProcessPriority(); // in juce_win32_Threads.cpp
|
||||
|
|
@ -252279,29 +252280,32 @@ typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAt
|
|||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
||||
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
|
||||
|
||||
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||
#define WGL_ACCELERATION_ARB 0x2003
|
||||
#define WGL_SWAP_METHOD_ARB 0x2007
|
||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||
#define WGL_COLOR_BITS_ARB 0x2014
|
||||
#define WGL_RED_BITS_ARB 0x2015
|
||||
#define WGL_GREEN_BITS_ARB 0x2017
|
||||
#define WGL_BLUE_BITS_ARB 0x2019
|
||||
#define WGL_ALPHA_BITS_ARB 0x201B
|
||||
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||
#define WGL_FULL_ACCELERATION_ARB 0x2027
|
||||
#define WGL_ACCUM_RED_BITS_ARB 0x201E
|
||||
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
|
||||
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||
#define WGL_STEREO_ARB 0x2012
|
||||
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#define WGL_TYPE_RGBA_ARB 0x202B
|
||||
enum
|
||||
{
|
||||
WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000,
|
||||
WGL_DRAW_TO_WINDOW_ARB = 0x2001,
|
||||
WGL_ACCELERATION_ARB = 0x2003,
|
||||
WGL_SWAP_METHOD_ARB = 0x2007,
|
||||
WGL_SUPPORT_OPENGL_ARB = 0x2010,
|
||||
WGL_PIXEL_TYPE_ARB = 0x2013,
|
||||
WGL_DOUBLE_BUFFER_ARB = 0x2011,
|
||||
WGL_COLOR_BITS_ARB = 0x2014,
|
||||
WGL_RED_BITS_ARB = 0x2015,
|
||||
WGL_GREEN_BITS_ARB = 0x2017,
|
||||
WGL_BLUE_BITS_ARB = 0x2019,
|
||||
WGL_ALPHA_BITS_ARB = 0x201B,
|
||||
WGL_DEPTH_BITS_ARB = 0x2022,
|
||||
WGL_STENCIL_BITS_ARB = 0x2023,
|
||||
WGL_FULL_ACCELERATION_ARB = 0x2027,
|
||||
WGL_ACCUM_RED_BITS_ARB = 0x201E,
|
||||
WGL_ACCUM_GREEN_BITS_ARB = 0x201F,
|
||||
WGL_ACCUM_BLUE_BITS_ARB = 0x2020,
|
||||
WGL_ACCUM_ALPHA_BITS_ARB = 0x2021,
|
||||
WGL_STEREO_ARB = 0x2012,
|
||||
WGL_SAMPLE_BUFFERS_ARB = 0x2041,
|
||||
WGL_SAMPLES_ARB = 0x2042,
|
||||
WGL_TYPE_RGBA_ARB = 0x202B
|
||||
};
|
||||
|
||||
static void getWglExtensions (HDC dc, StringArray& result) noexcept
|
||||
{
|
||||
|
|
@ -261987,7 +261991,7 @@ int64 Time::getHighResolutionTicks() noexcept
|
|||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / (int64) 1000);
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept
|
||||
|
|
@ -269340,13 +269344,15 @@ public:
|
|||
{
|
||||
mach_timebase_info_data_t timebase;
|
||||
(void) mach_timebase_info (&timebase);
|
||||
highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer);
|
||||
highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom);
|
||||
highResTimerFrequency = (timebase.denom * (int64) 1000000000) / timebase.numer;
|
||||
numerator = timebase.numer;
|
||||
denominator = timebase.denom * (int64) 1000000;
|
||||
highResTimerToMillisecRatio = numerator / (double) denominator;
|
||||
}
|
||||
|
||||
inline uint32 millisecondsSinceStartup() const noexcept
|
||||
{
|
||||
return (uint32) (mach_absolute_time() * highResTimerToMillisecRatio);
|
||||
return (uint32) ((mach_absolute_time() * numerator) / denominator);
|
||||
}
|
||||
|
||||
inline double getMillisecondCounterHiRes() const noexcept
|
||||
|
|
@ -269355,6 +269361,9 @@ public:
|
|||
}
|
||||
|
||||
int64 highResTimerFrequency;
|
||||
|
||||
private:
|
||||
int64 numerator, denominator;
|
||||
double highResTimerToMillisecRatio;
|
||||
};
|
||||
|
||||
|
|
@ -271813,8 +271822,6 @@ public:
|
|||
timerCallback();
|
||||
}
|
||||
|
||||
~ScreenSaverDefeater() {}
|
||||
|
||||
void timerCallback()
|
||||
{
|
||||
if (Process::isForegroundProcess())
|
||||
|
|
@ -286929,7 +286936,7 @@ int64 Time::getHighResolutionTicks() noexcept
|
|||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / (int64) 1000);
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 53
|
||||
#define JUCE_BUILDNUMBER 85
|
||||
#define JUCE_BUILDNUMBER 86
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -895,102 +895,6 @@ extern JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger();
|
|||
#ifndef __JUCE_MEMORY_JUCEHEADER__
|
||||
#define __JUCE_MEMORY_JUCEHEADER__
|
||||
|
||||
/*
|
||||
This file defines the various juce_malloc(), juce_free() macros that can be used in
|
||||
preference to the standard calls.
|
||||
|
||||
None of this stuff is actually used in the library itself, and will probably be
|
||||
deprecated at some point in the future, to force everyone to use HeapBlock and other
|
||||
safer allocation methods.
|
||||
*/
|
||||
|
||||
#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS && ! DOXYGEN
|
||||
#ifndef JUCE_DLL
|
||||
|
||||
// Win32 debug non-DLL versions..
|
||||
|
||||
#define juce_malloc(numBytes) _malloc_dbg (numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define juce_calloc(numBytes) _calloc_dbg (1, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define juce_realloc(location, numBytes) _realloc_dbg (location, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define juce_free(location) _free_dbg (location, _NORMAL_BLOCK)
|
||||
|
||||
#else
|
||||
|
||||
// Win32 debug DLL versions..
|
||||
|
||||
// For the DLL, we'll define some functions in the DLL that will be used for allocation - that
|
||||
// way all juce calls in the DLL and in the host API will all use the same allocator.
|
||||
extern JUCE_API void* juce_DebugMalloc (int size, const char* file, int line);
|
||||
extern JUCE_API void* juce_DebugCalloc (int size, const char* file, int line);
|
||||
extern JUCE_API void* juce_DebugRealloc (void* block, int size, const char* file, int line);
|
||||
extern JUCE_API void juce_DebugFree (void* block);
|
||||
|
||||
#define juce_malloc(numBytes) JUCE_NAMESPACE::juce_DebugMalloc (numBytes, __FILE__, __LINE__)
|
||||
#define juce_calloc(numBytes) JUCE_NAMESPACE::juce_DebugCalloc (numBytes, __FILE__, __LINE__)
|
||||
#define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_DebugRealloc (location, numBytes, __FILE__, __LINE__)
|
||||
#define juce_free(location) JUCE_NAMESPACE::juce_DebugFree (location)
|
||||
|
||||
#define JUCE_LEAK_DETECTOR(OwnerClass) public:\
|
||||
static void* operator new (size_t sz) { void* const p = juce_malloc ((int) sz); return (p != 0) ? p : ::operator new (sz); } \
|
||||
static void* operator new (size_t, void* p) { return p; } \
|
||||
static void operator delete (void* p) { juce_free (p); } \
|
||||
static void operator delete (void*, void*) {}
|
||||
#endif
|
||||
|
||||
#elif defined (JUCE_DLL) && ! DOXYGEN
|
||||
|
||||
// Win32 DLL (release) versions..
|
||||
|
||||
// For the DLL, we'll define some functions in the DLL that will be used for allocation - that
|
||||
// way all juce calls in the DLL and in the host API will all use the same allocator.
|
||||
extern JUCE_API void* juce_Malloc (int size);
|
||||
extern JUCE_API void* juce_Calloc (int size);
|
||||
extern JUCE_API void* juce_Realloc (void* block, int size);
|
||||
extern JUCE_API void juce_Free (void* block);
|
||||
|
||||
#define juce_malloc(numBytes) JUCE_NAMESPACE::juce_Malloc (numBytes)
|
||||
#define juce_calloc(numBytes) JUCE_NAMESPACE::juce_Calloc (numBytes)
|
||||
#define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_Realloc (location, numBytes)
|
||||
#define juce_free(location) JUCE_NAMESPACE::juce_Free (location)
|
||||
|
||||
#define JUCE_LEAK_DETECTOR(OwnerClass) public:\
|
||||
static void* operator new (size_t sz) { void* const p = juce_malloc ((int) sz); return (p != 0) ? p : ::operator new (sz); } \
|
||||
static void* operator new (size_t, void* p) { return p; } \
|
||||
static void operator delete (void* p) { juce_free (p); } \
|
||||
static void operator delete (void*, void*) {}
|
||||
#else
|
||||
|
||||
// Mac, Linux and Win32 (release) versions..
|
||||
|
||||
/** This can be used instead of calling malloc directly.
|
||||
Only use direct memory allocation if there's really no way to use a HeapBlock object instead!
|
||||
*/
|
||||
#define juce_malloc(numBytes) malloc (numBytes)
|
||||
|
||||
/** This can be used instead of calling calloc directly.
|
||||
Only use direct memory allocation if there's really no way to use a HeapBlock object instead!
|
||||
*/
|
||||
#define juce_calloc(numBytes) calloc (1, numBytes)
|
||||
|
||||
/** This can be used instead of calling realloc directly.
|
||||
Only use direct memory allocation if there's really no way to use a HeapBlock object instead!
|
||||
*/
|
||||
#define juce_realloc(location, numBytes) realloc (location, numBytes)
|
||||
|
||||
/** This can be used instead of calling free directly.
|
||||
Only use direct memory allocation if there's really no way to use a HeapBlock object instead!
|
||||
*/
|
||||
#define juce_free(location) free (location)
|
||||
|
||||
#endif
|
||||
|
||||
/** (Deprecated) This was a win32-specific way of checking for object leaks - now please
|
||||
use the JUCE_LEAK_DETECTOR instead.
|
||||
*/
|
||||
#ifndef juce_UseDebuggingNewOperator
|
||||
#define juce_UseDebuggingNewOperator
|
||||
#endif
|
||||
|
||||
#if JUCE_MSVC || DOXYGEN
|
||||
/** This is a compiler-independent way of declaring a variable as being thread-local.
|
||||
|
||||
|
|
@ -1031,6 +935,35 @@ inline void deleteAndZero (Type& pointer) { delete pointer; pointer = nullp
|
|||
template <typename Type>
|
||||
inline Type* addBytesToPointer (Type* pointer, int bytes) noexcept { return (Type*) (((char*) pointer) + bytes); }
|
||||
|
||||
/** A handy function which returns the difference between any two pointers, in bytes.
|
||||
The address of the second pointer is subtracted from the first, and the difference in bytes is returned.
|
||||
*/
|
||||
template <typename Type1, typename Type2>
|
||||
inline int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept { return (int) (((const char*) pointer1) - (const char*) pointer2); }
|
||||
|
||||
/* In a win32 DLL build, we'll expose some malloc/free functions that live inside the DLL, and use these for
|
||||
allocating all the objects - that way all juce objects in the DLL and in the host will live in the same heap,
|
||||
avoiding problems when an object is created in one module and passed across to another where it is deleted.
|
||||
By piggy-backing on the JUCE_LEAK_DETECTOR macro, these allocators can be injected into most juce classes.
|
||||
*/
|
||||
#if JUCE_MSVC && defined (JUCE_DLL) && ! DOXYGEN
|
||||
extern JUCE_API void* juceDLL_malloc (size_t);
|
||||
extern JUCE_API void juceDLL_free (void*);
|
||||
|
||||
#define JUCE_LEAK_DETECTOR(OwnerClass) public:\
|
||||
static void* operator new (size_t sz) { return JUCE_NAMESPACE::juceDLL_malloc ((int) sz); } \
|
||||
static void* operator new (size_t, void* p) { return p; } \
|
||||
static void operator delete (void* p) { JUCE_NAMESPACE::juceDLL_free (p); } \
|
||||
static void operator delete (void*, void*) {}
|
||||
#endif
|
||||
|
||||
/** (Deprecated) This was a win32-specific way of checking for object leaks - now please
|
||||
use the JUCE_LEAK_DETECTOR instead.
|
||||
*/
|
||||
#ifndef juce_UseDebuggingNewOperator
|
||||
#define juce_UseDebuggingNewOperator
|
||||
#endif
|
||||
|
||||
#endif // __JUCE_MEMORY_JUCEHEADER__
|
||||
|
||||
/*** End of inlined file: juce_Memory.h ***/
|
||||
|
|
@ -1912,7 +1845,7 @@ public:
|
|||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
static int copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, int maxBytes) noexcept
|
||||
{
|
||||
int numBytesDone = 0;
|
||||
typename DestCharPointerType::CharType const* const startAddress = dest.getAddress();
|
||||
maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null)
|
||||
|
||||
for (;;)
|
||||
|
|
@ -1924,12 +1857,12 @@ public:
|
|||
if (c == 0 || maxBytes < 0)
|
||||
break;
|
||||
|
||||
numBytesDone += bytesNeeded;
|
||||
dest.write (c);
|
||||
}
|
||||
|
||||
dest.writeNull();
|
||||
return numBytesDone;
|
||||
|
||||
return getAddressDifference (dest.getAddress(), startAddress);
|
||||
}
|
||||
|
||||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
|
|
@ -8008,6 +7941,12 @@ public:
|
|||
/** Returns this identifier's raw string pointer. */
|
||||
operator const String::CharPointerType() const noexcept { return name; }
|
||||
|
||||
/** Checks a given string for characters that might not be valid in an Identifier.
|
||||
Since Identifiers are used as a script variables and XML attributes, they should only contain
|
||||
alphanumeric characters and underscores.
|
||||
*/
|
||||
static bool isValidIdentifier (const String& possibleIdentifier) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
String::CharPointerType name;
|
||||
|
|
@ -8053,7 +7992,7 @@ public:
|
|||
operator const String() const { return getDefault(); }
|
||||
};
|
||||
|
||||
/** An predefined object representing a new-line, which can be written to a string or stream.
|
||||
/** A predefined object representing a new-line, which can be written to a string or stream.
|
||||
|
||||
To write a new-line to a stream, you can use the predefined 'newLine' variable like this:
|
||||
@code
|
||||
|
|
@ -9317,7 +9256,7 @@ public:
|
|||
Do not use this method unless you really need access to the internal var object
|
||||
for some reason - for normal reading and writing always prefer operator[]() and set().
|
||||
*/
|
||||
var* getVarPointer (const Identifier& name) const;
|
||||
var* getVarPointer (const Identifier& name) const noexcept;
|
||||
|
||||
/** Sets properties to the values of all of an XML element's attributes. */
|
||||
void setFromXmlAttributes (const XmlElement& xml);
|
||||
|
|
@ -10791,7 +10730,7 @@ public:
|
|||
{
|
||||
const ScopedLockType sl (getLock());
|
||||
|
||||
for (const HashEntry* entry = slots [generateHashFor (keyToLookFor)]; entry != nullptr; entry = entry->nextEntry)
|
||||
for (const HashEntry* entry = slots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry)
|
||||
if (entry->key == keyToLookFor)
|
||||
return entry->value;
|
||||
|
||||
|
|
@ -10803,7 +10742,7 @@ public:
|
|||
{
|
||||
const ScopedLockType sl (getLock());
|
||||
|
||||
for (const HashEntry* entry = slots [generateHashFor (keyToLookFor)]; entry != nullptr; entry = entry->nextEntry)
|
||||
for (const HashEntry* entry = slots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry)
|
||||
if (entry->key == keyToLookFor)
|
||||
return true;
|
||||
|
||||
|
|
@ -10832,25 +10771,22 @@ public:
|
|||
const ScopedLockType sl (getLock());
|
||||
const int hashIndex = generateHashFor (newKey);
|
||||
|
||||
if (isPositiveAndBelow (hashIndex, getNumSlots()))
|
||||
HashEntry* const firstEntry = slots.getUnchecked (hashIndex);
|
||||
|
||||
for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry)
|
||||
{
|
||||
HashEntry* const firstEntry = slots.getUnchecked (hashIndex);
|
||||
|
||||
for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry)
|
||||
if (entry->key == newKey)
|
||||
{
|
||||
if (entry->key == newKey)
|
||||
{
|
||||
entry->value = newValue;
|
||||
return;
|
||||
}
|
||||
entry->value = newValue;
|
||||
return;
|
||||
}
|
||||
|
||||
slots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry));
|
||||
++totalNumItems;
|
||||
|
||||
if (totalNumItems > (getNumSlots() * 3) / 2)
|
||||
remapTable (getNumSlots() * 2);
|
||||
}
|
||||
|
||||
slots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry));
|
||||
++totalNumItems;
|
||||
|
||||
if (totalNumItems > (getNumSlots() * 3) / 2)
|
||||
remapTable (getNumSlots() * 2);
|
||||
}
|
||||
|
||||
/** Removes an item with the given key. */
|
||||
|
|
@ -10858,7 +10794,7 @@ public:
|
|||
{
|
||||
const ScopedLockType sl (getLock());
|
||||
const int hashIndex = generateHashFor (keyToRemove);
|
||||
HashEntry* entry = slots [hashIndex];
|
||||
HashEntry* entry = slots.getUnchecked (hashIndex);
|
||||
HashEntry* previous = nullptr;
|
||||
|
||||
while (entry != nullptr)
|
||||
|
|
@ -11953,6 +11889,10 @@ public:
|
|||
system clock. It should be accurate to within a few millisecs, depending on platform,
|
||||
hardware, etc.
|
||||
|
||||
Being a 32-bit return value, it will of course wrap back to 0 after 2^32 seconds of
|
||||
uptime, so be careful to take that into account. If you need a 64-bit time, you can
|
||||
use currentTimeMillis() instead.
|
||||
|
||||
@see getApproximateMillisecondCounter
|
||||
*/
|
||||
static uint32 getMillisecondCounter() noexcept;
|
||||
|
|
@ -38449,10 +38389,12 @@ public:
|
|||
@param deleteSourceWhenDeleted if true, then the input source object will
|
||||
be deleted when this object is deleted
|
||||
@param numberOfSamplesToBuffer the size of buffer to use for reading ahead
|
||||
@param numberOfChannels the number of channels that will be played
|
||||
*/
|
||||
BufferingAudioSource (PositionableAudioSource* source,
|
||||
bool deleteSourceWhenDeleted,
|
||||
int numberOfSamplesToBuffer);
|
||||
int numberOfSamplesToBuffer,
|
||||
int numberOfChannels = 2);
|
||||
|
||||
/** Destructor.
|
||||
|
||||
|
|
@ -38486,7 +38428,7 @@ private:
|
|||
|
||||
PositionableAudioSource* source;
|
||||
bool deleteSourceWhenDeleted;
|
||||
int numberOfSamplesToBuffer;
|
||||
int numberOfSamplesToBuffer, numberOfChannels;
|
||||
AudioSampleBuffer buffer;
|
||||
CriticalSection bufferStartPosLock;
|
||||
int64 volatile bufferValidStart, bufferValidEnd, nextPlayPos;
|
||||
|
|
@ -43908,6 +43850,9 @@ public:
|
|||
|
||||
This stores the current device, its samplerate, block size, etc, and
|
||||
can be restored later with initialise().
|
||||
|
||||
Note that this can return a null pointer if no settings have been explicitly changed
|
||||
(i.e. if the device manager has just been left in its default state).
|
||||
*/
|
||||
XmlElement* createStateXml() const;
|
||||
|
||||
|
|
@ -47730,7 +47675,7 @@ private:
|
|||
|
||||
ReferenceCountedArray <Node> nodes;
|
||||
OwnedArray <Connection> connections;
|
||||
int lastNodeId;
|
||||
uint32 lastNodeId;
|
||||
AudioSampleBuffer renderingBuffers;
|
||||
OwnedArray <MidiBuffer> midiBuffers;
|
||||
|
||||
|
|
@ -57819,22 +57764,24 @@ private:
|
|||
|
||||
@code
|
||||
{
|
||||
WildcardFileFilter wildcardFilter ("*.foo", "Foo files");
|
||||
WildcardFileFilter wildcardFilter ("*.foo", String::empty, "Foo files");
|
||||
|
||||
FileBrowserComponent browser (FileBrowserComponent::loadFileMode,
|
||||
FileBrowserComponent browser (FileBrowserComponent::canSelectFiles,
|
||||
File::nonexistent,
|
||||
&wildcardFilter,
|
||||
0);
|
||||
nullptr);
|
||||
|
||||
FileChooserDialogBox dialogBox ("Open some kind of file",
|
||||
"Please choose some kind of file that you want to open...",
|
||||
browser,
|
||||
getLookAndFeel().alertWindowBackground);
|
||||
false,
|
||||
Colours::lightgrey);
|
||||
|
||||
if (dialogBox.show())
|
||||
{
|
||||
File selectedFile = browser.getCurrentFile();
|
||||
...
|
||||
File selectedFile = browser.getSelectedFile (0);
|
||||
|
||||
...etc..
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
|
@ -58447,6 +58394,10 @@ public:
|
|||
patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav
|
||||
or .aiff.
|
||||
|
||||
Passing an empty string as a pattern will fail to match anything, so by leaving
|
||||
either the file or directory pattern parameter empty means you can control
|
||||
whether files or directories are found.
|
||||
|
||||
The description is a name to show the user in a list of possible patterns, so
|
||||
for the wav/aiff example, your description might be "audio files".
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ void AudioTransportSource::setSource (PositionableAudioSource* const newSource,
|
|||
|
||||
if (readAheadBufferSize_ > 0)
|
||||
newPositionableSource = newBufferingSource
|
||||
= new BufferingAudioSource (newPositionableSource, false, readAheadBufferSize_);
|
||||
= new BufferingAudioSource (newPositionableSource, false, readAheadBufferSize_, maxNumChannels);
|
||||
|
||||
newPositionableSource->setNextReadPosition (0);
|
||||
|
||||
|
|
|
|||
|
|
@ -121,11 +121,13 @@ juce_ImplementSingleton (SharedBufferingAudioSourceThread)
|
|||
//==============================================================================
|
||||
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* source_,
|
||||
const bool deleteSourceWhenDeleted_,
|
||||
int numberOfSamplesToBuffer_)
|
||||
const int numberOfSamplesToBuffer_,
|
||||
const int numberOfChannels_)
|
||||
: source (source_),
|
||||
deleteSourceWhenDeleted (deleteSourceWhenDeleted_),
|
||||
numberOfSamplesToBuffer (jmax (1024, numberOfSamplesToBuffer_)),
|
||||
buffer (2, 0),
|
||||
numberOfChannels (numberOfChannels_),
|
||||
buffer (numberOfChannels_, 0),
|
||||
bufferValidStart (0),
|
||||
bufferValidEnd (0),
|
||||
nextPlayPos (0),
|
||||
|
|
@ -155,7 +157,7 @@ void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sa
|
|||
|
||||
sampleRate = sampleRate_;
|
||||
|
||||
buffer.setSize (2, jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer));
|
||||
buffer.setSize (numberOfChannels, jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer));
|
||||
buffer.clear();
|
||||
|
||||
bufferValidStart = 0;
|
||||
|
|
@ -178,7 +180,7 @@ void BufferingAudioSource::releaseResources()
|
|||
if (thread != nullptr)
|
||||
thread->removeSource (this);
|
||||
|
||||
buffer.setSize (2, 0);
|
||||
buffer.setSize (numberOfChannels, 0);
|
||||
source->releaseResources();
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +207,7 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
|
|||
|
||||
if (validStart < validEnd)
|
||||
{
|
||||
for (int chan = jmin (2, info.buffer->getNumChannels()); --chan >= 0;)
|
||||
for (int chan = jmin (numberOfChannels, info.buffer->getNumChannels()); --chan >= 0;)
|
||||
{
|
||||
const int startBufferIndex = (validStart + nextPlayPos) % buffer.getNumSamples();
|
||||
const int endBufferIndex = (validEnd + nextPlayPos) % buffer.getNumSamples();
|
||||
|
|
|
|||
|
|
@ -51,10 +51,12 @@ public:
|
|||
@param deleteSourceWhenDeleted if true, then the input source object will
|
||||
be deleted when this object is deleted
|
||||
@param numberOfSamplesToBuffer the size of buffer to use for reading ahead
|
||||
@param numberOfChannels the number of channels that will be played
|
||||
*/
|
||||
BufferingAudioSource (PositionableAudioSource* source,
|
||||
bool deleteSourceWhenDeleted,
|
||||
int numberOfSamplesToBuffer);
|
||||
int numberOfSamplesToBuffer,
|
||||
int numberOfChannels = 2);
|
||||
|
||||
/** Destructor.
|
||||
|
||||
|
|
@ -90,7 +92,7 @@ private:
|
|||
//==============================================================================
|
||||
PositionableAudioSource* source;
|
||||
bool deleteSourceWhenDeleted;
|
||||
int numberOfSamplesToBuffer;
|
||||
int numberOfSamplesToBuffer, numberOfChannels;
|
||||
AudioSampleBuffer buffer;
|
||||
CriticalSection bufferStartPosLock;
|
||||
int64 volatile bufferValidStart, bufferValidEnd, nextPlayPos;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,9 @@ public:
|
|||
|
||||
This stores the current device, its samplerate, block size, etc, and
|
||||
can be restored later with initialise().
|
||||
|
||||
Note that this can return a null pointer if no settings have been explicitly changed
|
||||
(i.e. if the device manager has just been left in its default state).
|
||||
*/
|
||||
XmlElement* createStateXml() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public:
|
|||
{
|
||||
const ScopedLockType sl (getLock());
|
||||
|
||||
for (const HashEntry* entry = slots [generateHashFor (keyToLookFor)]; entry != nullptr; entry = entry->nextEntry)
|
||||
for (const HashEntry* entry = slots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry)
|
||||
if (entry->key == keyToLookFor)
|
||||
return entry->value;
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ public:
|
|||
{
|
||||
const ScopedLockType sl (getLock());
|
||||
|
||||
for (const HashEntry* entry = slots [generateHashFor (keyToLookFor)]; entry != nullptr; entry = entry->nextEntry)
|
||||
for (const HashEntry* entry = slots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry)
|
||||
if (entry->key == keyToLookFor)
|
||||
return true;
|
||||
|
||||
|
|
@ -203,25 +203,22 @@ public:
|
|||
const ScopedLockType sl (getLock());
|
||||
const int hashIndex = generateHashFor (newKey);
|
||||
|
||||
if (isPositiveAndBelow (hashIndex, getNumSlots()))
|
||||
HashEntry* const firstEntry = slots.getUnchecked (hashIndex);
|
||||
|
||||
for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry)
|
||||
{
|
||||
HashEntry* const firstEntry = slots.getUnchecked (hashIndex);
|
||||
|
||||
for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry)
|
||||
if (entry->key == newKey)
|
||||
{
|
||||
if (entry->key == newKey)
|
||||
{
|
||||
entry->value = newValue;
|
||||
return;
|
||||
}
|
||||
entry->value = newValue;
|
||||
return;
|
||||
}
|
||||
|
||||
slots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry));
|
||||
++totalNumItems;
|
||||
|
||||
if (totalNumItems > (getNumSlots() * 3) / 2)
|
||||
remapTable (getNumSlots() * 2);
|
||||
}
|
||||
|
||||
slots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry));
|
||||
++totalNumItems;
|
||||
|
||||
if (totalNumItems > (getNumSlots() * 3) / 2)
|
||||
remapTable (getNumSlots() * 2);
|
||||
}
|
||||
|
||||
/** Removes an item with the given key. */
|
||||
|
|
@ -229,7 +226,7 @@ public:
|
|||
{
|
||||
const ScopedLockType sl (getLock());
|
||||
const int hashIndex = generateHashFor (keyToRemove);
|
||||
HashEntry* entry = slots [hashIndex];
|
||||
HashEntry* entry = slots.getUnchecked (hashIndex);
|
||||
HashEntry* previous = nullptr;
|
||||
|
||||
while (entry != nullptr)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 53
|
||||
#define JUCE_BUILDNUMBER 85
|
||||
#define JUCE_BUILDNUMBER 86
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -276,7 +276,9 @@ uint32 Time::getMillisecondCounter() noexcept
|
|||
|
||||
uint32 Time::getApproximateMillisecondCounter() noexcept
|
||||
{
|
||||
jassert (TimeHelpers::lastMSCounterValue != 0);
|
||||
if (TimeHelpers::lastMSCounterValue == 0)
|
||||
getMillisecondCounter();
|
||||
|
||||
return TimeHelpers::lastMSCounterValue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -298,6 +298,10 @@ public:
|
|||
system clock. It should be accurate to within a few millisecs, depending on platform,
|
||||
hardware, etc.
|
||||
|
||||
Being a 32-bit return value, it will of course wrap back to 0 after 2^32 seconds of
|
||||
uptime, so be careful to take that into account. If you need a 64-bit time, you can
|
||||
use currentTimeMillis() instead.
|
||||
|
||||
@see getApproximateMillisecondCounter
|
||||
*/
|
||||
static uint32 getMillisecondCounter() noexcept;
|
||||
|
|
|
|||
|
|
@ -72,13 +72,14 @@ public:
|
|||
{
|
||||
const uint32 now = Time::getMillisecondCounter();
|
||||
|
||||
if (now <= lastTime)
|
||||
if (now == lastTime)
|
||||
{
|
||||
wait (2);
|
||||
wait (1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const int elapsed = now - lastTime;
|
||||
const int elapsed = now >= lastTime ? (now - lastTime)
|
||||
: (std::numeric_limits<uint32>::max() - (lastTime - now));
|
||||
lastTime = now;
|
||||
|
||||
const int timeUntilFirstTimer = getTimeUntilFirstTimer (elapsed);
|
||||
|
|
|
|||
|
|
@ -373,20 +373,22 @@ public:
|
|||
{
|
||||
if (isVisible())
|
||||
{
|
||||
WeakReference<Component> deletionChecker (this);
|
||||
|
||||
activeSubMenu = nullptr;
|
||||
currentChild = nullptr;
|
||||
|
||||
exitModalState (item != nullptr ? item->itemId : 0);
|
||||
|
||||
if (makeInvisible)
|
||||
setVisible (false);
|
||||
|
||||
if (item != nullptr
|
||||
&& item->commandManager != nullptr
|
||||
&& item->itemId != 0)
|
||||
{
|
||||
*managerOfChosenCommand = item->commandManager;
|
||||
}
|
||||
|
||||
exitModalState (item != nullptr ? item->itemId : 0);
|
||||
|
||||
if (makeInvisible && (deletionChecker != nullptr))
|
||||
setVisible (false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,13 @@ inline void deleteAndZero (Type& pointer) { delete poi
|
|||
template <typename Type>
|
||||
inline Type* addBytesToPointer (Type* pointer, int bytes) noexcept { return (Type*) (((char*) pointer) + bytes); }
|
||||
|
||||
/** A handy function which returns the difference between any two pointers, in bytes.
|
||||
The address of the second pointer is subtracted from the first, and the difference in bytes is returned.
|
||||
*/
|
||||
template <typename Type1, typename Type2>
|
||||
inline int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept { return (int) (((const char*) pointer1) - (const char*) pointer2); }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/* In a win32 DLL build, we'll expose some malloc/free functions that live inside the DLL, and use these for
|
||||
allocating all the objects - that way all juce objects in the DLL and in the host will live in the same heap,
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ int64 Time::getHighResolutionTicks() noexcept
|
|||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / (int64) 1000);
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ int64 Time::getHighResolutionTicks() noexcept
|
|||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / (int64) 1000);
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept
|
||||
|
|
|
|||
|
|
@ -274,8 +274,6 @@ public:
|
|||
timerCallback();
|
||||
}
|
||||
|
||||
~ScreenSaverDefeater() {}
|
||||
|
||||
void timerCallback()
|
||||
{
|
||||
if (Process::isForegroundProcess())
|
||||
|
|
|
|||
|
|
@ -190,13 +190,15 @@ public:
|
|||
{
|
||||
mach_timebase_info_data_t timebase;
|
||||
(void) mach_timebase_info (&timebase);
|
||||
highResTimerFrequency = (int64) (1.0e9 * timebase.denom / timebase.numer);
|
||||
highResTimerToMillisecRatio = timebase.numer / (1.0e6 * timebase.denom);
|
||||
highResTimerFrequency = (timebase.denom * (int64) 1000000000) / timebase.numer;
|
||||
numerator = timebase.numer;
|
||||
denominator = timebase.denom * (int64) 1000000;
|
||||
highResTimerToMillisecRatio = numerator / (double) denominator;
|
||||
}
|
||||
|
||||
inline uint32 millisecondsSinceStartup() const noexcept
|
||||
{
|
||||
return (uint32) (mach_absolute_time() * highResTimerToMillisecRatio);
|
||||
return (uint32) ((mach_absolute_time() * numerator) / denominator);
|
||||
}
|
||||
|
||||
inline double getMillisecondCounterHiRes() const noexcept
|
||||
|
|
@ -205,6 +207,9 @@ public:
|
|||
}
|
||||
|
||||
int64 highResTimerFrequency;
|
||||
|
||||
private:
|
||||
int64 numerator, denominator;
|
||||
double highResTimerToMillisecRatio;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ public:
|
|||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
static int copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, int maxBytes) noexcept
|
||||
{
|
||||
int numBytesDone = 0;
|
||||
typename DestCharPointerType::CharType const* const startAddress = dest.getAddress();
|
||||
maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null)
|
||||
|
||||
for (;;)
|
||||
|
|
@ -320,12 +320,12 @@ public:
|
|||
if (c == 0 || maxBytes < 0)
|
||||
break;
|
||||
|
||||
numBytesDone += bytesNeeded;
|
||||
dest.write (c);
|
||||
}
|
||||
|
||||
dest.writeNull();
|
||||
return numBytesDone;
|
||||
|
||||
return getAddressDifference (dest.getAddress(), startAddress);
|
||||
}
|
||||
|
||||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Identifier::Identifier (const String& name_)
|
|||
{
|
||||
/* An Identifier string must be suitable for use as a script variable or XML
|
||||
attribute, so it can only contain this limited set of characters.. */
|
||||
jassert (name_.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name_.isNotEmpty());
|
||||
jassert (isValidIdentifier (name_));
|
||||
}
|
||||
|
||||
Identifier::Identifier (const char* const name_)
|
||||
|
|
@ -66,11 +66,17 @@ Identifier::Identifier (const char* const name_)
|
|||
{
|
||||
/* An Identifier string must be suitable for use as a script variable or XML
|
||||
attribute, so it can only contain this limited set of characters.. */
|
||||
jassert (toString().containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && toString().isNotEmpty());
|
||||
jassert (isValidIdentifier (toString()));
|
||||
}
|
||||
|
||||
Identifier::~Identifier()
|
||||
{
|
||||
}
|
||||
|
||||
bool Identifier::isValidIdentifier (const String& possibleIdentifier) noexcept
|
||||
{
|
||||
return possibleIdentifier.isNotEmpty()
|
||||
&& possibleIdentifier.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -78,6 +78,13 @@ public:
|
|||
/** Returns this identifier's raw string pointer. */
|
||||
operator const String::CharPointerType() const noexcept { return name; }
|
||||
|
||||
/** Checks a given string for characters that might not be valid in an Identifier.
|
||||
Since Identifiers are used as a script variables and XML attributes, they should only contain
|
||||
alphanumeric characters and underscores.
|
||||
*/
|
||||
static bool isValidIdentifier (const String& possibleIdentifier) noexcept;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String::CharPointerType name;
|
||||
|
|
|
|||
|
|
@ -2052,7 +2052,7 @@ struct StringCopier
|
|||
jassert (maxBufferSizeBytes >= 0); // keep this value positive, or no characters will be copied!
|
||||
|
||||
if (buffer == nullptr)
|
||||
return (int) CharPointerType_Dest::getBytesRequiredFor (source);
|
||||
return (int) (CharPointerType_Dest::getBytesRequiredFor (source) + sizeof (typename CharPointerType_Dest::CharType));
|
||||
|
||||
return CharPointerType_Dest (buffer).writeWithDestByteLimit (source, maxBufferSizeBytes);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue