diff --git a/WickedEngine/wiECS.h b/WickedEngine/wiECS.h index d9f20d67d..333a2beb5 100644 --- a/WickedEngine/wiECS.h +++ b/WickedEngine/wiECS.h @@ -38,6 +38,7 @@ namespace wi::ecs uint64_t version = 0; // The ComponentLibrary serialization will modify this by the registered component's version number wi::unordered_set resource_registration; // register for resource manager serialization ComponentLibrary* componentlibrary = nullptr; + wi::unordered_map library_versions; ~EntitySerializer() { @@ -50,6 +51,15 @@ namespace wi::ecs { return version; } + uint64_t GetVersion(const std::string& name) const + { + auto it = library_versions.find(name); + if (it != library_versions.end()) + { + return it->second; + } + return 0; + } void RegisterResource(const std::string& resource_name) { @@ -502,6 +512,34 @@ namespace wi::ecs if(archive.IsReadMode()) { bool has_next = false; + size_t begin = archive.GetPos(); + + // First pass, gather component type versions and jump over all data: + // This is so that we can look up other component versions within component serialization if needed + do + { + archive >> has_next; + if (has_next) + { + std::string name; + archive >> name; + uint64_t jump_pos = 0; + archive >> jump_pos; + auto it = entries.find(name); + if (it != entries.end()) + { + archive >> seri.version; + seri.library_versions[name] = seri.version; + } + archive.Jump(jump_pos); + } + } while (has_next); + + // Jump back to beginning of component library data + archive.Jump(begin); + + // Second pass, read all component data: + // At this point, all existing component type versions are available do { archive >> has_next; @@ -509,8 +547,8 @@ namespace wi::ecs { std::string name; archive >> name; - uint64_t jump_size = 0; - archive >> jump_size; + uint64_t jump_pos = 0; + archive >> jump_pos; auto it = entries.find(name); if(it != entries.end()) { @@ -520,7 +558,7 @@ namespace wi::ecs else { // component manager of this name was not registered, skip serialization by jumping over the data - archive.Jump(jump_size); + archive.Jump(jump_pos); } } } @@ -528,6 +566,12 @@ namespace wi::ecs } else { + // Save all component type versions: + for (auto& it : entries) + { + seri.library_versions[it.first] = it.second.version; + } + // Serialize all component data, at this point component type version lookup is also complete for(auto& it : entries) { archive << true; diff --git a/WickedEngine/wiTerrain.cpp b/WickedEngine/wiTerrain.cpp index 2b9c530f7..55d421821 100644 --- a/WickedEngine/wiTerrain.cpp +++ b/WickedEngine/wiTerrain.cpp @@ -1233,7 +1233,7 @@ namespace wi::terrain { GraphicsDevice* device = GetDevice(); - if (!chunk_data.heightmap.IsValid()) + if (!chunk_data.heightmap.IsValid() && !chunk_data.heightmap_data.empty()) { TextureDesc desc; desc.width = (uint32_t)chunk_width; @@ -1901,9 +1901,9 @@ namespace wi::terrain // Note: separate component types serialized within terrain must NOT use the version of the terrain, but their own! ComponentLibrary& library = *seri.componentlibrary; const uint64_t terrain_version = seri.GetVersion(); - const uint64_t grass_version = library.GetVersion("wi::scene::Scene::hairs"); - const uint64_t material_version = library.GetVersion("wi::scene::Scene::materials"); - const uint64_t weather_version = library.GetVersion("wi::scene::Scene::weathers"); + const uint64_t grass_version = seri.GetVersion("wi::scene::Scene::hairs"); + const uint64_t material_version = seri.GetVersion("wi::scene::Scene::materials"); + const uint64_t weather_version = seri.GetVersion("wi::scene::Scene::weathers"); if (archive.IsReadMode()) { diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 4e5bfb771..24720780f 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 463; + const int revision = 464; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);