#include "assetsettings.h" #include "description_parser.h" #include "packages.h" #include "utils.h" #include "runtime/aio.h" #include "runtime/buffer_manager.h" #include #include #include rt_result rtParseAssetSettings(const char *text, size_t length, const char *file_path, rt_asset_settings *settings) { unsigned int root_list; rt_parse_state state; rt_result res = rtParseDescription(text, length, file_path, &root_list, &state); if (res != RT_SUCCESS) { rtReportError("ASSETC", "Failed to parse asset settings: %s", file_path); return res; } /* Default settings */ settings->package = 0; settings->processing_flags = 0; settings->reprocess_on_dependency_change = false; const rt_parsed_stmt *package_stmt = rtFindStatement(&state, root_list, "package"); if (package_stmt) { if (package_stmt->form != RT_STMT_FORM_VALUE) { rtReportError("ASSETC", "Expected a package name as the value of 'package' in %s.", file_path); res = RT_UNKNOWN_ERROR; goto out; } settings->package = rtAddPackageFile(package_stmt->value); } const rt_parsed_stmt *flags_stmt = rtFindStatement(&state, root_list, "processing_flags"); if (flags_stmt) { if (flags_stmt->form != RT_STMT_FORM_VALUE) { rtReportError("ASSETC", "Expected a hexadecimal number as the value of 'processing_flags' in %s.", file_path); res = RT_UNKNOWN_ERROR; goto out; } sscanf(flags_stmt->value.start, "%x", &settings->processing_flags); } const rt_parsed_stmt *reprocess_stmt = rtFindStatement(&state, root_list, "reprocess_on_dependency_change"); if (reprocess_stmt) { if (reprocess_stmt->form != RT_STMT_FORM_VALUE) { rtReportError("ASSETC", "Expected either 'true' or 'false' as the value of 'reprocess_on_dependency_change' in %s.", file_path); res = RT_UNKNOWN_ERROR; goto out; } if (rtCompareSpanToString(reprocess_stmt->value, "true") == 0) settings->reprocess_on_dependency_change = true; else if (rtCompareSpanToString(reprocess_stmt->value, "false") == 0) settings->reprocess_on_dependency_change = false; else { rtReportError("ASSETC", "Expected either 'true' or 'false' as the value of " "'reprocess_on_dependency_change' in %s.", file_path); res = RT_UNKNOWN_ERROR; goto out; } } out: rtReleaseParseState(&state); return res; } rt_result rtLoadAssetSettings(const char *asset_path, rt_asset_settings *settings) { size_t path_len = strlen(asset_path); char *as_path = malloc(path_len + 3); if (!as_path) { return RT_UNKNOWN_ERROR; } memcpy(as_path, asset_path, path_len); size_t ext_len = 0; while (ext_len < path_len) { if (as_path[path_len - ext_len] == '.') break; ++ext_len; } strcpy(&as_path[path_len - ext_len], ".as"); size_t as_size = rtGetFileSize(as_path); if (as_size == 0) { rtReportError("ASSETC", "Failed to retrieve size of setting file %s", as_path); free(as_path); return RT_UNKNOWN_ERROR; } void *as_buffer = rtAllocBuffer(as_size); rt_load_batch as_load; as_load.loads[0].file = rtAddFile(as_path); as_load.loads[0].num_bytes = as_size; as_load.loads[0].dest = as_buffer; if (!as_load.loads[0].dest) { rtReportError("ASSETC", "Failed to allocate buffer for setting file %s", as_path); free(as_path); return RT_UNKNOWN_ERROR; } as_load.loads[0].offset = 0; as_load.num_loads = 1; rt_aio_handle as_handle; if (rtSubmitLoadBatch(&as_load, &as_handle) != RT_SUCCESS) { rtReportError("ASSETC", "Failed to submit load of setting file %s", as_path); free(as_path); return RT_UNKNOWN_ERROR; } if (rtWaitForAIOCompletion(as_handle) != RT_AIO_STATE_FINISHED) { rtReportError("ASSETC", "Failed to load setting file %s", as_path); free(as_path); return RT_UNKNOWN_ERROR; } rtReleaseAIO(as_handle); if (rtParseAssetSettings(as_buffer, as_size, as_path, settings) != RT_SUCCESS) { free(as_path); return RT_UNKNOWN_ERROR; } free(as_path); return RT_SUCCESS; }