/* The data buffer needs to be loaded by the calling thread if we're in synchronous mode. */
async = (flags & MA_DATA_SOURCE_FLAG_ASYNC) != 0;
/*
The first thing to do is find the insertion point. If it's already loaded it means we can just increment the reference counter and signal the event. Otherwise we
need to do a full load.
*/
result = ma_resource_manager_data_buffer_node_insert_point(pResourceManager, hashedName32, &pInsertPoint);
if (result == MA_ALREADY_EXISTS) {
/* Fast path. The data buffer already exists. We just need to increment the reference counter and signal the event, if any. */
pDataBuffer->pNode = pInsertPoint;
result = ma_resource_manager_data_buffer_node_increment_ref(pResourceManager, pDataBuffer->pNode, NULL);
if (result != MA_SUCCESS) {
return result; /* Should never happen. Failed to increment the reference count. */
}
/*
The existing node may be in the middle of loading. We need to wait for the node to finish
loading before going any further or else we won't be able to initialize the connector. The
alternative to this could be to initialize the connector via the job queue when the data
source is being loaded asynchronously.
*/
if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY && ma_resource_manager_is_threading_enabled(pResourceManager) && async) {
/* Loading asynchronously. */
/* TODO: This needs to be improved so that when loading asynchronously we post a message to the job queue instead of just waiting. */
if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_encoded) {
while (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) {
ma_yield();
}
} else {
while (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) {
ma_yield();
}
}
} else {
/* Not loading asychronously. We need to wait for the sound to be fully decoded so we can initialize a connector. */
while (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) {
if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
/* We're not threading, so process the next job if there are any. */
result = ma_resource_manager_process_next_job(pResourceManager);
if (result == MA_NO_DATA_AVAILABLE || result == MA_JOB_QUIT) {
break;
}
} else {
/* We're threading, so just keep spinning until some other thread finishes decoding of the original sound. */
ma_yield();
}
}
}
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, NULL);
/* It's an unknown length. We need to dynamically expand the buffer as we decode. To start with we allocate space for one page. We'll then double it as we need more space. */
/* We've reached the end. As we were loading we were doubling the size of the buffer each time we needed more memory. Let's try reducing this by doing a final realloc(). */