void Scene::PreloadResources(File* file, bool isSceneFile) { ResourceCache* cache = GetSubsystem<ResourceCache>(); // Read node ID (not needed) /*unsigned nodeID = */file->ReadUInt(); // Read Node or Scene attributes; these do not include any resources const Vector<AttributeInfo>* attributes = context_->GetAttributes(isSceneFile ? Scene::GetTypeStatic() : Node::GetTypeStatic()); assert(attributes); for (unsigned i = 0; i < attributes->Size(); ++i) { const AttributeInfo& attr = attributes->At(i); if (!(attr.mode_ & AM_FILE)) continue; Variant varValue = file->ReadVariant(attr.type_); } // Read component attributes unsigned numComponents = file->ReadVLE(); for (unsigned i = 0; i < numComponents; ++i) { VectorBuffer compBuffer(*file, file->ReadVLE()); StringHash compType = compBuffer.ReadStringHash(); // Read component ID (not needed) /*unsigned compID = */compBuffer.ReadUInt(); attributes = context_->GetAttributes(compType); if (attributes) { for (unsigned j = 0; j < attributes->Size(); ++j) { const AttributeInfo& attr = attributes->At(j); if (!(attr.mode_ & AM_FILE)) continue; Variant varValue = compBuffer.ReadVariant(attr.type_); if (attr.type_ == VAR_RESOURCEREF) { const ResourceRef& ref = varValue.GetResourceRef(); // Sanitate resource name beforehand so that when we get the background load event, the name matches exactly String name = cache->SanitateResourceName(ref.name_); bool success = cache->BackgroundLoadResource(ref.type_, name); if (success) { ++asyncProgress_.totalResources_; asyncProgress_.resources_.Insert(StringHash(name)); } } else if (attr.type_ == VAR_RESOURCEREFLIST) { const ResourceRefList& refList = varValue.GetResourceRefList(); for (unsigned k = 0; k < refList.names_.Size(); ++k) { String name = cache->SanitateResourceName(refList.names_[k]); bool success = cache->BackgroundLoadResource(refList.type_, name); if (success) { ++asyncProgress_.totalResources_; asyncProgress_.resources_.Insert(StringHash(name)); } } } } } } // Read child nodes unsigned numChildren = file->ReadVLE(); for (unsigned i = 0; i < numChildren; ++i) PreloadResources(file, false); }
void Scene::PreloadResourcesXML(const XMLElement& element) { ResourceCache* cache = GetSubsystem<ResourceCache>(); // Node or Scene attributes do not include any resources; therefore skip to the components XMLElement compElem = element.GetChild("component"); while (compElem) { String typeName = compElem.GetAttribute("type"); const Vector<AttributeInfo>* attributes = context_->GetAttributes(StringHash(typeName)); if (attributes) { XMLElement attrElem = compElem.GetChild("attribute"); unsigned startIndex = 0; while (attrElem) { String name = attrElem.GetAttribute("name"); unsigned i = startIndex; unsigned attempts = attributes->Size(); while (attempts) { const AttributeInfo& attr = attributes->At(i); if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true)) { if (attr.type_ == VAR_RESOURCEREF) { ResourceRef ref = attrElem.GetVariantValue(attr.type_).GetResourceRef(); String name = cache->SanitateResourceName(ref.name_); bool success = cache->BackgroundLoadResource(ref.type_, name); if (success) { ++asyncProgress_.totalResources_; asyncProgress_.resources_.Insert(StringHash(name)); } } else if (attr.type_ == VAR_RESOURCEREFLIST) { ResourceRefList refList = attrElem.GetVariantValue(attr.type_).GetResourceRefList(); for (unsigned k = 0; k < refList.names_.Size(); ++k) { String name = cache->SanitateResourceName(refList.names_[k]); bool success = cache->BackgroundLoadResource(refList.type_, name); if (success) { ++asyncProgress_.totalResources_; asyncProgress_.resources_.Insert(StringHash(name)); } } } startIndex = (i + 1) % attributes->Size(); break; } else { i = (i + 1) % attributes->Size(); --attempts; } } attrElem = attrElem.GetNext("attribute"); } } compElem = compElem.GetNext("component"); } XMLElement childElem = element.GetChild("node"); while (childElem) { PreloadResourcesXML(childElem); childElem = childElem.GetNext("node"); } }
void Scene::PreloadResourcesJSON(const JSONValue& value) { // If not threaded, can not background load resources, so rather load synchronously later when needed #ifdef URHO3D_THREADING ResourceCache* cache = GetSubsystem<ResourceCache>(); // Node or Scene attributes do not include any resources; therefore skip to the components JSONArray componentArray = value.Get("components").GetArray(); for (unsigned i = 0; i < componentArray.Size(); i++) { const JSONValue& compValue = componentArray.At(i); String typeName = compValue.Get("type").GetString(); const Vector<AttributeInfo>* attributes = context_->GetAttributes(StringHash(typeName)); if (attributes) { JSONArray attributesArray = compValue.Get("attributes").GetArray(); unsigned startIndex = 0; for (unsigned j = 0; j < attributesArray.Size(); j++) { const JSONValue& attrVal = attributesArray.At(j); String name = attrVal.Get("name").GetString(); unsigned i = startIndex; unsigned attempts = attributes->Size(); while (attempts) { const AttributeInfo& attr = attributes->At(i); if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true)) { if (attr.type_ == VAR_RESOURCEREF) { ResourceRef ref = attrVal.Get("value").GetVariantValue(attr.type_).GetResourceRef(); String name = cache->SanitateResourceName(ref.name_); bool success = cache->BackgroundLoadResource(ref.type_, name); if (success) { ++asyncProgress_.totalResources_; asyncProgress_.resources_.Insert(StringHash(name)); } } else if (attr.type_ == VAR_RESOURCEREFLIST) { ResourceRefList refList = attrVal.Get("value").GetVariantValue(attr.type_).GetResourceRefList(); for (unsigned k = 0; k < refList.names_.Size(); ++k) { String name = cache->SanitateResourceName(refList.names_[k]); bool success = cache->BackgroundLoadResource(refList.type_, name); if (success) { ++asyncProgress_.totalResources_; asyncProgress_.resources_.Insert(StringHash(name)); } } } startIndex = (i + 1) % attributes->Size(); break; } else { i = (i + 1) % attributes->Size(); --attempts; } } } } } JSONArray childrenArray = value.Get("children").GetArray(); for (unsigned i = 0; i < childrenArray.Size(); i++) { const JSONValue& childVal = childrenArray.At(i); PreloadResourcesJSON(childVal); } #endif }