summaryrefslogtreecommitdiff
path: root/scene/resources/resource_format_text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/resource_format_text.cpp')
-rw-r--r--scene/resources/resource_format_text.cpp108
1 files changed, 96 insertions, 12 deletions
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index e838d4a685..e9f90fc85f 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -445,6 +445,11 @@ Error ResourceInteractiveLoaderText::poll() {
} else {
resource_cache.push_back(res);
+#ifdef TOOLS_ENABLED
+ //remember ID for saving
+ res->set_id_for_path(local_path,index);
+#endif
+
}
ExtResource er;
@@ -1355,13 +1360,15 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) {
if (external_resources.has(res)) {
- return "ExtResource( " + itos(external_resources[res] + 1) + " )";
+ return "ExtResource( " + itos(external_resources[res]) + " )";
} else {
if (internal_resources.has(res)) {
return "SubResource( " + itos(internal_resources[res]) + " )";
} else if (res->get_path().length() && res->get_path().find("::") == -1) {
-
+ if (res->get_path() == local_path) { //circular reference attempt
+ return "null";
+ }
//external resource
String path = relative_paths ? local_path.path_to_file(res->get_path()) : res->get_path();
return "Resource( \"" + path + "\" )";
@@ -1386,6 +1393,10 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
return;
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
+ if (res->get_path() == local_path) {
+ ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
+ return;
+ }
int index = external_resources.size();
external_resources[res] = index;
return;
@@ -1408,7 +1419,20 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
if (pi.usage & PROPERTY_USAGE_STORAGE) {
Variant v = res->get(I->get().name);
- _find_resources(v);
+
+ if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
+ RES sres = v;
+ if (sres.is_valid()) {
+ NonPersistentKey npk;
+ npk.base = res;
+ npk.property = pi.name;
+ non_persistent_map[npk] = sres;
+ resource_set.insert(sres);
+ saved_resources.push_back(sres);
+ }
+ } else {
+ _find_resources(v);
+ }
}
I = I->next();
@@ -1440,7 +1464,8 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
_find_resources(v);
}
} break;
- default: {}
+ default: {
+ }
}
}
@@ -1519,18 +1544,65 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_line("]\n"); //one empty line
}
- Vector<RES> sorted_er;
- sorted_er.resize(external_resources.size());
+ {
+
+
+
+ }
+#ifdef TOOLS_ENABLED
+ //keep order from cached ids
+ Set<int> cached_ids_found;
+ for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
+ int cached_id = E->key()->get_id_for_path(local_path);
+ if (cached_id < 0 || cached_ids_found.has(cached_id)) {
+ E->get() = -1; //reset
+ } else {
+ E->get() = cached_id;
+ cached_ids_found.insert(cached_id);
+ }
+ }
+ //create IDs for non cached resources
for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
+ if (cached_ids_found.has(E->get())) { //already cached, go on
+ continue;
+ }
+
+ int attempt = 1; //start from one, more readable format
+ while(cached_ids_found.has(attempt)) {
+ attempt++;
+ }
- sorted_er.write[E->get()] = E->key();
+ cached_ids_found.insert(attempt);
+ E->get() = attempt;
+ //update also in resource
+ Ref<Resource> res = E->key();
+ res->set_id_for_path(local_path,attempt);
+ }
+#else
+ //make sure to start from one, as it makes format more readable
+ for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
+ E->get() = E->get() + 1;
}
+#endif
+
+ Vector<ResourceSort> sorted_er;
+
+ for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
+
+ ResourceSort rs;
+ rs.resource = E->key();
+ rs.index = E->get();
+ sorted_er.push_back(rs);
+ }
+
+ sorted_er.sort();
+
for (int i = 0; i < sorted_er.size(); i++) {
- String p = sorted_er[i]->get_path();
+ String p = sorted_er[i].resource->get_path();
- f->store_string("[ext_resource path=\"" + p + "\" type=\"" + sorted_er[i]->get_save_class() + "\" id=" + itos(i + 1) + "]\n"); //bundled
+ f->store_string("[ext_resource path=\"" + p + "\" type=\"" + sorted_er[i].resource->get_save_class() + "\" id=" + itos(sorted_er[i].index) + "]\n"); //bundled
}
if (external_resources.size())
@@ -1600,7 +1672,17 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
if (PE->get().usage & PROPERTY_USAGE_STORAGE) {
String name = PE->get().name;
- Variant value = res->get(name);
+ Variant value;
+ if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
+ NonPersistentKey npk;
+ npk.base = res;
+ npk.property = name;
+ if (non_persistent_map.has(npk)) {
+ value = non_persistent_map[npk];
+ }
+ } else {
+ value = res->get(name);
+ }
Variant default_value = ClassDB::class_get_default_property_value(res->get_class(), name);
if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) {
@@ -1616,7 +1698,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
}
- f->store_string("\n");
+ if (E->next())
+ f->store_line(String());
}
if (packed_scene.is_valid()) {
@@ -1685,7 +1768,8 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(_valprop(String(state->get_node_property_name(i, j))) + " = " + vars + "\n");
}
- f->store_line(String());
+ if (i < state->get_node_count() - 1)
+ f->store_line(String());
}
for (int i = 0; i < state->get_connection_count(); i++) {