| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2017-08-05 21:55:37 +07:00
										 |  |  | /*  node_path.cpp                                                        */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-05 09:12:53 -03:00
										 |  |  | #include "node_path.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/print_string.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | void NodePath::_update_hash_cache() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	uint32_t h = data->absolute ? 1 : 0; | 
					
						
							|  |  |  | 	int pc = data->path.size(); | 
					
						
							|  |  |  | 	const StringName *sn = data->path.ptr(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < pc; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		h = h ^ sn[i].hash(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	int spc = data->subpath.size(); | 
					
						
							|  |  |  | 	const StringName *ssn = data->subpath.ptr(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < spc; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		h = h ^ ssn[i].hash(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	data->hash_cache_valid = true; | 
					
						
							|  |  |  | 	data->hash_cache = h; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-19 21:26:12 -03:00
										 |  |  | void NodePath::prepend_period() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (data->path.size() && data->path[0].operator String() != ".") { | 
					
						
							|  |  |  | 		data->path.insert(0, "."); | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 		data->hash_cache_valid = false; | 
					
						
							| 
									
										
										
										
											2016-07-19 21:26:12 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool NodePath::is_absolute() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!data) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return data->absolute; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | int NodePath::get_name_count() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!data) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return data->path.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | StringName NodePath::get_name(int p_idx) const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!data, StringName()); | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, data->path.size(), StringName()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return data->path[p_idx]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int NodePath::get_subname_count() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!data) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return data->subpath.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | StringName NodePath::get_subname(int p_idx) const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!data, StringName()); | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, data->subpath.size(), StringName()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return data->subpath[p_idx]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NodePath::unref() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (data && data->refcount.unref()) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		memdelete(data); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool NodePath::operator==(const NodePath &p_path) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (data == p_path.data) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (!data || !p_path.data) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (data->absolute != p_path.data->absolute) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	int path_size = data->path.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (path_size != p_path.data->path.size()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int subpath_size = data->subpath.size(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	if (subpath_size != p_path.data->subpath.size()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	const StringName *l_path_ptr = data->path.ptr(); | 
					
						
							|  |  |  | 	const StringName *r_path_ptr = p_path.data->path.ptr(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < path_size; i++) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 		if (l_path_ptr[i] != r_path_ptr[i]) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	const StringName *l_subpath_ptr = data->subpath.ptr(); | 
					
						
							|  |  |  | 	const StringName *r_subpath_ptr = p_path.data->subpath.ptr(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < subpath_size; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 		if (l_subpath_ptr[i] != r_subpath_ptr[i]) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool NodePath::operator!=(const NodePath &p_path) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return (!(*this == p_path)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NodePath::operator=(const NodePath &p_path) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (this == &p_path) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	unref(); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (p_path.data && p_path.data->refcount.ref()) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		data = p_path.data; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NodePath::operator String() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!data) | 
					
						
							|  |  |  | 		return String(); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	String ret; | 
					
						
							|  |  |  | 	if (data->absolute) | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ret = "/"; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < data->path.size(); i++) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (i > 0) | 
					
						
							|  |  |  | 			ret += "/"; | 
					
						
							|  |  |  | 		ret += data->path[i].operator String(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < data->subpath.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ret += ":" + data->subpath[i].operator String(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | NodePath::NodePath(const NodePath &p_path) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_path.data && p_path.data->refcount.ref()) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		data = p_path.data; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Vector<StringName> NodePath::get_names() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (data) | 
					
						
							|  |  |  | 		return data->path; | 
					
						
							|  |  |  | 	return Vector<StringName>(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Vector<StringName> NodePath::get_subnames() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (data) | 
					
						
							|  |  |  | 		return data->subpath; | 
					
						
							|  |  |  | 	return Vector<StringName>(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | StringName NodePath::get_concatenated_subnames() const { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!data, StringName()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!data->concatenated_subpath) { | 
					
						
							|  |  |  | 		int spc = data->subpath.size(); | 
					
						
							|  |  |  | 		String concatenated; | 
					
						
							|  |  |  | 		const StringName *ssn = data->subpath.ptr(); | 
					
						
							|  |  |  | 		for (int i = 0; i < spc; i++) { | 
					
						
							| 
									
										
										
										
											2017-11-22 14:13:56 +02:00
										 |  |  | 			concatenated += i == 0 ? ssn[i].operator String() : ":" + ssn[i]; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		data->concatenated_subpath = concatenated; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return data->concatenated_subpath; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | NodePath NodePath::rel_path_to(const NodePath &p_np) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!is_absolute(), NodePath()); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!p_np.is_absolute(), NodePath()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Vector<StringName> src_dirs = get_names(); | 
					
						
							|  |  |  | 	Vector<StringName> dst_dirs = p_np.get_names(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//find common parent
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int common_parent = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (true) { | 
					
						
							|  |  |  | 		if (src_dirs.size() == common_parent) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (dst_dirs.size() == common_parent) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (src_dirs[common_parent] != dst_dirs[common_parent]) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		common_parent++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	common_parent--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector<StringName> relpath; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = src_dirs.size() - 1; i > common_parent; i--) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		relpath.push_back(".."); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = common_parent + 1; i < dst_dirs.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		relpath.push_back(dst_dirs[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (relpath.size() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		relpath.push_back("."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	return NodePath(relpath, p_np.get_subnames(), false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NodePath NodePath::get_as_property_path() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-09 15:02:31 +02:00
										 |  |  | 	if (!data || !data->path.size()) { | 
					
						
							| 
									
										
										
										
											2017-11-22 14:13:56 +02:00
										 |  |  | 		return *this; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		Vector<StringName> new_path = data->subpath; | 
					
						
							| 
									
										
										
										
											2017-11-22 14:13:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		String initial_subname = data->path[0]; | 
					
						
							| 
									
										
										
										
											2018-04-21 22:35:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-26 17:38:02 +02:00
										 |  |  | 		for (int i = 1; i < data->path.size(); i++) { | 
					
						
							| 
									
										
										
										
											2018-04-21 22:35:23 +08:00
										 |  |  | 			initial_subname += "/" + data->path[i]; | 
					
						
							| 
									
										
										
										
											2017-11-22 14:13:56 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		new_path.insert(0, initial_subname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 		return NodePath(Vector<StringName>(), new_path, false); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_path.size() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = memnew(Data); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	data->refcount.init(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data->absolute = p_absolute; | 
					
						
							|  |  |  | 	data->path = p_path; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	data->has_slashes = true; | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	data->hash_cache_valid = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	if (p_path.size() == 0 && p_subpath.size() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = memnew(Data); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	data->refcount.init(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data->absolute = p_absolute; | 
					
						
							|  |  |  | 	data->path = p_path; | 
					
						
							|  |  |  | 	data->subpath = p_subpath; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	data->has_slashes = true; | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	data->hash_cache_valid = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | void NodePath::simplify() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!data) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < data->path.size(); i++) { | 
					
						
							|  |  |  | 		if (data->path.size() == 1) | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (data->path[i].operator String() == ".") { | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | 			data->path.remove(i); | 
					
						
							|  |  |  | 			i--; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		} else if (data->path[i].operator String() == ".." && i > 0 && data->path[i - 1].operator String() != "." && data->path[i - 1].operator String() != "..") { | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | 			//remove both
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			data->path.remove(i - 1); | 
					
						
							|  |  |  | 			data->path.remove(i - 1); | 
					
						
							|  |  |  | 			i -= 2; | 
					
						
							|  |  |  | 			if (data->path.size() == 0) { | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | 				data->path.push_back("."); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	data->hash_cache_valid = false; | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NodePath NodePath::simplified() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	NodePath np = *this; | 
					
						
							| 
									
										
										
										
											2015-10-10 09:09:09 -03:00
										 |  |  | 	np.simplify(); | 
					
						
							|  |  |  | 	return np; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | NodePath::NodePath(const String &p_path) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_path.length() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String path = p_path; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Vector<StringName> subpath; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	bool absolute = (path[0] == '/'); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	bool last_is_slash = true; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	bool has_slashes = false; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int slices = 0; | 
					
						
							|  |  |  | 	int subpath_pos = path.find(":"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (subpath_pos != -1) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		int from = subpath_pos + 1; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = from; i <= path.length(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (path[i] == ':' || path[i] == 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				String str = path.substr(from, i - from); | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 				if (str == "") { | 
					
						
							|  |  |  | 					if (path[i] == 0) continue; // Allow end-of-path :
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 					ERR_FAIL_MSG("Invalid NodePath '" + p_path + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 				subpath.push_back(str); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				from = i + 1; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		path = path.substr(0, subpath_pos); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	for (int i = (int)absolute; i < path.length(); i++) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (path[i] == '/') { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			last_is_slash = true; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 			has_slashes = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			if (last_is_slash) | 
					
						
							|  |  |  | 				slices++; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			last_is_slash = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	if (slices == 0 && !absolute && !subpath.size()) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = memnew(Data); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	data->refcount.init(); | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	data->absolute = absolute; | 
					
						
							| 
									
										
										
										
											2017-05-30 23:20:15 +03:00
										 |  |  | 	data->has_slashes = has_slashes; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data->subpath = subpath; | 
					
						
							| 
									
										
										
										
											2018-07-02 15:08:35 -03:00
										 |  |  | 	data->hash_cache_valid = false; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (slices == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 	data->path.resize(slices); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	last_is_slash = true; | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	int from = (int)absolute; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int slice = 0; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	for (int i = (int)absolute; i < path.length() + 1; i++) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (path[i] == '/' || path[i] == 0) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			if (!last_is_slash) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				String name = path.substr(from, i - from); | 
					
						
							|  |  |  | 				ERR_FAIL_INDEX(slice, data->path.size()); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 				data->path.write[slice++] = name; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			from = i + 1; | 
					
						
							|  |  |  | 			last_is_slash = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			last_is_slash = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool NodePath::is_empty() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return !data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | NodePath::NodePath() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NodePath::~NodePath() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	unref(); | 
					
						
							|  |  |  | } |