| 516 | } |
| 517 | |
| 518 | void Properties::resolveInheritance(std::string_view id) |
| 519 | { |
| 520 | // Namespaces can be defined like so: |
| 521 | // "name id : parentID { }" |
| 522 | // This method merges data from the parent namespace into the child. |
| 523 | |
| 524 | // Get a top-level namespace. |
| 525 | Properties* derived; |
| 526 | if (!id.empty()) |
| 527 | { |
| 528 | derived = getNamespace(id); |
| 529 | } |
| 530 | else |
| 531 | { |
| 532 | derived = getNextNamespace(); |
| 533 | } |
| 534 | while (derived) |
| 535 | { |
| 536 | // If the namespace has a parent ID, find the parent. |
| 537 | if (!derived->_parentID.empty()) |
| 538 | { |
| 539 | Properties* parent = getNamespace(derived->_parentID.c_str()); |
| 540 | if (parent) |
| 541 | { |
| 542 | resolveInheritance(parent->getId()); |
| 543 | |
| 544 | // Copy the child. |
| 545 | Properties* overrides = new Properties(*derived); |
| 546 | |
| 547 | // Delete the child's data. |
| 548 | for (size_t i = 0, count = derived->_namespaces.size(); i < count; i++) |
| 549 | { |
| 550 | AX_SAFE_DELETE(derived->_namespaces[i]); |
| 551 | } |
| 552 | |
| 553 | // Copy data from the parent into the child. |
| 554 | derived->_properties = parent->_properties; |
| 555 | derived->_namespaces.clear(); |
| 556 | std::vector<Properties*>::const_iterator itt; |
| 557 | for (const auto space : parent->_namespaces) |
| 558 | { |
| 559 | derived->_namespaces.emplace_back(new Properties(*space)); |
| 560 | } |
| 561 | derived->rewind(); |
| 562 | |
| 563 | // Take the original copy of the child and override the data copied from the parent. |
| 564 | derived->mergeWith(overrides); |
| 565 | |
| 566 | // Delete the child copy. |
| 567 | AX_SAFE_DELETE(overrides); |
| 568 | } |
| 569 | } |
| 570 | |
| 571 | // Resolve inheritance within this namespace. |
| 572 | derived->resolveInheritance(); |
| 573 | |
| 574 | // Get the next top-level namespace and check again. |
| 575 | if (id.empty()) |
no test coverage detected