|  | /*!
	@file		AudioUnitSDK/ComponentBase.cpp
	@copyright	© 2000-2021 Apple Inc. All rights reserved.
*/
// self
#include <AudioUnitSDK/AUUtility.h>
#include <AudioUnitSDK/ComponentBase.h>
// std
#include <mutex>
namespace ausdk {
static OSStatus CB_GetComponentDescription(
	AudioComponentInstance inInstance, AudioComponentDescription* outDesc);
std::recursive_mutex& ComponentBase::InitializationMutex()
{
	__attribute__ ((no_destroy)) static std::recursive_mutex global;
	return global;
}
ComponentBase::ComponentBase(AudioComponentInstance inInstance) : mComponentInstance(inInstance)
{
	(void)GetComponentDescription();
}
void ComponentBase::DoPostConstructor()
{
	PostConstructorInternal();
	PostConstructor();
}
void ComponentBase::DoPreDestructor()
{
	PreDestructor();
	PreDestructorInternal();
}
OSStatus ComponentBase::AP_Open(void* self, AudioComponentInstance compInstance)
{
	OSStatus result = noErr;
	const auto acpi = static_cast<AudioComponentPlugInInstance*>(self);
	try {
		const std::lock_guard guard{ InitializationMutex() };
		auto* const cb =
			static_cast<ComponentBase*>((*acpi->mConstruct)(&acpi->mInstanceStorage, compInstance));
		cb->DoPostConstructor(); // allows base class to do additional initialization
		// once the derived class is fully constructed
		result = noErr;
	}
	AUSDK_Catch(result)
	if (result != noErr) {
		delete acpi; // NOLINT
	}
	return result;
}
OSStatus ComponentBase::AP_Close(void* self)
{
	OSStatus result = noErr;
	try {
		const auto acpi = static_cast<AudioComponentPlugInInstance*>(self);
		if (const auto acImp =
				reinterpret_cast<ComponentBase*>(&acpi->mInstanceStorage)) { // NOLINT
			acImp->DoPreDestructor();
			(*acpi->mDestruct)(&acpi->mInstanceStorage);
			free(self); // NOLINT manual memory management
		}
	}
	AUSDK_Catch(result)
	return result;
}
AudioComponentDescription ComponentBase::GetComponentDescription() const
{
	AudioComponentDescription desc = {};
	if (CB_GetComponentDescription(mComponentInstance, &desc) == noErr) {
		return desc;
	}
	return {};
}
static OSStatus CB_GetComponentDescription(
	AudioComponentInstance inInstance, AudioComponentDescription* outDesc)
{
	const AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
	if (comp != nullptr) {
		return AudioComponentGetDescription(comp, outDesc);
	}
	return kAudio_ParamError;
}
} // namespace ausdk
 |