mirror of
https://github.com/morgan9e/VolumeControl
synced 2026-04-14 00:04:05 +09:00
Initial commit
This commit is contained in:
235
shared/VC_Utils.cpp
Normal file
235
shared/VC_Utils.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
// This file is part of Background Music.
|
||||
//
|
||||
// Background Music is free software: you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation, either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// Background Music is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//
|
||||
// VC_Utils.cpp
|
||||
// SharedSource
|
||||
//
|
||||
// Copyright © 2016, 2017 Kyle Neideck
|
||||
//
|
||||
|
||||
// Self Include
|
||||
#include "VC_Utils.h"
|
||||
|
||||
// Local Includes
|
||||
#include "VC_Types.h"
|
||||
|
||||
// System Includes
|
||||
#include <MacTypes.h>
|
||||
#include <mach/mach_error.h>
|
||||
#include <CoreFoundation/CoreFoundation.h> // For kCFCoreFoundationVersionNumber
|
||||
|
||||
|
||||
#pragma clang assume_nonnull begin
|
||||
|
||||
dispatch_queue_t VCGetDispatchQueue_PriorityUserInteractive()
|
||||
{
|
||||
long queueClass;
|
||||
|
||||
// Compile-time check that QOS_CLASS_USER_INTERACTIVE can be used. It was added in 10.10.
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 // MAC_OS_X_VERSION_10_10
|
||||
// Runtime check for the same.
|
||||
if(floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
queueClass = QOS_CLASS_USER_INTERACTIVE;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Fallback for older versions.
|
||||
queueClass = DISPATCH_QUEUE_PRIORITY_HIGH;
|
||||
}
|
||||
|
||||
return dispatch_get_global_queue(queueClass, 0);
|
||||
}
|
||||
|
||||
namespace VC_Utils
|
||||
{
|
||||
// Forward declarations
|
||||
static OSStatus LogAndSwallowExceptions(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const char* __nullable message,
|
||||
bool expected,
|
||||
const std::function<void(void)>& function);
|
||||
|
||||
#pragma mark Exception utils
|
||||
|
||||
bool LogIfMachError(const char* callerName,
|
||||
const char* errorReturnedBy,
|
||||
mach_error_t error)
|
||||
{
|
||||
if(error != KERN_SUCCESS)
|
||||
{
|
||||
char* errorStr = mach_error_string(error);
|
||||
LogError("%s: %s returned an error (%d): %s\n",
|
||||
callerName,
|
||||
errorReturnedBy,
|
||||
error,
|
||||
errorStr ? errorStr : "Unknown error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ThrowIfMachError(const char* callerName,
|
||||
const char* errorReturnedBy,
|
||||
mach_error_t error)
|
||||
{
|
||||
if(!LogIfMachError(callerName, errorReturnedBy, error))
|
||||
{
|
||||
Throw(CAException(error));
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus LogAndSwallowExceptions(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const std::function<void(void)>& function)
|
||||
{
|
||||
return LogAndSwallowExceptions(fileName, lineNumber, callerName, nullptr, true, function);
|
||||
}
|
||||
|
||||
OSStatus LogAndSwallowExceptions(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const char* __nullable message,
|
||||
const std::function<void(void)>& function)
|
||||
{
|
||||
return LogAndSwallowExceptions(fileName, lineNumber, callerName, message, true, function);
|
||||
}
|
||||
|
||||
void LogException(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const CAException& e)
|
||||
{
|
||||
OSStatus err = e.GetError();
|
||||
const char err4CC[5] = CA4CCToCString(err);
|
||||
|
||||
LogError("%s:%d:%s: CAException, code: '%s' (%d).",
|
||||
(fileName ? fileName : ""),
|
||||
lineNumber,
|
||||
callerName,
|
||||
err4CC,
|
||||
err);
|
||||
}
|
||||
|
||||
void LogUnexpectedException(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName)
|
||||
{
|
||||
LogError("%s:%d:%s: Unknown unexpected exception.",
|
||||
(fileName ? fileName : ""),
|
||||
lineNumber,
|
||||
callerName);
|
||||
}
|
||||
|
||||
OSStatus LogUnexpectedExceptions(const char* callerName,
|
||||
const std::function<void(void)>& function)
|
||||
{
|
||||
return LogUnexpectedExceptions(nullptr, -1, callerName, nullptr, function);
|
||||
}
|
||||
|
||||
OSStatus LogUnexpectedExceptions(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const std::function<void(void)>& function)
|
||||
{
|
||||
return LogUnexpectedExceptions(fileName, lineNumber, callerName, nullptr, function);
|
||||
}
|
||||
|
||||
OSStatus LogUnexpectedExceptions(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const char* __nullable message,
|
||||
const std::function<void(void)>& function)
|
||||
{
|
||||
return LogAndSwallowExceptions(fileName, lineNumber, callerName, message, false, function);
|
||||
}
|
||||
|
||||
#pragma mark Implementation
|
||||
|
||||
static OSStatus LogAndSwallowExceptions(const char* __nullable fileName,
|
||||
int lineNumber,
|
||||
const char* callerName,
|
||||
const char* __nullable message,
|
||||
bool expected,
|
||||
const std::function<void(void)>& function)
|
||||
{
|
||||
try
|
||||
{
|
||||
function();
|
||||
}
|
||||
catch(const CAException& e)
|
||||
{
|
||||
// TODO: Can/should we log a stack trace somewhere? (If so, also in the following catch
|
||||
// block.)
|
||||
// TODO: Log a warning instead of an error for expected exceptions?
|
||||
OSStatus err = e.GetError();
|
||||
const char err4CC[5] = CA4CCToCString(err);
|
||||
|
||||
LogError("%s:%d:%s: %sCAException, code: '%s' (%d). %s%s %s %s ",
|
||||
(fileName ? fileName : ""),
|
||||
lineNumber,
|
||||
callerName,
|
||||
(expected ? "" : "Unexpected "),
|
||||
err4CC,
|
||||
err,
|
||||
(message ? message : ""),
|
||||
(message ? "." : ""),
|
||||
(expected ? "If you think this might be a bug:"
|
||||
: "Feel free to report this at"),
|
||||
"https://github.com/kyleneideck/BackgroundMusic/issues");
|
||||
|
||||
#if VC_StopDebuggerOnLoggedExceptions || VC_StopDebuggerOnLoggedUnexpectedExceptions
|
||||
#if !VC_StopDebuggerOnLoggedExceptions
|
||||
if(!expected)
|
||||
#endif
|
||||
{
|
||||
VCAssert(false, "CAException");
|
||||
}
|
||||
#endif
|
||||
return e.GetError();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LogError("%s:%d:%s: %s exception. %s%s %s %s",
|
||||
(fileName ? fileName : ""),
|
||||
lineNumber,
|
||||
callerName,
|
||||
(expected ? "Unknown" : "Unexpected unknown"),
|
||||
(message ? message : ""),
|
||||
(message ? "." : ""),
|
||||
(expected ? "If you think this might be a bug:"
|
||||
: "Feel free to report this at"),
|
||||
"https://github.com/kyleneideck/BackgroundMusic/issues");
|
||||
|
||||
#if VC_StopDebuggerOnLoggedExceptions || VC_StopDebuggerOnLoggedUnexpectedExceptions
|
||||
VCAssert(false, "Unknown exception");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
Reference in New Issue
Block a user