| 459 | std::vector<Shared<Resource>> resources; |
| 460 | resources.emplace_back(Valdi::makeShared<Resource>(ResourceId(bundleName, filePathWithinBundle), resource)); |
| 461 | updateResources(resources); |
| 462 | } |
| 463 | |
| 464 | void Runtime::updateResources(const std::vector<Shared<Resource>>& resources) { |
| 465 | runWithExclusiveJsThreadLock([this, resources]() { |
| 466 | snap::utils::time::StopWatch sw; |
| 467 | sw.start(); |
| 468 | VALDI_INFO(*_logger, "Hot reloading {} resources", resources.size()); |
| 469 | |
| 470 | if (Valdi::traceReloaderPerformance) { |
| 471 | VALDI_INFO(*_logger, "Runtime::updateResources started"); |
| 472 | } |
| 473 | |
| 474 | std::vector<ResourceId> unloadedJsFiles; |
| 475 | |
| 476 | for (const auto& resource : resources) { |
| 477 | const auto& bundleName = resource->resourceId.bundleName; |
| 478 | const auto& filePathWithinBundle = resource->resourceId.resourcePath; |
| 479 | |
| 480 | if (Valdi::traceReloaderPerformance) { |
| 481 | VALDI_INFO(*_logger, "Updating resource {}:{} at {}", bundleName, filePathWithinBundle, sw.elapsed()); |
| 482 | } |
| 483 | |
| 484 | auto bundle = getResourceManager().getBundle(bundleName); |
| 485 | |
| 486 | if (filePathWithinBundle.hasSuffix(".valdicss")) { |
| 487 | auto document = CSSDocument::parse( |
| 488 | resource->resourceId, resource->data.data(), resource->data.size(), _attributeIds); |
| 489 | if (!document) { |
| 490 | VALDI_ERROR(*_logger, |
| 491 | "Unable to parse CSS document '{}' in bundle '{}' for reloading: {}", |
| 492 | filePathWithinBundle, |
| 493 | bundleName, |
| 494 | document.error()); |
| 495 | continue; |
| 496 | } |
| 497 | bundle->setCSSDocument(filePathWithinBundle, document.value()); |
| 498 | } else if (filePathWithinBundle.hasSuffix(".js")) { |
| 499 | auto jsPath = filePathWithinBundle.substring(0, filePathWithinBundle.length() - 3); |
| 500 | |
| 501 | bundle->setJs(jsPath, JavaScriptFile(resource->data, StringBox::emptyString())); |
| 502 | |
| 503 | unloadedJsFiles.emplace_back(bundleName, jsPath); |
| 504 | |
| 505 | } else if (filePathWithinBundle.hasSuffix(".assetcatalog")) { |
| 506 | auto assetCatalogPath = filePathWithinBundle.substring(0, filePathWithinBundle.length() - 13); |
| 507 | |
| 508 | auto assetCatalogResult = AssetCatalog::parse(resource->data.data(), resource->data.size()); |
| 509 | |
| 510 | if (!assetCatalogResult) { |
| 511 | VALDI_ERROR(*_logger, |
| 512 | "Failed to parse AssetCatalog '{}' in bundle '{}': {}", |
| 513 | filePathWithinBundle, |
| 514 | bundleName, |
| 515 | assetCatalogResult.error()); |
| 516 | continue; |
| 517 | } |
| 518 | |