| 261 | } |
| 262 | |
| 263 | Ref<ObjectDiffResult> ObjectDiffResult::get_diff_obj(Object *a, Object *b, bool exclude_non_storage, const Dictionary &p_structured_changes) { |
| 264 | Ref<ObjectDiffResult> diff; |
| 265 | diff.instantiate(); |
| 266 | List<PropertyInfo> p_list_a; |
| 267 | List<PropertyInfo> p_list_b; |
| 268 | diff->set_old_object(a); |
| 269 | diff->set_new_object(b); |
| 270 | a->get_property_list(&p_list_a, false); |
| 271 | b->get_property_list(&p_list_b, false); |
| 272 | if (a->get_script_instance()) { |
| 273 | a->get_script_instance()->get_property_list(&p_list_a); |
| 274 | a->notification(Node::NOTIFICATION_READY); |
| 275 | a->get_script_instance()->notification(Node::NOTIFICATION_READY); |
| 276 | } |
| 277 | if (b->get_script_instance()) { |
| 278 | b->get_script_instance()->get_property_list(&p_list_b); |
| 279 | b->notification(Node::NOTIFICATION_READY); |
| 280 | b->get_script_instance()->notification(Node::NOTIFICATION_READY); |
| 281 | } |
| 282 | // diff is key: [old_value, new_value] |
| 283 | HashSet<String> prop_names; |
| 284 | // TODO: handle PROPERTY_USAGE_NO_EDITOR, PROPERTY_USAGE_INTERNAL, etc. |
| 285 | for (auto &prop : p_list_a) { |
| 286 | if (exclude_non_storage && !(prop.usage & PROPERTY_USAGE_STORAGE)) { |
| 287 | continue; |
| 288 | } |
| 289 | prop_names.insert(prop.name); |
| 290 | } |
| 291 | for (auto &prop : p_list_b) { |
| 292 | if (exclude_non_storage && !(prop.usage & PROPERTY_USAGE_STORAGE)) { |
| 293 | continue; |
| 294 | } |
| 295 | prop_names.insert(prop.name); |
| 296 | } |
| 297 | for (auto &prop : prop_names) { |
| 298 | bool a_valid = false; |
| 299 | bool b_valid = false; |
| 300 | auto prop_a = a->get(prop, &a_valid); |
| 301 | auto prop_b = b->get(prop, &b_valid); |
| 302 | if (!a_valid && !b_valid) { |
| 303 | continue; |
| 304 | } |
| 305 | if (!a_valid) { |
| 306 | diff->set_property_diff(memnew(PropertyDiffResult(prop, "deleted", Variant(), prop_b, a, b))); |
| 307 | } else if (!b_valid) { |
| 308 | diff->set_property_diff(memnew(PropertyDiffResult(prop, "added", prop_a, Variant(), a, b))); |
| 309 | } else if (!DiffResult::deep_equals(prop_a, prop_b)) { |
| 310 | diff->set_property_diff(memnew(PropertyDiffResult(prop, "changed", prop_a, prop_b, a, b))); |
| 311 | } |
| 312 | } |
| 313 | return diff; |
| 314 | } |
| 315 | |
| 316 | void NodeDiffResult::_bind_methods() { |
| 317 | ClassDB::bind_method(D_METHOD("set_path", "path"), &NodeDiffResult::set_path); |
nothing calls this directly
no test coverage detected