| 76 | } |
| 77 | |
| 78 | s32 ResourceLoader::run() |
| 79 | { |
| 80 | while (1) { |
| 81 | _mutex.lock(); |
| 82 | while (!_exit.load() && _requests.empty()) |
| 83 | _requests_condition.wait(_mutex); |
| 84 | |
| 85 | _mutex.unlock(); |
| 86 | if (_exit.load()) |
| 87 | break; |
| 88 | |
| 89 | ResourceRequest rr; |
| 90 | while (!_exit.load() && _requests.pop(rr)) { |
| 91 | ResourceId res_id = resource_id(rr.type, rr.name); |
| 92 | logd(RESOURCE_LOADER, "Load " RESOURCE_ID_FMT, res_id._id); |
| 93 | |
| 94 | TempAllocator128 ta; |
| 95 | DynamicString path(ta); |
| 96 | destination_path(path, res_id); |
| 97 | |
| 98 | if (_is_bundle) { |
| 99 | if (rr.type == RESOURCE_TYPE_PACKAGE || rr.type == RESOURCE_TYPE_CONFIG) { |
| 100 | File *file = _data_filesystem.open(path.c_str(), FileOpenMode::READ); |
| 101 | CE_ASSERT(file->is_open(), "Cannot load " RESOURCE_ID_FMT, res_id._id); |
| 102 | |
| 103 | // Load the resource. |
| 104 | rr.data = rr.load_function(*file, *rr.allocator); |
| 105 | |
| 106 | _data_filesystem.close(*file); |
| 107 | } else { |
| 108 | const PackageResource *pkg = rr.package_resource; |
| 109 | CE_ASSERT(pkg != NULL, "Missing package for bundled resource: " RESOURCE_ID_FMT, res_id._id); |
| 110 | |
| 111 | // Find the resource inside the package. |
| 112 | for (u32 ii = 0; ii < pkg->num_resources; ++ii) { |
| 113 | const ResourceOffset *offt = package_resource::resource_offset(pkg, ii); |
| 114 | if (offt->type == rr.type && offt->name == rr.name) { |
| 115 | const void *resource_data = package_resource::data(pkg) + offt->offset; |
| 116 | |
| 117 | // Load the resource. |
| 118 | FileMemory fm(resource_data, offt->size); |
| 119 | rr.data = rr.load_function(fm, *rr.allocator); |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | } else { |
| 125 | File *file = _data_filesystem.open(path.c_str(), FileOpenMode::READ); |
| 126 | if (!file->is_open()) { |
| 127 | logw(RESOURCE_LOADER, "Cannot load resource: " RESOURCE_ID_FMT ". Falling back...", res_id._id); |
| 128 | |
| 129 | StringId64 fallback_name; |
| 130 | fallback_name = hash_map::get(_fallback, rr.type, fallback_name); |
| 131 | CE_ENSURE(fallback_name._id != 0); |
| 132 | |
| 133 | res_id = resource_id(rr.type, fallback_name); |
| 134 | destination_path(path, res_id); |
| 135 |
no test coverage detected