Quellcode durchsuchen

tools: all objects must have a type

Daniele Bartolini vor 4 Jahren
Ursprung
Commit
a7d0a6cafc
3 geänderte Dateien mit 52 neuen und 32 gelöschten Zeilen
  1. 50 30
      tools/core/database.vala
  2. 1 1
      tools/level_editor/level.vala
  3. 1 1
      tools/level_editor/project.vala

+ 50 - 30
tools/core/database.vala

@@ -9,7 +9,7 @@ namespace Crown
 {
 public class Database
 {
-	private static bool _debug = false;
+	private static bool _debug = true;
 	private static bool _debug_getters = false;
 
 	private enum Action
@@ -357,10 +357,19 @@ public class Database
 	}
 
 	// See: load_more_from_path().
-	public int load_more_from_file(ref Guid object_id, FileStream? fs, string resource_path)
+	public int load_more_from_file(out Guid object_id, FileStream? fs, string resource_path)
 	{
 		Hashtable json = SJSON.load_from_file(fs);
-		object_id = decode(json);
+
+		if (json.has_key("id"))
+			object_id = Guid.parse((string)json["id"]);
+		else
+			object_id = Guid.new_guid();
+
+		create_internal(0, object_id);
+		set_object_type(object_id, resource_type(resource_path));
+
+		decode_object(object_id, "", json);
 
 		// Create a mapping between the path and the object it has been loaded into.
 		set_property_internal(0, GUID_ZERO, resource_path, object_id);
@@ -374,27 +383,29 @@ public class Database
 	// database to refer to the object that has been loaded. This is useful when
 	// you do not have the object ID but only its path, as it is often the case
 	// since resources use paths and not IDs to reference each other.
-	public int load_more_from_path(ref Guid object_id, string path, string resource_path)
+	public int load_more_from_path(out Guid object_id, string path, string resource_path)
 	{
+		object_id = GUID_ZERO;
+
 		FileStream fs = FileStream.open(path, "rb");
 		if (fs == null)
 			return 1;
 
-		return load_more_from_file(ref object_id, fs, resource_path);
+		return load_more_from_file(out object_id, fs, resource_path);
 	}
 
 	/// Loads the database with the object stored at @a path.
-	public int load_from_file(ref Guid object_id, FileStream fs, string resource_path)
+	public int load_from_file(out Guid object_id, FileStream fs, string resource_path)
 	{
 		reset();
-		return load_more_from_file(ref object_id, fs, resource_path);
+		return load_more_from_file(out object_id, fs, resource_path);
 	}
 
 	/// Loads the database with the object stored at @a path.
-	public int load_from_path(ref Guid object_id, string path, string resource_path)
+	public int load_from_path(out Guid object_id, string path, string resource_path)
 	{
 		reset();
-		return load_more_from_path(ref object_id, path, resource_path);
+		return load_more_from_path(out object_id, path, resource_path);
 	}
 
 	/// Encodes the object @a id into SJSON object.
@@ -445,25 +456,19 @@ public class Database
 		return "<invalid>";
 	}
 
-	// Decodes the @a json data inside the database object @a id.
-	public Guid decode(Hashtable json)
-	{
-		Guid id;
-		if (json.has_key("id"))
-			id = Guid.parse((string)json["id"]);
-		else
-			id = Guid.new_guid();
-
-		create_internal(0, id);
-		decode_object(id, "", json);
-		return id;
-	}
-
 	private void decode_object(Guid id, string db_key, Hashtable json)
 	{
 		string old_db = db_key;
 		string k = db_key;
 
+		if (k == "" && json.has_key("type"))
+		{
+			// The "type" key defines object type only if it appears
+			// in the root of a JSON object (k == "").
+			if (!has_property(id, "type"))
+				set_object_type(id, (string)json["type"]);
+		}
+
 		string[] keys = json.keys.to_array();
 		foreach (string key in keys)
 		{
@@ -496,18 +501,18 @@ public class Database
 		}
 	}
 
-	private void decode_set(Guid id, string key, ArrayList<Value?> json)
+	private void decode_set(Guid owner_id, string key, ArrayList<Value?> json)
 	{
 		// Set should be created even if it is empty.
-		create_empty_set(0, id, key);
+		create_empty_set(0, owner_id, key);
 
 		for (int i = 0; i < json.size; ++i)
 		{
 			Hashtable obj = (Hashtable)json[i];
-			Guid item_id = Guid.parse((string)obj["id"]);
-			create_internal(0, item_id);
-			decode_object(item_id, "", obj);
-			add_to_set_internal(0, id, key, item_id);
+			Guid obj_id = Guid.parse((string)obj["id"]);
+			create_internal(0, obj_id);
+			decode_object(obj_id, "", obj);
+			add_to_set_internal(0, owner_id, key, obj_id);
 		}
 	}
 
@@ -725,7 +730,22 @@ public class Database
 		((HashSet<Guid?>)ob[key]).remove(item_id);
 
 		_distance_from_last_sync += dir;
-		key_changed(id, key);
+	}
+
+	public string object_type(Guid id)
+	{
+		assert(has_object(id));
+		return (string)get_data(id)["type"];
+	}
+
+	// Sets the @a type of the object @a id.
+	// This is called automatically when loading data or when new objects are created via create().
+	// It can occasionally be called manually after loading legacy data with no type information
+	// stored inside objects.
+	public void set_object_type(Guid id, string type)
+	{
+		assert(has_object(id));
+		get_data(id)["type"] = type;
 	}
 
 	public void create(Guid id)

+ 1 - 1
tools/level_editor/level.vala

@@ -72,7 +72,7 @@ public class Level
 			return 1;
 
 		reset();
-		int ret = _db.load_from_file(ref _id, fs, resource_path);
+		int ret = _db.load_from_file(out _id, fs, resource_path);
 		if (ret != 0)
 			return ret;
 

+ 1 - 1
tools/level_editor/project.vala

@@ -107,7 +107,7 @@ public class Project
 		string path = resource_path_to_absolute_path(resource_path);
 
 		Guid prefab_id = GUID_ZERO;
-		if (_database.load_more_from_path(ref prefab_id, path, resource_path) != 0)
+		if (_database.load_more_from_path(out prefab_id, path, resource_path) != 0)
 			return; // Caller can query the database to check for error.
 		assert(prefab_id != GUID_ZERO);