Changeset 809 for code/branches/core/src/orxonox/core/ClassTreeMask.cc
- Timestamp:
- Feb 13, 2008, 2:47:10 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core/src/orxonox/core/ClassTreeMask.cc
r808 r809 26 26 */ 27 27 28 /*! 29 @file ClassTreeMask.cc 30 @brief Implementation of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes. 31 */ 32 28 33 #include "ClassTreeMask.h" 29 34 #include "Identifier.h" … … 35 40 // ### ClassTreeMaskNode ### 36 41 // ############################### 42 /** 43 @brief Constructor: Creates the node, sets the subclass and the rule. 44 @param subclass The subclass the rule refers to 45 @param bIncluded The rule: included (true) or excluded (false) 46 */ 37 47 ClassTreeMaskNode::ClassTreeMaskNode(const Identifier* subclass, bool bIncluded) 38 48 { … … 41 51 } 42 52 53 /** 54 @brief Destructor: Deletes all subnodes. 55 */ 43 56 ClassTreeMaskNode::~ClassTreeMaskNode() 44 57 { 58 // Go through the list of all subnodes and delete them 45 59 for (std::list<ClassTreeMaskNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ) 46 60 delete (*(it++)); 47 61 } 48 62 63 /** 64 @brief Sets the rule for the node to "included". 65 */ 49 66 void ClassTreeMaskNode::include() 50 67 { … … 52 69 } 53 70 71 /** 72 @brief Sets the rule for the node to "excluded". 73 */ 54 74 void ClassTreeMaskNode::exclude() 55 75 { … … 57 77 } 58 78 79 /** 80 @brief Sets the rule for the node to a given value. 81 @param bIncluded The rule: included (true) or excluded (false) 82 */ 59 83 void ClassTreeMaskNode::setIncluded(bool bIncluded) 60 84 { … … 62 86 } 63 87 88 /** 89 @brief Adds a new subnode to the list of subnodes. 90 @param subnode The new subnode 91 */ 64 92 void ClassTreeMaskNode::addSubnode(ClassTreeMaskNode* subnode) 65 93 { … … 67 95 } 68 96 97 /** 98 @brief Tells if the rule is "included" or not. 99 @return The rule: true = included, false = excluded 100 */ 69 101 bool ClassTreeMaskNode::isIncluded() const 70 102 { … … 72 104 } 73 105 106 /** 107 @brief Tells if the rule is "excluded" or not. 108 @return The inverted rule: true = excluded, false = included 109 */ 74 110 bool ClassTreeMaskNode::isExcluded() const 75 111 { … … 77 113 } 78 114 115 /** 116 @brief Returns the Identifier of the class the rule refers to. 117 @return The Identifier representing the class 118 */ 79 119 const Identifier* ClassTreeMaskNode::getClass() const 80 120 { … … 86 126 // ### ClassTreeMaskIterator ### 87 127 // ############################### 128 /** 129 @brief Constructor: Initializes the iterator by creating a helper-list with the root-node and putting it to the stack. 130 @param node The root-node 131 */ 88 132 ClassTreeMaskIterator::ClassTreeMaskIterator(ClassTreeMaskNode* node) 89 133 { 134 // Create a list and put the root-note into it 90 135 std::list<ClassTreeMaskNode*>::iterator it = this->rootlist_.insert(this->rootlist_.end(), node); 136 137 // Put the iterator to the only element of the list and the corresponding end()-iterator on the stack 91 138 this->nodes_.push(std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator>(it, this->rootlist_.end())); 92 139 } 93 140 141 /** 142 @brief Destructor: Does nothing. 143 */ 94 144 ClassTreeMaskIterator::~ClassTreeMaskIterator() 95 145 { 96 146 } 97 147 148 /** 149 @brief Iterates through the rule-tree. 150 @return A reference to the iterator itself 151 */ 98 152 ClassTreeMaskIterator& ClassTreeMaskIterator::operator++() 99 153 { 154 // Check if the actual node has subnodes 100 155 if ((*this->nodes_.top().first)->subnodes_.begin() != (*this->nodes_.top().first)->subnodes_.end()) 156 { 157 // Yes it has: Push an iterator, pointing at the first subnode, on the stack 101 158 this->nodes_.push(std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator>((*this->nodes_.top().first)->subnodes_.begin(), (*this->nodes_.top().first)->subnodes_.end())); 159 } 102 160 else 103 161 { 162 // No subnodes, meaning we reached a leaf: Go to the next node 104 163 do 105 164 { 165 // Iterate one step in the current list 106 166 ++this->nodes_.top().first; 167 168 // Check if we reached the end of the list (the second item in the stored pair always represents the end) 107 169 if (this->nodes_.top().first == this->nodes_.top().second) 108 170 { 171 // Yes we've reached the end: Pop the list-iterator from the stack 109 172 this->nodes_.pop(); 173 174 // Continue with the loop, meaning: Try to iterate through the previous list 110 175 continue; 111 176 } 112 177 178 // If we reached this point, we aren't yet at the end of the list: Leave the loop 113 179 break; 114 } while (!this->nodes_.empty()); 115 } 116 180 } while (!this->nodes_.empty()); // Stop looping if the stack is empty, meaning: We've iterated to the end 181 } 182 183 // Finally return a reference to the iterator itself 117 184 return *this; 118 185 } 119 186 187 /** 188 @brief Returns a pointer to the ClassTreeMaskNode whereon the iterator points. 189 @return The pointer to the node 190 */ 120 191 ClassTreeMaskNode* ClassTreeMaskIterator::operator*() const 121 192 { … … 123 194 } 124 195 196 /** 197 @brief Returns a pointer to the ClassTreeMaskNode whereon the iterator points. 198 @return The pointer to the node 199 */ 125 200 ClassTreeMaskNode* ClassTreeMaskIterator::operator->() const 126 201 { … … 128 203 } 129 204 205 /** 206 @brief Returns true if the stack is empty, meaning we've reached the end of the tree. 207 @return True if we've reached the end of the tree 208 */ 130 209 ClassTreeMaskIterator::operator bool() 131 210 { … … 133 212 } 134 213 214 /** 215 @brief Compares the current node with the given one and returns true if they match. 216 @param compare The node to compare with 217 @return The result of the comparison (true if they match) 218 */ 135 219 bool ClassTreeMaskIterator::operator==(ClassTreeMaskNode* compare) 136 220 { … … 141 225 } 142 226 227 /** 228 @brief Compares the current node with the given one and returns true if they don't match. 229 @param compare The node to compare with 230 @return The result of the comparison (true if they don't match) 231 */ 143 232 bool ClassTreeMaskIterator::operator!=(ClassTreeMaskNode* compare) 144 233 { … … 153 242 // ### ClassTreeMask ### 154 243 // ############################### 244 /** 245 @brief Constructor: Adds the root-node of the tree with the first rule ("include everything"). 246 */ 155 247 ClassTreeMask::ClassTreeMask() 156 248 { … … 158 250 } 159 251 252 /** 253 @brief Copyconstructor: Adds the root-node of the tree with the first rule ("include everything") and adds all rules from the other mask. 254 @param other The other mask 255 */ 160 256 ClassTreeMask::ClassTreeMask(const ClassTreeMask& other) 161 257 { … … 165 261 } 166 262 263 /** 264 @brief Destructor: Deletes the root node (which will delete all subnodes too). 265 */ 167 266 ClassTreeMask::~ClassTreeMask() 168 267 { … … 170 269 } 171 270 271 /** 272 @brief Adds a new "include" rule for a given subclass to the mask. 273 @param subclass The subclass 274 */ 172 275 void ClassTreeMask::include(const Identifier* subclass) 173 276 { … … 175 278 } 176 279 280 /** 281 @brief Adds a new "exclude" rule for a given subclass to the mask. 282 @param subclass The subclass 283 */ 177 284 void ClassTreeMask::exclude(const Identifier* subclass) 178 285 { … … 180 287 } 181 288 289 /** 290 @brief Adds a new rule for a given subclass to the mask. 291 @param subclass The subclass 292 @param bInclude The rule: include (true) or exclude (false) 293 */ 182 294 void ClassTreeMask::add(const Identifier* subclass, bool bInclude) 183 295 { … … 185 297 } 186 298 299 /** 300 @brief Adds a new rule for a given subclass to a node of the internal rule-tree (recursive function). 301 @param node The node 302 @param subclass The subclass 303 @param bInclude The rule: include (true) or exclude (false) 304 */ 187 305 void ClassTreeMask::add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude) 188 306 { … … 201 319 if (subclass->isA((*it)->getClass())) 202 320 { 203 // We've found an existing node -> delegate the work and return321 // We've found an existing node -> delegate the work with a recursive function-call and return 204 322 this->add(*it, subclass, bInclude); 205 323 return; … … 230 348 } 231 349 350 /** 351 @brief Resets the mask to "include everything". 352 */ 232 353 void ClassTreeMask::reset() 233 354 { … … 236 357 } 237 358 359 /** 360 @brief Tells if a given subclass is included or not. 361 @param subclass The subclass 362 @return Included (true) or excluded (false) 363 */ 238 364 bool ClassTreeMask::isIncluded(const Identifier* subclass) const 239 365 { … … 241 367 } 242 368 369 /** 370 @brief Tells if a given subclass of a node in the rule-tree is included or not (recursive function). 371 @param node The node 372 @param subclass The subclass 373 @return Included (true) or excluded (false) 374 */ 243 375 bool ClassTreeMask::isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const 244 376 { 245 //std::cout << "1_1: " << subclass->getName() << " (" << subclass << ") / " << node->getClass()->getName() << " (" << node->getClass() << ")" << std::endl;246 377 // Check if the searched subclass is of the same type as the class in the current node or a derivative 247 378 if (subclass->isA(node->getClass())) … … 251 382 return node->isIncluded(); 252 383 253 // Go through the list of subnodes and look for a node containing the searched subclass 384 // Go through the list of subnodes and look for a node containing the searched subclass and delegate the request by a recursive function-call. 254 385 for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it) 255 386 if (subclass->isA((*it)->getClass())) … … 266 397 } 267 398 399 /** 400 @brief Tells if a given subclass is excluded or not. 401 @param subclass The subclass 402 @return The inverted rule: Excluded (true) or included (false) 403 */ 268 404 bool ClassTreeMask::isExcluded(const Identifier* subclass) const 269 405 { … … 271 407 } 272 408 409 /** 410 @brief Removes all unneeded rules that don't change the information of the mask. 411 */ 273 412 void ClassTreeMask::clean() 274 413 { … … 276 415 } 277 416 417 /** 418 @brief Removes all unneded rules that don't change the information of a node of a mask (recursive function). 419 @param node The node 420 */ 278 421 void ClassTreeMask::clean(ClassTreeMaskNode* node) 279 422 { 280 //std::cout << "4_1: " << node->getClass()->getName() << ": " << node->isIncluded() << "\n"; 423 // Iterate through all subnodes of the given node 281 424 for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ) 282 425 { 283 //std::cout << "4_2: " << (*it)->getClass()->getName() << ": " << (*it)->isIncluded() << "\n"; 426 // Recursive function-call: Clean the subnode 284 427 this->clean(*it); 285 //std::cout << "4_3\n"; 428 429 // Now check if the subnode contains the same rule as the current node 286 430 if ((*it)->isIncluded() == node->isIncluded()) 287 431 { 288 //std::cout << "4_4\n"; 432 // It does: Move all subnodes of the redundant subnode to the current node 289 433 node->subnodes_.insert(node->subnodes_.end(), (*it)->subnodes_.begin(), (*it)->subnodes_.end()); 290 434 (*it)->subnodes_.clear(); 291 node->subnodes_.erase(it); 292 it = node->subnodes_.begin();293 //std::cout << "4_5\n";435 436 // Remove the redundant subnode from the current node 437 node->subnodes_.erase(it++); 294 438 } 295 439 else 296 440 { 297 //std::cout << "4_6\n"; 441 // The subnode is necessary: Move on to the next subnode 298 442 ++it; 299 443 } 300 444 } 301 //std::cout << "4_7\n"; 302 } 303 445 } 446 447 /** 448 @brief Assignment operator: Adds all rules of the other mask. 449 @param other The other mask 450 @return A reference to the mask itself 451 */ 304 452 ClassTreeMask& ClassTreeMask::operator=(const ClassTreeMask& other) 305 453 { 454 // Make a copy to avoid troubles with self-assignments (like A = A). 306 455 ClassTreeMask temp(other); 307 456 457 // Removes all current rules 308 458 this->reset(); 309 459 460 // Copy all rules from the other mask 310 461 for (ClassTreeMaskIterator it = temp.root_; it; ++it) 311 462 this->add(it->getClass(), it->isIncluded()); 312 463 464 // Return a reference to the mask itself 313 465 return (*this); 314 466 } 315 467 468 /** 469 @brief Prefix operator + does nothing. 470 @return A reference to the mask itself 471 */ 316 472 ClassTreeMask& ClassTreeMask::operator+() 317 473 { … … 319 475 } 320 476 477 /** 478 @brief Prefix operator - inverts the mask. 479 @return The inverted mask 480 */ 321 481 ClassTreeMask ClassTreeMask::operator-() const 322 482 { … … 324 484 } 325 485 486 /** 487 @brief Adds two masks in the sense of a union (all classes that are included in at least one of the masks will be included in the resulting mask too). 488 @param other The mask to unite with 489 @return The union 490 */ 326 491 ClassTreeMask ClassTreeMask::operator+(const ClassTreeMask& other) const 327 492 { 493 // Create a new mask 328 494 ClassTreeMask newmask; 495 496 // Add all nodes from the first mask, calculate the rule with the or-operation 329 497 for (ClassTreeMaskIterator it = this->root_; it; ++it) 330 498 { … … 332 500 newmask.add(subclass, this->isIncluded(subclass) or other.isIncluded(subclass)); 333 501 } 502 503 // Add all nodes from the second mask, calculate the rule with the or-operation 334 504 for (ClassTreeMaskIterator it = other.root_; it; ++it) 335 505 { … … 337 507 newmask.add(subclass, this->isIncluded(subclass) or other.isIncluded(subclass)); 338 508 } 509 510 // Drop all redundant rules 339 511 newmask.clean(); 340 512 513 // Return the new mask 341 514 return newmask; 342 515 } 343 516 517 /** 518 @brief Intersects two masks (only classes that are included in both masks will be included in the resulting mask too). 519 @param other The mask to intersect with 520 @return The intersection 521 */ 344 522 ClassTreeMask ClassTreeMask::operator*(const ClassTreeMask& other) const 345 523 { 524 // Create a new mask 346 525 ClassTreeMask newmask; 526 527 // Add all nodes from the first mask, calculate the rule with the and-operation 347 528 for (ClassTreeMaskIterator it = this->root_; it; ++it) 348 529 { … … 350 531 newmask.add(subclass, this->isIncluded(subclass) and other.isIncluded(subclass)); 351 532 } 533 534 // Add all nodes from the second mask, calculate the rule with the and-operation 352 535 for (ClassTreeMaskIterator it = other.root_; it; ++it) 353 536 { … … 355 538 newmask.add(subclass, this->isIncluded(subclass) and other.isIncluded(subclass)); 356 539 } 540 541 // Drop all redundant rules 357 542 newmask.clean(); 358 543 544 // Return the new mask 359 545 return newmask; 360 546 } 361 547 548 /** 549 @brief Removes all elements of the second mask from the first mask (all classes that are included in the first mask stay included, except those that are included in the second mask too). 550 @param other The mask to subtract. 551 @return The difference 552 */ 362 553 ClassTreeMask ClassTreeMask::operator-(const ClassTreeMask& other) const 363 554 { … … 365 556 } 366 557 558 /** 559 @brief Inverts the mask (all included classes are now excluded and vice versa). 560 @return The complement 561 */ 367 562 ClassTreeMask ClassTreeMask::operator!() const 368 563 { 564 // Create a new mask 369 565 ClassTreeMask newmask; 566 567 // Add all nodes from the other mask, inverting the rules 370 568 for (ClassTreeMaskIterator it = this->root_; it; ++it) 371 569 { … … 373 571 newmask.add(subclass, !this->isIncluded(subclass)); 374 572 } 573 574 // Return the new mask 375 575 return newmask; 376 576 } 377 577 578 /** 579 @brief Unites this mask with another mask. 580 @param other The other mask 581 @return A reference to the mask itself 582 */ 378 583 ClassTreeMask& ClassTreeMask::operator+=(const ClassTreeMask& other) 379 584 { … … 382 587 } 383 588 589 /** 590 @brief Intersects this mask with another mask. 591 @param other The other mask 592 @return A reference to the mask itself 593 */ 384 594 ClassTreeMask& ClassTreeMask::operator*=(const ClassTreeMask& other) 385 595 { … … 388 598 } 389 599 600 /** 601 @brief Subtracts another mask from this mask. 602 @param other The other mask 603 @return A reference to the mask itself 604 */ 390 605 ClassTreeMask& ClassTreeMask::operator-=(const ClassTreeMask& other) 391 606 { … … 394 609 } 395 610 611 /** 612 @brief Intersects two masks (only classes that are included in both masks will be included in the resulting mask too). 613 @param other The mask to intersect with 614 @return The intersection 615 */ 396 616 ClassTreeMask ClassTreeMask::operator&(const ClassTreeMask& other) const 397 617 { … … 399 619 } 400 620 621 /** 622 @brief Adds two masks in the sense of a union (all classes that are included in at least one of the masks will be included in the resulting mask too). 623 @param other The mask to unite with 624 @return The union 625 */ 401 626 ClassTreeMask ClassTreeMask::operator|(const ClassTreeMask& other) const 402 627 { … … 404 629 } 405 630 631 /** 632 @brief Joins two masks in the sense of a xor (exclusivity) operation (all classes that are included in exactly one of the masks, but not in both, will be included in the resulting mask too). 633 @param other The mask to join with 634 @return The result 635 */ 406 636 ClassTreeMask ClassTreeMask::operator^(const ClassTreeMask& other) const 407 637 { 638 // Create a new mask 408 639 ClassTreeMask newmask; 640 641 // Add all nodes from the first mask, calculate the rule with the xor-operation 409 642 for (ClassTreeMaskIterator it = this->root_; it; ++it) 410 643 { … … 412 645 newmask.add(subclass, this->isIncluded(subclass) xor other.isIncluded(subclass)); 413 646 } 647 648 // Add all nodes from the second mask, calculate the rule with the xor-operation 414 649 for (ClassTreeMaskIterator it = other.root_; it; ++it) 415 650 { … … 417 652 newmask.add(subclass, this->isIncluded(subclass) xor other.isIncluded(subclass)); 418 653 } 654 655 // Drop all redundant rules 419 656 newmask.clean(); 420 657 658 // Return the new mask 421 659 return newmask; 422 660 } 423 661 662 /** 663 @brief Inverts the mask (all included classes are now excluded and vice versa). 664 @return The complement 665 */ 424 666 ClassTreeMask ClassTreeMask::operator~() const 425 667 { … … 427 669 } 428 670 671 /** 672 @brief Intersects this mask with another mask (and-operation) 673 @param other The other mask 674 @return A reference to the mask itself 675 */ 429 676 ClassTreeMask& ClassTreeMask::operator&=(const ClassTreeMask& other) 430 677 { … … 433 680 } 434 681 682 /** 683 @brief Unites this mask with another mask (or-operation). 684 @param other The other mask 685 @return A reference to the mask itself 686 */ 435 687 ClassTreeMask& ClassTreeMask::operator|=(const ClassTreeMask& other) 436 688 { … … 439 691 } 440 692 693 /** 694 @brief Joins this mask with another mask with a xor-operation. 695 @param other The other mask 696 @return A reference to the mask itself 697 */ 441 698 ClassTreeMask& ClassTreeMask::operator^=(const ClassTreeMask& other) 442 699 { … … 445 702 } 446 703 704 /** 705 @brief Converts the content of a mask into a human readable string and puts it on the ostream. 706 @param out The ostream 707 @param mask The mask 708 @return A reference to the ostream 709 */ 447 710 std::ostream& operator<<(std::ostream& out, const ClassTreeMask& mask) 448 711 { 712 // Iterate through all rules 449 713 for (ClassTreeMaskIterator it = mask.root_; it; ++it) 450 714 { 715 // Calculate the prefix: + means included, - means excluded 451 716 if (it->isIncluded()) 452 717 out << "+"; … … 454 719 out << "-"; 455 720 721 // Put the name of the corresponding class on the stream 456 722 out << it->getClass()->getName() << " "; 457 723 }
Note: See TracChangeset
for help on using the changeset viewer.