1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "alias_tree_owner.h"
21 #include "nel/misc/variable.h"
23 using namespace AITYPES
;
25 extern NLMISC::CVariable
<bool> LogAliasTreeOwner
;
27 CAliasTreeOwnerLocator
* CAliasTreeOwnerLocator::_Instance
= NULL
;
28 CAliasTreeOwnerLocator
* CAliasTreeOwnerLocator::getInstance()
31 _Instance
= new CAliasTreeOwnerLocator();
35 CAliasTreeOwner
* CAliasTreeOwnerLocator::getEntity(uint32
const alias
) const
37 std::map
<uint32
, CAliasTreeOwner
*>::const_iterator it
= _EntitiesByAlias
.find(alias
);
38 if (it
!=_EntitiesByAlias
.end())
44 CAliasTreeOwner
* CAliasTreeOwnerLocator::getEntity(std::string
const& name
) const
46 std::map
<std::string
, CAliasTreeOwner
*>::const_iterator it
= _EntitiesByName
.find(name
);
47 if (it
!=_EntitiesByName
.end())
53 void CAliasTreeOwnerLocator::addEntity(uint32
const alias
, std::string
const& name
, CAliasTreeOwner
* entity
)
55 _EntitiesByAlias
.insert(std::make_pair(alias
, entity
));
56 _EntitiesByName
.insert(std::make_pair(name
, entity
));
59 void CAliasTreeOwnerLocator::delEntity(uint32
const alias
, std::string
const& name
, CAliasTreeOwner
* entity
)
61 _EntitiesByName
.erase(name
);
62 _EntitiesByAlias
.erase(alias
);
65 std::vector
<NLMISC::CDbgPtr
<CAliasTreeOwner
> > CAliasTreeOwner::_CurrentOwnerList
;
67 void CAliasTreeOwner::updateAliasTree(const CAIAliasDescriptionNode
&newTree
)
69 _CurrentOwnerList
.push_back(this);
70 // check if this objet already have an associated Tree :)
73 CAIAliasDescriptionNode
&oldTree
= *getAliasNode();
75 // scan my own alias tree and make sure that everything listed still exists in the new tree
76 // Check for no more existing Alias Nodes ..
77 // scan destruction is reverse for coherence with construction.
78 for (int i
=oldTree
.getChildCount()-1;i
>=0;i
--)
80 CAIAliasDescriptionNode
*const oldChild
=oldTree
.getChild(i
);
82 // search new alias tree for a record corresponding to the one we're on in the old tree
83 if (!newTree
.getChildByAlias (oldChild
->getAlias()))
85 //nlstop("Have to parse the rest of child because a cchild may have been added in the upper hierarchy");
87 // LOG("updateAliasTreeDelete(): deleting: %s:%u (%s)", getName(oldChild->getType()), oldChild->getAlias(), oldChild->fullName().c_str());
88 // if (!updateAliasTreeDelete(oldChild))
89 // nlwarning("updateAliasTreeDelete(): Don't know how to deal with node: %s:%u (%s)", getName(oldChild->getType()), oldChild->getAlias(), oldChild->fullName().c_str());
90 IAliasCont
*const cont
= getAliasCont(oldChild
->getType());
92 cont
->removeChildByAlias(oldChild
->getAlias()); // smartPtr will do the job if necessary.
99 // scan the new alias tree for entries that aren't in the old tree
100 // Check for new existing Alias Nodes ..
101 for (uint j
=0;j
<newTree
.getChildCount();j
++)
103 CAIAliasDescriptionNode
*const newAliasChild
= newTree
.getChild(j
);
104 CAliasTreeOwner
* currentDeeperChild
=this;
109 // special case, the node represents a folder. Have to parse him normally on the current object.
110 if (newAliasChild
->getType()==AITypeFolder
)
113 CAliasTreeOwner
* childOwner
= NULL
;
114 IAliasCont
* cont
= NULL
;
116 // we try to get a valid IAliasCont for this type.
117 if (!getCont(childOwner
,cont
,newAliasChild
->getType()))
119 // kick hack to prevent special parsing case.
120 if ( newAliasChild
->getType()!=AITypeEventAction
121 && newAliasChild
->getType()!=AITypeFaunaSpawnAtom
)
123 if (LogAliasTreeOwner
)
124 nlwarning("ATO: '%s' not found in '%s', Skeeping ..", std::string(AITYPES::getName(newAliasChild
->getType())).c_str(), getName().c_str() );
129 CAliasTreeOwner
* child
= cont
->getAliasChildByAlias(newAliasChild
->getAlias());
130 if (!child
) // a child related to this alias not yet exists ..
132 // so we ask to create one objet of this type ( implementation is specialized :) )
133 // giving it the so precious CAIAliasDescriptionNode.
134 // assumes that it adds the child to its parent ( check by the next assert ).
135 child
=childOwner
->createChild(cont
,newAliasChild
);
136 nlassert(cont
->getAliasChildByAlias(newAliasChild
->getAlias())!=NULL
);
138 if (LogAliasTreeOwner
)
139 nldebug("ATO: In '%s' @ %p, created child '%s' @ %p", this->getName().c_str(), this, child
->getName().c_str(), child
);
144 nlwarning("ATO: Cannot create child '%s' in '%s', Skeeping ..", std::string(AITYPES::getName(newAliasChild
->getType())).c_str(), getName().c_str() );
147 currentDeeperChild
=child
;
150 currentDeeperChild
->updateAliasTree(*newAliasChild
);
151 updateDependencies(*newAliasChild
, currentDeeperChild
);
153 _CurrentOwnerList
.pop_back();
158 bool CAliasTreeOwner::getCont(CAliasTreeOwner
*&childOwner
, IAliasCont
*&cont
, TAIType _type
)
160 std::vector
<NLMISC::CDbgPtr
<CAliasTreeOwner
> >::reverse_iterator
first(_CurrentOwnerList
.rbegin()), last(_CurrentOwnerList
.rend());
161 for (; first
!= last
; ++first
)
163 cont
=(*first
)->getAliasCont(_type
);