Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 13, 2013, 11:35:26 PM (11 years ago)
Author:
landauf
Message:

implemented new concept to initialize the class hierarchy: each identifier is initialized individually by creating an object of the corresponding class. identifiers of abstract classes must be told explicitly about their direct parents. this allows to build the class tree correctly also for complicated setups like multiple inheritance of abstract classes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core6/src/libraries/core/class/Identifier.cc

    r9641 r9646  
    3737
    3838#include "util/StringUtils.h"
     39#include "core/CoreIncludes.h"
    3940#include "core/config/ConfigValueContainer.h"
    4041#include "core/XMLPort.h"
     
    5253        : classID_(IdentifierManager::getInstance().getUniqueClassId())
    5354    {
    54         this->bCreatedOneObject_ = false;
    55         this->bSetName_ = false;
    5655        this->factory_ = 0;
     56        this->bInitialized_ = false;
    5757        this->bLoadable_ = false;
    5858
     
    8080
    8181    /**
    82         @brief Registers a class, which means that the name and the parents get stored.
    83         @param parents A list, containing the Identifiers of all parents of the class
    84         @param bRootClass True if the class is either an Interface or the BaseObject itself
    85     */
    86     void Identifier::initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass)
    87     {
    88         // Check if at least one object of the given type was created
    89         if (!this->bCreatedOneObject_ && IdentifierManager::getInstance().isCreatingHierarchy())
    90         {
    91             // If no: We have to store the information and initialize the Identifier
    92             orxout(verbose, context::identifier) << "Register Class in ClassIdentifier<" << this->getName() << ">-Singleton -> Initialize Singleton." << endl;
    93             if (bRootClass)
    94                 this->initialize(0); // If a class is derived from two interfaces, the second interface might think it's derived from the first because of the order of constructor-calls. Thats why we set parents to zero in that case.
    95             else
    96                 this->initialize(parents);
    97         }
    98     }
    99 
    100     /**
    101         @brief Initializes the Identifier with a list containing all parents of the class the Identifier belongs to.
    102         @param parents A list containing all parents
    103     */
    104     void Identifier::initialize(std::set<const Identifier*>* parents)
    105     {
    106         orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << this->name_ << ">-Singleton." << endl;
    107         this->bCreatedOneObject_ = true;
    108 
    109         if (parents)
    110         {
    111             this->parents_ = (*parents);
    112             this->directParents_ = (*parents);
    113 
    114             // Iterate through all parents
    115             for (std::set<const Identifier*>::iterator it = parents->begin(); it != parents->end(); ++it)
    116             {
    117                 // Tell the parent we're one of it's children
    118                 (*it)->children_.insert((*it)->children_.end(), this);
    119 
    120                 // Erase all parents of our parent from our direct-parent-list
    121                 for (std::set<const Identifier*>::const_iterator it1 = (*it)->getParents().begin(); it1 != (*it)->getParents().end(); ++it1)
    122                 {
    123                     // Search for the parent's parent in our direct-parent-list
    124                     for (std::set<const Identifier*>::iterator it2 = this->directParents_.begin(); it2 != this->directParents_.end(); ++it2)
    125                     {
    126                         if ((*it1) == (*it2))
    127                         {
    128                             // We've found a non-direct parent in our list: Erase it
    129                             this->directParents_.erase(it2);
    130                             break;
    131                         }
    132                     }
    133                 }
    134             }
    135 
    136             // Now iterate through all direct parents
    137             for (std::set<const Identifier*>::iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
    138             {
    139                 // Tell the parent we're one of it's direct children
    140                 (*it)->directChildren_.insert((*it)->directChildren_.end(), this);
    141 
    142                 // Create the super-function dependencies
    143                 (*it)->createSuperFunctionCaller();
    144             }
    145         }
    146     }
    147 
    148     /**
    14982        @brief Sets the name of the class.
    15083    */
    15184    void Identifier::setName(const std::string& name)
    15285    {
    153         if (!this->bSetName_)
     86        if (name != this->name_)
    15487        {
    15588            this->name_ = name;
    156             this->bSetName_ = true;
    157             IdentifierManager::getInstance().registerIdentifier(this);
     89            IdentifierManager::getInstance().addIdentifierToLookupMaps(this);
    15890        }
    15991    }
     
    194126    {
    195127        this->networkID_ = id;
    196         IdentifierManager::getInstance().registerIdentifier(this);
     128        IdentifierManager::getInstance().addIdentifierToLookupMaps(this);
     129    }
     130
     131    /**
     132     * @brief Used to define the direct parents of an Identifier of an abstract class.
     133     */
     134    Identifier& Identifier::inheritsFrom(Identifier* directParent)
     135    {
     136        if (this->parents_.empty())
     137            this->directParents_.insert(directParent);
     138        else
     139            orxout(internal_error) << "Trying to add " << directParent->getName() << " as a direct parent of " << this->getName() << " after the latter was already initialized" << endl;
     140
     141        return *this;
     142    }
     143
     144    /**
     145     * @brief Initializes the parents of this Identifier while creating the class hierarchy.
     146     * @param identifiers All identifiers that were used to create an instance of this class (including this identifier itself)
     147     */
     148    void Identifier::initializeParents(const std::set<const Identifier*>& identifiers)
     149    {
     150        if (!IdentifierManager::getInstance().isCreatingHierarchy())
     151        {
     152            orxout(internal_warning) << "Identifier::initializeParents() created outside of class hierarchy creation" << endl;
     153            return;
     154        }
     155
     156        for (std::set<const Identifier*>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it)
     157            if (*it != this)
     158                this->parents_.insert(*it);
     159    }
     160
     161    /**
     162     * @brief Initializes the direct parents of this Identifier while creating the class hierarchy. This is only intended for abstract classes.
     163     */
     164    void Identifier::initializeDirectParentsOfAbstractClass()
     165    {
     166        if (!IdentifierManager::getInstance().isCreatingHierarchy())
     167        {
     168            orxout(internal_warning) << "Identifier::initializeDirectParentsOfAbstractClass() created outside of class hierarchy creation" << endl;
     169            return;
     170        }
     171
     172        // only Identifiable is allowed to have no parents (even tough it's currently not abstract)
     173        if (this->directParents_.empty() && !this->isExactlyA(Class(Identifiable)))
     174        {
     175            orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeidName() << " is marked as abstract but has no direct parents defined" << endl;
     176            orxout(internal_error) << "  If this class is not abstract, use RegisterClass(ThisClass);" << endl;
     177            orxout(internal_error) << "  If this class is abstract, use RegisterAbstractClass(ThisClass).inheritsFrom(Class(BaseClass));" << endl;
     178        }
     179    }
     180
     181    /**
     182     * @brief Finishes the initialization of this Identifier after creating the class hierarchy by wiring the (direct) parent/child references correctly.
     183     */
     184    void Identifier::finishInitialization()
     185    {
     186        if (!IdentifierManager::getInstance().isCreatingHierarchy())
     187        {
     188            orxout(internal_warning) << "Identifier::finishInitialization() created outside of class hierarchy creation" << endl;
     189            return;
     190        }
     191
     192        if (this->isInitialized())
     193            return;
     194
     195        // if no direct parents were defined, initialize them with the set of all parents
     196        if (this->directParents_.empty())
     197            this->directParents_ = this->parents_;
     198
     199        // initialize all parents before continuing to initialize this identifier
     200        for (std::set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
     201        {
     202            Identifier* directParent = const_cast<Identifier*>(*it);
     203            directParent->finishInitialization(); // initialize parent
     204            this->parents_.insert(directParent);  // direct parent is also a parent
     205            this->parents_.insert(directParent->parents_.begin(), directParent->parents_.end()); // parents of direct parent are also parents
     206        }
     207
     208        // parents of parents are no direct parents of this identifier
     209        for (std::set<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent)
     210            for (std::set<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent)
     211                this->directParents_.erase(*it_parent_parent);
     212
     213        // tell all parents that this identifier is a child
     214        for (std::set<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it)
     215            const_cast<Identifier*>(*it)->children_.insert(this);
     216
     217        // tell all direct parents that this identifier is a direct child
     218        for (std::set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
     219        {
     220            const_cast<Identifier*>(*it)->directChildren_.insert(this);
     221
     222            // Create the super-function dependencies
     223            (*it)->createSuperFunctionCaller();
     224        }
     225
     226        this->bInitialized_ = true;
    197227    }
    198228
Note: See TracChangeset for help on using the changeset viewer.