Index: ps/trunk/binaries/system/Collada.dll =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/binaries/system/FCollada.dll =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/binaries/system/FCollada.pdb =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/binaries/system/FColladaD.dll =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/binaries/system/FColladaD.pdb =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/libraries/source/fcollada/build.sh =================================================================== --- ps/trunk/libraries/source/fcollada/build.sh (revision 24321) +++ ps/trunk/libraries/source/fcollada/build.sh (revision 24322) @@ -1,35 +1,35 @@ #!/bin/sh set -e -LIB_VERSION="fcollada-3.05+wildfiregames.3" +LIB_VERSION="fcollada-3.05+wildfiregames.4" JOBS=${JOBS:="-j2"} MAKE=${MAKE:="make"} LDFLAGS=${LDFLAGS:=""} CFLAGS=${CFLAGS:=""} CXXFLAGS=${CXXFLAGS:=""} if [ -e .already-built ] && [ "$(cat .already-built)" = "${LIB_VERSION}" ] then echo "FCollada is already up to date." exit fi echo "Building FCollada..." echo if [ "$(uname -s)" = "Darwin" ]; then # The Makefile refers to pkg-config for libxml2, but we # don't have that (replace with xml2-config instead). sed -i.bak -e 's/pkg-config libxml-2.0/xml2-config/' src/Makefile fi rm -f .already-built rm -f lib/*.a mkdir -p lib (cd src && rm -rf "output/" && "${MAKE}" clean && CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" && LDFLAGS="$LDFLAGS" "${MAKE}" "${JOBS}") || die "FCollada build failed" if [ "$(uname -s)" = "Darwin" ]; then # Undo Makefile change as we don't want to have it when creating patches. mv src/Makefile.bak src/Makefile fi echo "$LIB_VERSION" > .already-built Index: ps/trunk/libraries/source/fcollada/include/FUtils/FUTracker.h =================================================================== --- ps/trunk/libraries/source/fcollada/include/FUtils/FUTracker.h (revision 24321) +++ ps/trunk/libraries/source/fcollada/include/FUtils/FUTracker.h (revision 24322) @@ -1,378 +1,378 @@ /* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America - + MIT License: http://www.opensource.org/licenses/mit-license.php */ #ifndef _FU_TRACKER_H_ #define _FU_TRACKER_H_ /** @file FUTracker.h This file contains the FUTrackable base class and the related tracker template classes. */ #ifndef _FU_OBJECT_H_ #include "FUtils/FUObject.h" #endif // _FU_OBJECT_H_ class FUTracker; /** A trackable object. Each object holds a pointer to the trackers that track it. This pointer is useful so that the trackers can be notified if the object is released. @ingroup FUtils */ class FCOLLADA_EXPORT FUTrackable : public FUObject { private: DeclareObjectType(FUObject); // The objects tracking this one. typedef fm::pvector FUTrackerList; FUTrackerList trackers; public: /** Constructor. Although it is not an abstract class, this class is not meant to be used directly. */ FUTrackable(); /** Destructor. This function informs the trackers of this object's release. */ virtual ~FUTrackable(); /** Retrieves the number of tracker tracking the object. This can be used as an expensive reference counting mechanism. @return The number of trackers tracking the object. */ size_t GetTrackerCount() const { return trackers.size(); } protected: /** Detaches all the trackers of this object. The trackers will be notified that this object has been released. It is not recommended to call this function outside of the Release() function. */ void Detach(); private: friend class FUTracker; void AddTracker(FUTracker* tracker); void RemoveTracker(FUTracker* tracker); bool HasTracker(const FUTracker* tracker) const; }; /** An object set Each set has access to a list of unique objects. When the objects are created/released: they will inform the list. @ingroup FUtils */ class FCOLLADA_EXPORT FUTracker { public: /** Destructor. */ virtual ~FUTracker() {} /** Callback when an object tracked by this tracker is being released. @param object A tracked object. */ virtual void OnObjectReleased(FUTrackable* object) = 0; /** Retrieves whether an object is tracked by this tracker. @param object An object. */ virtual bool TracksObject(const FUTrackable* object) const { return object != NULL ? object->HasTracker(this) : false; } protected: /** Adds an object to be tracked. @param object The object to track. */ void TrackObject(FUTrackable* object) { if (object) object->AddTracker(this); } /** Stops tracking an object @param object The object to stop tracking. */ void UntrackObject(FUTrackable* object) { if (object) object->RemoveTracker(this); } }; /** A tracked object pointer The reverse idea of a smart pointer: if the object pointed to by the pointer is released, the pointer will become NULL. @ingroup FUtils */ template class FUTrackedPtr : public FUTracker { protected: /** The tracked pointer. */ ObjectClass* ptr; public: /** Copy constructor. - @param _ptr The object to track. This pointer can be NULL to indicate + @param pObj The object to track. This pointer can be NULL to indicate that no object should be tracked at this time. */ - FUTrackedPtr(ObjectClass* _ptr = NULL) : ptr(_ptr) + FUTrackedPtr(ObjectClass* pObj = nullptr) : ptr(pObj) { - if (ptr != NULL) FUTracker::TrackObject((FUTrackable*) ptr); - ptr = ptr; + if (pObj != nullptr) + FUTracker::TrackObject(static_cast(pObj)); } /** Destructor. Stops the tracking of the pointer. */ ~FUTrackedPtr() { - if (ptr != NULL) FUTracker::UntrackObject((FUTrackable*) ptr); - ptr = NULL; + if (ptr != nullptr) FUTracker::UntrackObject((FUTrackable*) ptr); + ptr = nullptr; } /** Assigns this tracking pointer a new object to track. @param _ptr The new object to track. @return This reference. */ FUTrackedPtr& operator=(ObjectClass* _ptr) { if (ptr != NULL) FUTracker::UntrackObject((FUTrackable*) ptr); ptr = _ptr; if (ptr != NULL) FUTracker::TrackObject((FUTrackable*) ptr); return *this; } inline FUTrackedPtr& operator=(const FUTrackedPtr& _ptr) { return operator=(_ptr.ptr); } /**< See above. */ /** Retrieves whether an object is tracked by this tracker. @param object An object. */ virtual bool TracksObject(const FUTrackable* object) const { return (FUTrackable*) ptr == object; } /** Accesses the tracked object. @return The tracked object. */ inline ObjectClass& operator*() { FUAssert(ptr != NULL, return *ptr); return *ptr; } inline const ObjectClass& operator*() const { FUAssert(ptr != NULL, return *ptr); return *ptr; } /**< See above. */ inline ObjectClass* operator->() { return ptr; } /**< See above. */ inline const ObjectClass* operator->() const { return ptr; } /**< See above. */ inline operator ObjectClass*() { return ptr; } /**< See above. */ inline operator const ObjectClass*() const { return ptr; } /**< See above. */ protected: /** Callback when an object tracked by this tracker is being released. @param object A contained object. */ virtual void OnObjectReleased(FUTrackable* object) { FUAssert(TracksObject(object), return); ptr = NULL; } }; /** An object list. Based on top of our modified version of the STL vector class, this contained object list holds pointers to some FUTrackable derived class and automatically removes objects when they are deleted. @ingroup FUtils */ template class FUTrackedList : private fm::pvector, FUTracker { public: typedef fm::pvector Parent; typedef ObjectClass* item; typedef const ObjectClass* const_item; typedef item* iterator; typedef const_item* const_iterator; /** Destructor. */ virtual ~FUTrackedList() { clear(); } /** Clears the object tracked by this object list. */ void clear() { for (iterator it = begin(); it != end(); ++it) { FUTracker::UntrackObject((FUTrackable*) (*it)); } Parent::clear(); } - + /** Retrieves the first element of the container. @return The first element in the container. */ ObjectClass*& front() { return (ObjectClass*&) Parent::front(); } const ObjectClass*& front() const { return (const ObjectClass*&) Parent::front(); } /**< See above. */ /** Retrieves the last element of the container. @return The last element in the container. */ ObjectClass*& back() { return (ObjectClass*&) Parent::back(); } const ObjectClass*& back() const { return (const ObjectClass*&) Parent::back(); } /**< See above. */ /** Retrieves an indexed object in the list. @param index An index. @return The given object. */ inline ObjectClass* at(size_t index) { return (ObjectClass*) Parent::at(index); } inline const ObjectClass* at(size_t index) const { return (const ObjectClass*) Parent::at(index); } /**< See above. */ template inline ObjectClass* operator[](INTEGER index) { return at(index); } /**< See above. */ template inline const ObjectClass* operator[](INTEGER index) const { return at(index); } /**< See above. */ /** Retrieves an iterator for the first element in the list. @return an iterator for the first element in the list. */ inline iterator begin() { return (iterator) Parent::begin(); } inline const_iterator begin() const { return (const_iterator) Parent::begin(); } /**< See above. */ - + /** Retrieves an iterator for the element after the last element in the list. @return an iterator for the element after the last element in the list. */ inline iterator end() { return (iterator) Parent::end(); } inline const_iterator end() const { return (const_iterator) Parent::end(); } /**< See above. */ - + /** Retrieves an iterator for a given element in the list. @param item An item of the list. @return An iterator for the given item. If the item is not found in the list, the end() iterator is returned. */ inline iterator find(const ObjectClass* item) { return (iterator) Parent::find(item); } inline const_iterator find(const ObjectClass* item) const { return (const_iterator) Parent::find(item); } /**< See above. */ /** Adds an object to the container's containment list. @param object An object to contain. */ inline void push_back(ObjectClass* object) { FUTracker::TrackObject((FUTrackable*) object); Parent::push_back(object); } /** Inserts an object in the container's containment list. @param _iterator The iterator after which to insert the object. @param object An object to insert. @return The iterator to the inserted object. */ iterator insert(iterator _iterator, ObjectClass* object) { FUTracker::TrackObject(object); return (iterator) Parent::insert(_iterator, object); } /** Inserts an object in the container's containment list. @param index Where to insert the object. @param object An object to insert. */ inline void insert(size_t index, ObjectClass* object) { insert(begin() + index, object); } /** Inserts a list of object in the container's containment list. @param _where The iterator after which to insert the object. @param _startIterator The iterator for the first object to insert. @param _endIterator The iterator just passed the last object. This object will not be inserted. */ template void insert(iterator _where, _It _startIterator, _It _endIterator) { if (_startIterator < _endIterator) { size_t relativeWhere = _where - begin(); size_t count = _endIterator - _startIterator; Parent::insert(Parent::begin() + relativeWhere, count); _where = begin() + relativeWhere; for (; _startIterator != _endIterator; ++_startIterator, ++_where) { *_where = const_cast((const ObjectClass*)(*_startIterator)); FUTracker::TrackObject(const_cast((const FUTrackable*) (*_startIterator))); } } } /** Removes the last value of the tracked object list. */ void pop_back() { if (!Parent::empty()) { FUTracker::UntrackObject(back()); Parent::pop_back(); } } - + /** Removes the value at the given position within the list. @param _it The list position for the value to remove. */ iterator erase(iterator _it) { FUTracker::UntrackObject((FUTrackable*) *_it); return (iterator) Parent::erase(_it); } /** Removes a range of values from the list. @param first The list position of the first value to remove. @param last The list position just passed the last value to remove. */ inline void erase(iterator first, iterator last) { for (iterator it = first; it != last; ++it) FUTracker::UntrackObject((FUTrackable*) *it); Parent::erase(first, last); } /** Removes a range of values from the list. @param first The index of the first value to remove. @param last The index just passed the last value to remove. */ inline void erase(size_t first, size_t last) { erase(begin() + first, begin() + last); } /** Removes a value contained within the list, once. @param value The value, contained within the list, to erase from it. @return Whether the value was found and erased from the list. */ inline bool erase(const ObjectClass* value) { iterator it = Parent::find(value); if (it != Parent::end()) { FUTracker::UntrackObject((FUTrackable*) *it); Parent::erase(it); return true; } return false; } /** Removes an indexed value contained within the list. @param index The index of the value to erase. */ inline void erase(size_t index) { erase(begin() + index); } /** Retrieves whether an object is contained by this container. @param object An object. */ virtual bool TracksObject(const FUTrackable* object) const { return Parent::contains((ObjectClass*) object); } /** Clones a list of tracked objects. This list will stop tracking all its current tracked objects and will start tracking the objects within the other list. @param other A second list of tracked objects. @return This list. */ FUTrackedList& operator= (const FUTrackedList& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } inline bool empty() const { return Parent::empty(); } /**< Inherited from pvector. */ inline size_t size() const { return Parent::size(); } /**< Inherited from pvector. */ void reserve(size_t count) { Parent::reserve(count); } /**< Inherited from pvector. */ inline bool contains(const ObjectClass* value) const { return Parent::contains(value); } /**< Inherited from pvector. */ /** Releases a value contained within a list. Use this function only if there is no duplicate pointers within the list. @param value The value, contained within the list, to release. @return Whether the value was found and released. */ inline bool release(const ObjectClass* value) { ObjectClass** it = find(value); if (it != Parent::end()) { erase(it); ((FUTrackable*) value)->Release(); return true; } return false; } /** Removes the first value of the tracked object list. */ void pop_front() { if (!Parent::empty()) { FUTracker::UntrackObject(front()); Parent::pop_front(); } } protected: /** Removes an object from the container's containment list. @param object A contained object. */ virtual void OnObjectReleased(FUTrackable* object) { FUAssert(TracksObject(object), return); Parent::erase((ObjectClass*) object); } }; #endif // _FU_TRACKER_H_ Index: ps/trunk/libraries/source/fcollada/lib/FCollada.lib =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/libraries/source/fcollada/lib/FColladaD.lib =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDAnimation.cpp =================================================================== --- ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDAnimation.cpp (revision 24321) +++ ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDAnimation.cpp (revision 24322) @@ -1,135 +1,135 @@ /* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America MIT License: http://www.opensource.org/licenses/mit-license.php */ /* Based on the FS Import classes: Copyright (C) 2005-2006 Feeling Software Inc Copyright (C) 2005-2006 Autodesk Media Entertainment MIT License: http://www.opensource.org/licenses/mit-license.php */ #include "StdAfx.h" #include "FCDocument/FCDocument.h" #include "FCDocument/FCDAnimation.h" #include "FCDocument/FCDAnimationChannel.h" #include "FCDocument/FCDAsset.h" // // FCDAnimation // ImplementObjectType(FCDAnimation); ImplementParameterObject(FCDAnimation, FCDAnimation, children, new FCDAnimation(parent->GetDocument(), parent)); ImplementParameterObject(FCDAnimation, FCDAnimationChannel, channels, new FCDAnimationChannel(parent->GetDocument(), parent)); FCDAnimation::FCDAnimation(FCDocument* document, FCDAnimation* _parent) : FCDEntity(document, "Animation") , parent(_parent) , InitializeParameterNoArg(children) , InitializeParameterNoArg(channels) { } FCDAnimation::~FCDAnimation() { // childNodes.clear(); parent = NULL; } FCDEntity* FCDAnimation::Clone(FCDEntity* _clone, bool cloneChildren) const { FCDAnimation* clone = NULL; if (_clone == NULL) _clone = clone = new FCDAnimation(const_cast(GetDocument()), NULL); else if (_clone->HasType(FCDAnimation::GetClassType())) clone = (FCDAnimation*) _clone; Parent::Clone(_clone, cloneChildren); if (clone != NULL) { // Clone the channels for (const FCDAnimationChannel** it = channels.begin(); it != channels.end(); ++it) { FCDAnimationChannel* clonedChannel = clone->AddChannel(); (*it)->Clone(clonedChannel); } if (cloneChildren) { // Clone the animation tree children for (const FCDAnimation** it = children.begin(); it != children.end(); ++it) { FCDAnimation* clonedChild = clone->AddChild(); (*it)->Clone(clonedChild, cloneChildren); } } } return _clone; } // Creates a new animation entity sub-tree contained within this animation entity tree. FCDAnimation* FCDAnimation::AddChild() { FCDAnimation* animation = new FCDAnimation(GetDocument(), this); children.push_back(animation); SetNewChildFlag(); return children.back(); } // Adds a new animation channel to this animation entity. FCDAnimationChannel* FCDAnimation::AddChannel() { FCDAnimationChannel* channel = new FCDAnimationChannel(GetDocument(), this); channels.push_back(channel); SetNewChildFlag(); return channels.back(); } // Look for an animation children with the given COLLADA Id. const FCDEntity* FCDAnimation::FindDaeId(const fm::string& daeId) const { if (GetDaeId() == daeId) return this; for (const FCDAnimation** it = children.begin(); it != children.end(); ++it) { const FCDEntity* found = (*it)->FindDaeId(daeId); if (found != NULL) return found; } return NULL; } void FCDAnimation::GetHierarchicalAssets(FCDAssetConstList& assets) const { for (const FCDAnimation* animation = this; animation != NULL; animation = animation->GetParent()) { // Retrieve the asset information structure for this node. const FCDAsset* asset = animation->GetAsset(); if (asset != NULL) assets.push_back(asset); } assets.push_back(GetDocument()->GetAsset()); } // Retrieve all the curves created under this animation element, in the animation tree void FCDAnimation::GetCurves(FCDAnimationCurveList& curves) { // Retrieve the curves for this animation tree element - for (const FCDAnimationChannel** it = (const FCDAnimationChannel**) channels.begin(); it != channels.end(); ++it) + for (const FCDAnimationChannel* const* it = channels.begin(); it != channels.end(); ++it) { size_t channelCurveCount = (*it)->GetCurveCount(); for (size_t i = 0; i < channelCurveCount; ++i) { curves.push_back((*it)->GetCurve(i)); } } // Retrieve the curves for the animation nodes under this one in the animation tree size_t childCount = children.size(); for (size_t i = 0; i < childCount; ++i) { children[i]->GetCurves(curves); } } Index: ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDControllerInstance.cpp =================================================================== --- ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDControllerInstance.cpp (revision 24321) +++ ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDControllerInstance.cpp (revision 24322) @@ -1,151 +1,151 @@ /* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America MIT License: http://www.opensource.org/licenses/mit-license.php */ #include "StdAfx.h" #include "FCDocument/FCDController.h" #include "FCDocument/FCDControllerInstance.h" #include "FCDocument/FCDSceneNode.h" #include "FCDocument/FCDSkinController.h" #include "FCDocument/FCDocument.h" // // FCDControllerInstance // ImplementObjectType(FCDControllerInstance); ImplementParameterObjectNoCtr(FCDControllerInstance, FCDSceneNode, joints); FCDControllerInstance::FCDControllerInstance(FCDocument* document, FCDSceneNode* parent, FCDEntity::Type entityType) : FCDGeometryInstance(document, parent, entityType) , InitializeParameterNoArg(joints) { } FCDControllerInstance::~FCDControllerInstance() { } FCDEntityInstance* FCDControllerInstance::Clone(FCDEntityInstance* _clone) const { FCDControllerInstance* clone = NULL; if (_clone == NULL) _clone = clone = new FCDControllerInstance(const_cast(GetDocument()), NULL, GetEntityType()); else if (_clone->HasType(FCDControllerInstance::GetClassType())) clone = (FCDControllerInstance*) _clone; Parent::Clone(_clone); if (clone != NULL) { // Clone the URI list. clone->skeletonRoots = skeletonRoots; // Clone the joint list. clone->joints = joints; } return _clone; } // Retrieves a list of all the root joints for the controller. void FCDControllerInstance::CalculateRootIds() { skeletonRoots.clear(); - for (const FCDSceneNode** itJ = (const FCDSceneNode**) joints.begin(); itJ != joints.end(); ++itJ) + for (const FCDSceneNode* const* itJ = joints.begin(); itJ != joints.end(); ++itJ) { const FCDSceneNode* joint = (*itJ); if (joint == NULL) continue; bool addToList = true; size_t parentCount = joint->GetParentCount(); for (size_t p = 0; p < parentCount; ++p) { const FCDSceneNode* parentJoint = joint->GetParent(p); if (FindJoint(parentJoint)) { addToList = false; break; } } if (addToList) { fstring utf16id = TO_FSTRING(joint->GetDaeId()); FUUri newRoot(FS("#") + utf16id); skeletonRoots.push_back(newRoot); } } } bool FCDControllerInstance::AddJoint(FCDSceneNode* j) { if (j != NULL) { j->SetJointFlag(true); AppendJoint(j); return true; } return false; } // Look for the information on a given joint bool FCDControllerInstance::FindJoint(const FCDSceneNode* joint) const { return joints.contains(joint); } size_t FCDControllerInstance::FindJointIndex(const FCDSceneNode* joint) const { size_t i = 0; for (const FCDSceneNode** itr = joints.begin(); itr != joints.end(); ++i, ++itr) { if (*itr == joint) return i; } return (size_t) ~0; } void FCDControllerInstance::AppendJoint(FCDSceneNode* j) { joints.push_back(j); } const FCDSkinController* FCDControllerInstance::FindSkin(const FCDEntity* entity) const { if (entity != NULL && entity->GetType() == FCDEntity::CONTROLLER) { const FCDController* controller = (const FCDController*) entity; if (controller->IsSkin()) { return controller->GetSkinController(); } else return FindSkin(controller->GetBaseTarget()); } return NULL; } void FCDControllerInstance::FindSkeletonNodes(FCDSceneNodeList& skeletonNodes) const { const FCDocument* document = GetDocument(); size_t numRoots = skeletonRoots.size(); skeletonNodes.reserve(numRoots); for (size_t i = 0; i < numRoots; ++i) { const FCDSceneNode* aRoot = document->FindSceneNode(TO_STRING(skeletonRoots[i].GetFragment()).c_str()); if (aRoot == NULL) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_UNKNOWN_JOINT, 0); } else skeletonNodes.push_back(const_cast(aRoot)); } // If we have no root, add the visual scene root. if (skeletonNodes.empty()) { skeletonNodes.push_back(const_cast(document->GetVisualSceneInstance())); } } Index: ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDExtra.cpp =================================================================== --- ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDExtra.cpp (revision 24321) +++ ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDExtra.cpp (revision 24322) @@ -1,413 +1,413 @@ /* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America MIT License: http://www.opensource.org/licenses/mit-license.php */ #include "StdAfx.h" #include "FCDocument/FCDocument.h" #include "FCDocument/FCDAnimated.h" #include "FCDocument/FCDExtra.h" #include "FColladaPlugin.h" namespace FCollada { extern FColladaPluginManager* pluginManager; } // // FCDExtra // ImplementObjectType(FCDExtra); ImplementParameterObject(FCDExtra, FCDEType, types, new FCDEType(parent->GetDocument(), parent, emptyCharString)); FCDExtra::FCDExtra(FCDocument* document, FUObject* _parent) : FCDObject(document) , parent(_parent) , InitializeParameterNoArg(types) { // Create the default extra type. types.push_back(new FCDEType(document, this, emptyCharString)); document->RegisterExtraTree(this); } FCDExtra::~FCDExtra() { GetDocument()->UnregisterExtraTree(this); } // Adds a type of the given name (or return the existing type with this name). FCDEType* FCDExtra::AddType(const char* name) { FCDEType* type = FindType(name); if (type == NULL) { type = new FCDEType(GetDocument(), this, emptyCharString); types.push_back(type); type->SetName(name); SetNewChildFlag(); } return type; } // Search for a profile-specific type const FCDEType* FCDExtra::FindType(const char* name) const { for (const FCDEType** itT = types.begin(); itT != types.end(); ++itT) { if (IsEquivalent((*itT)->GetName(), name)) return *itT; } return NULL; } bool FCDExtra::HasContent() const { if (types.empty()) return false; for (const FCDEType** itT = types.begin(); itT != types.end(); ++itT) { size_t techniqueCount = (*itT)->GetTechniqueCount(); for (size_t i = 0; i < techniqueCount; ++i) { const FCDETechnique* technique = (*itT)->GetTechnique(i); if (technique->GetChildNodeCount() > 0) return true; } } return false; } FCDExtra* FCDExtra::Clone(FCDExtra* clone) const { if (clone == NULL) clone = new FCDExtra(const_cast(GetDocument()), NULL); // Create all the types clone->types.reserve(types.size()); for (const FCDEType** itT = types.begin(); itT != types.end(); ++itT) { FCDEType* cloneT = clone->AddType((*itT)->GetName()); (*itT)->Clone(cloneT); } return clone; } // // FCDEType // ImplementObjectType(FCDEType); ImplementParameterObject(FCDEType, FCDETechnique, techniques, new FCDETechnique(parent->GetDocument(), parent, emptyCharString)); FCDEType::FCDEType(FCDocument* document, FCDExtra* _parent, const char* _name) : FCDObject(document) , parent(_parent) , InitializeParameter(name, _name) , InitializeParameterNoArg(techniques) { } FCDEType::~FCDEType() { } // Adds a technique of the given profile (or return the existing technique with this profile). FCDETechnique* FCDEType::AddTechnique(const char* profile) { FCDETechnique* technique = FindTechnique(profile); if (technique == NULL) { technique = new FCDETechnique(GetDocument(), this, profile); techniques.push_back(technique); SetNewChildFlag(); } return technique; } // Search for a profile-specific technique const FCDETechnique* FCDEType::FindTechnique(const char* profile) const { for (const FCDETechnique** itT = techniques.begin(); itT != techniques.end(); ++itT) { if (IsEquivalent((*itT)->GetProfile(), profile)) return *itT; } return NULL; } // Search for a root node with a specific element name const FCDENode* FCDEType::FindRootNode(const char* name) const { const FCDENode* rootNode = NULL; for (const FCDETechnique** itT = techniques.begin(); itT != techniques.end(); ++itT) { rootNode = (*itT)->FindChildNode(name); if (rootNode != NULL) break; } return rootNode; } FCDEType* FCDEType::Clone(FCDEType* clone) const { // If no clone is given: create one if (clone == NULL) { clone = new FCDEType(const_cast(GetDocument()), NULL, name->c_str()); } clone->techniques.reserve(techniques.size()); for (const FCDETechnique** itT = techniques.begin(); itT != techniques.end(); ++itT) { FCDETechnique* cloneT = clone->AddTechnique((*itT)->GetProfile()); (*itT)->Clone(cloneT); } return clone; } // // FCDENode // ImplementObjectType(FCDENode); ImplementParameterObject(FCDENode, FCDENode, children, new FCDENode(parent->GetDocument(), parent)); ImplementParameterObjectNoArg(FCDENode, FCDEAttribute, attributes); ImplementParameterObject(FCDENode, FCDAnimatedCustom, animated, new FCDAnimatedCustom(parent->GetDocument())); FCDENode::FCDENode(FCDocument* document, FCDENode* _parent) : FCDObject(document), parent(_parent) , InitializeParameterNoArg(name) , InitializeParameterNoArg(content) , InitializeParameterNoArg(children) , InitializeParameterNoArg(attributes) , InitializeParameterNoArg(animated) { animated = new FCDAnimatedCustom(this); } FCDENode::~FCDENode() { parent = NULL; } void FCDENode::SetContent(const fchar* _content) { // As COLLADA doesn't allow for mixed content, release all the children. while (!children.empty()) { children.back()->Release(); } content = _content; SetDirtyFlag(); } void FCDENode::SetAnimated(FCDAnimatedCustom* animatedCustom) { SAFE_RELEASE(animated); animated = animatedCustom; } // Search for a children with a specific name const FCDENode* FCDENode::FindChildNode(const char* name) const { for (const FCDENode** itN = children.begin(); itN != children.end(); ++itN) { if (IsEquivalent((*itN)->GetName(), name)) return (*itN); } return NULL; } void FCDENode::FindChildrenNodes(const char* name, FCDENodeList& nodes) const { for (const FCDENode** itN = children.begin(); itN != children.end(); ++itN) { if (IsEquivalent((*itN)->GetName(), name)) nodes.push_back(const_cast(*itN)); } } const FCDENode* FCDENode::FindParameter(const char* name) const { for (const FCDENode** itN = children.begin(); itN != children.end(); ++itN) { const FCDENode* node = (*itN); if (IsEquivalent(node->GetName(), name)) return node; } return NULL; } void FCDENode::FindParameters(FCDENodeList& nodes, StringList& names) { - for (const FCDENode** itN = (const FCDENode**) children.begin(); itN != children.end(); ++itN) + for (const FCDENode* const* itN = children.begin(); itN != children.end(); ++itN) { const FCDENode* node = (*itN); if (node->GetChildNodeCount() == 0) { nodes.push_back(const_cast(node)); names.push_back(node->GetName()); } } } void FCDENode::SetName(fm::string& _name) { name = _name; CleanName(name); SetDirtyFlag(); } void FCDENode::CleanName(fm::string& n) { size_t length = n.length(); if (length == 0) return; // First character must be alphabetic or the underscore. if (n[0] != '_' && !(n[0] >= 'a' && n[0] <= 'z') && !(n[0] >= 'A' && n[0] <= 'Z')) { n[0] = '_'; } // Other characters must be alpha-numeric or the underscore. for (size_t i = 1; i < length; ++i) { char& c = n[i]; if (c != '_' && !(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9')) { c = '_'; } } } const fchar* FCDENode::GetContent() const { return content->c_str(); } // Adds a new attribute to this extra tree node. FCDEAttribute* FCDENode::AddAttribute(fm::string& _name, const fchar* _value) { CleanName(_name); FCDEAttribute* attribute = FindAttribute(_name.c_str()); if (attribute == NULL) { attribute = new FCDEAttribute(); attributes.push_back(attribute); attribute->SetName(_name); } attribute->SetValue(_value); SetNewChildFlag(); return attribute; } // Search for an attribute with a specific name const FCDEAttribute* FCDENode::FindAttribute(const char* name) const { for (const FCDEAttribute** itA = attributes.begin(); itA != attributes.end(); ++itA) { if (IsEquivalent((*itA)->GetName(), name)) return (*itA); } return NULL; } const fstring& FCDENode::ReadAttribute(const char* name) const { const FCDEAttribute* attribute = FindAttribute(name); return (attribute != NULL) ? attribute->GetValue() : emptyFString; } FCDENode* FCDENode::AddParameter(const char* name, const fchar* value) { FCDENode* parameter = AddChildNode(); parameter->SetName(name); parameter->SetContent(value); SetNewChildFlag(); return parameter; } FCDENode* FCDENode::Clone(FCDENode* clone) const { if (clone == NULL) return NULL; clone->name = name; clone->content = content; clone->attributes.reserve(attributes.size()); for (const FCDEAttribute** itA = attributes.begin(); itA != attributes.end(); ++itA) { clone->AddAttribute((*itA)->GetName(), (*itA)->GetValue()); } clone->children.reserve(children.size()); for (const FCDENode** itC = children.begin(); itC != children.end(); ++itC) { FCDENode* clonedChild = clone->AddChildNode(); (*itC)->Clone(clonedChild); } // TODO: Clone the animated custom.. return clone; } FCDENode* FCDENode::AddChildNode() { FCDENode* node = new FCDENode(GetDocument(), this); children.push_back(node); SetNewChildFlag(); return node; } FCDENode* FCDENode::AddChildNode(const char* name) { FCDENode* node = new FCDENode(GetDocument(), this); children.push_back(node); node->SetName(name); SetNewChildFlag(); return node; } // // FCDETechnique // ImplementObjectType(FCDETechnique); ImplementParameterObjectNoCtr(FCDETechnique, FUObject, pluginOverride); FCDETechnique::FCDETechnique(FCDocument* document, FCDEType* _parent, const char* _profile) : FCDENode(document, NULL), parent(_parent) , InitializeParameterNoArg(pluginOverride) , InitializeParameter(profile, _profile) { } FCDETechnique::~FCDETechnique() {} FCDENode* FCDETechnique::Clone(FCDENode* clone) const { if (clone == NULL) { clone = new FCDETechnique(const_cast(GetDocument()), NULL, profile->c_str()); } else if (clone->GetObjectType().Includes(FCDETechnique::GetClassType())) { ((FCDETechnique*) clone)->profile = profile; } FCDENode::Clone(clone); return clone; } // // FCDEAttribute // FCDEAttribute::FCDEAttribute() : FUParameterizable() , InitializeParameterNoArg(name) , InitializeParameterNoArg(value) { } FCDEAttribute::FCDEAttribute(const char* _name, const fchar* _value) : FUParameterizable() , InitializeParameter(name, _name) , InitializeParameter(value, _value) { } Index: ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDMaterialInstance.cpp =================================================================== --- ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDMaterialInstance.cpp (revision 24321) +++ ps/trunk/libraries/source/fcollada/src/FCollada/FCDocument/FCDMaterialInstance.cpp (revision 24322) @@ -1,198 +1,198 @@ /* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America MIT License: http://www.opensource.org/licenses/mit-license.php */ /* Based on the FS Import classes: Copyright (C) 2005-2006 Feeling Software Inc Copyright (C) 2005-2006 Autodesk Media Entertainment MIT License: http://www.opensource.org/licenses/mit-license.php */ #include "StdAfx.h" #include "FCDocument/FCDocument.h" #include "FCDocument/FCDEffectParameter.h" #include "FCDocument/FCDEffectParameterFactory.h" #include "FCDocument/FCDExtra.h" #include "FCDocument/FCDGeometry.h" #include "FCDocument/FCDGeometryMesh.h" #include "FCDocument/FCDGeometryPolygons.h" #include "FCDocument/FCDController.h" #include "FCDocument/FCDGeometryMesh.h" #include "FCDocument/FCDGeometryPolygons.h" #include "FCDocument/FCDMaterial.h" #include "FCDocument/FCDMaterialInstance.h" // // FCDMaterialInstanceBind // ImplementObjectType(FCDMaterialInstanceBind); FCDMaterialInstanceBind::FCDMaterialInstanceBind() : FUParameterizable() , InitializeParameterNoArg(semantic) , InitializeParameterNoArg(target) { } FCDMaterialInstanceBind::~FCDMaterialInstanceBind() { } // // FCDMaterialInstanceBindVertexInput // ImplementObjectType(FCDMaterialInstanceBindVertexInput); FCDMaterialInstanceBindVertexInput::FCDMaterialInstanceBindVertexInput() : FUParameterizable() , InitializeParameterNoArg(semantic) , InitializeParameter(inputSemantic, FUDaeGeometryInput::TEXCOORD) , InitializeParameter(inputSet, 0) { } FCDMaterialInstanceBindVertexInput::~FCDMaterialInstanceBindVertexInput() { } // // FCDMaterialInstance // ImplementObjectType(FCDMaterialInstance); ImplementParameterObjectNoArg(FCDMaterialInstance, FCDMaterialInstanceBind, bindings) ImplementParameterObjectNoArg(FCDMaterialInstance, FCDMaterialInstanceBindVertexInput, vertexBindings) ImplementParameterObjectNoArg(FCDMaterialInstance, FCDMaterialInstanceBindTextureSurface, texSurfBindings) FCDMaterialInstance::FCDMaterialInstance(FCDocument* document, FCDEntityInstance* _parent) : FCDEntityInstance(document, _parent->GetParent(), FCDEntity::MATERIAL), parent(_parent) , InitializeParameterNoArg(semantic) , InitializeParameterNoArg(bindings) , InitializeParameterNoArg(vertexBindings) { } FCDMaterialInstance::~FCDMaterialInstance() { parent = NULL; } FCDObject* FCDMaterialInstance::GetGeometryTarget() { if (parent != NULL && parent->GetEntity() != NULL) { FCDEntity* e = parent->GetEntity(); if (e->HasType(FCDController::GetClassType())) { e = ((FCDController*) e)->GetBaseGeometry(); } if (e->HasType(FCDGeometry::GetClassType())) { FCDGeometry* geometry = (FCDGeometry*) e; if (geometry->IsMesh()) { FCDGeometryMesh* mesh = geometry->GetMesh(); size_t polygonsCount = mesh->GetPolygonsCount(); for (size_t i = 0; i < polygonsCount; ++i) { FCDGeometryPolygons* polygons = mesh->GetPolygons(i); if (IsEquivalent(polygons->GetMaterialSemantic(), semantic)) { return polygons; } } } } } return NULL; } const FCDMaterialInstanceBind* FCDMaterialInstance::FindBinding(const char* semantic) { - for (const FCDMaterialInstanceBind** it = (const FCDMaterialInstanceBind**) bindings.begin(); it != bindings.end(); ++it) + for (const FCDMaterialInstanceBind* const* it = bindings.begin(); it != bindings.end(); ++it) { if (IsEquivalent((*it)->semantic, semantic)) return (*it); } return NULL; } FCDMaterialInstanceBindVertexInput* FCDMaterialInstance::AddVertexInputBinding() { FCDMaterialInstanceBindVertexInput* out = new FCDMaterialInstanceBindVertexInput(); vertexBindings.push_back(out); SetNewChildFlag(); return vertexBindings.back(); } FCDMaterialInstanceBindVertexInput* FCDMaterialInstance::AddVertexInputBinding(const char* semantic, FUDaeGeometryInput::Semantic inputSemantic, int32 inputSet) { FCDMaterialInstanceBindVertexInput* vbinding = AddVertexInputBinding(); vbinding->semantic = semantic; vbinding->inputSemantic = inputSemantic; vbinding->inputSet = inputSet; return vbinding; } const FCDMaterialInstanceBindVertexInput* FCDMaterialInstance::FindVertexInputBinding(const char* semantic) const { for (const FCDMaterialInstanceBindVertexInput** it = vertexBindings.begin(); it != vertexBindings.end(); ++it) { if (IsEquivalent((*it)->semantic, semantic)) return (*it); } return NULL; } FCDMaterialInstanceBind* FCDMaterialInstance::AddBinding() { FCDMaterialInstanceBind* out = new FCDMaterialInstanceBind(); bindings.push_back(out); SetNewChildFlag(); return bindings.back(); } FCDMaterialInstanceBind* FCDMaterialInstance::AddBinding(const char* semantic, const char* target) { FCDMaterialInstanceBind* binding = AddBinding(); binding->semantic = semantic; binding->target = target; return binding; } void FCDMaterialInstance::RemoveBinding(size_t index) { FUAssert(index < bindings.size(), return); bindings.erase(index); } FCDEntityInstance* FCDMaterialInstance::Clone(FCDEntityInstance* _clone) const { FCDMaterialInstance* clone = NULL; if (_clone == NULL) clone = new FCDMaterialInstance(const_cast(GetDocument()), NULL); else if (!_clone->HasType(FCDMaterialInstance::GetClassType())) return Parent::Clone(_clone); else clone = (FCDMaterialInstance*) _clone; Parent::Clone(clone); // Clone the bindings and the semantic information. clone->semantic = semantic; size_t bindingCount = bindings.size(); for (size_t b = 0; b < bindingCount; ++b) { const FCDMaterialInstanceBind* bind = bindings[b]; clone->AddBinding(*bind->semantic, *bind->target); } bindingCount = vertexBindings.size(); for (size_t b = 0; b < bindingCount; ++b) { const FCDMaterialInstanceBindVertexInput* bind = vertexBindings[b]; clone->AddVertexInputBinding(*bind->semantic, (FUDaeGeometryInput::Semantic) *bind->inputSemantic, *bind->inputSet); } return clone; } Index: ps/trunk/libraries/source/fcollada/src/FCollada/FUtils/FUTracker.h =================================================================== --- ps/trunk/libraries/source/fcollada/src/FCollada/FUtils/FUTracker.h (revision 24321) +++ ps/trunk/libraries/source/fcollada/src/FCollada/FUtils/FUTracker.h (revision 24322) @@ -1,378 +1,378 @@ /* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America - + MIT License: http://www.opensource.org/licenses/mit-license.php */ #ifndef _FU_TRACKER_H_ #define _FU_TRACKER_H_ /** @file FUTracker.h This file contains the FUTrackable base class and the related tracker template classes. */ #ifndef _FU_OBJECT_H_ #include "FUtils/FUObject.h" #endif // _FU_OBJECT_H_ class FUTracker; /** A trackable object. Each object holds a pointer to the trackers that track it. This pointer is useful so that the trackers can be notified if the object is released. @ingroup FUtils */ class FCOLLADA_EXPORT FUTrackable : public FUObject { private: DeclareObjectType(FUObject); // The objects tracking this one. typedef fm::pvector FUTrackerList; FUTrackerList trackers; public: /** Constructor. Although it is not an abstract class, this class is not meant to be used directly. */ FUTrackable(); /** Destructor. This function informs the trackers of this object's release. */ virtual ~FUTrackable(); /** Retrieves the number of tracker tracking the object. This can be used as an expensive reference counting mechanism. @return The number of trackers tracking the object. */ size_t GetTrackerCount() const { return trackers.size(); } protected: /** Detaches all the trackers of this object. The trackers will be notified that this object has been released. It is not recommended to call this function outside of the Release() function. */ void Detach(); private: friend class FUTracker; void AddTracker(FUTracker* tracker); void RemoveTracker(FUTracker* tracker); bool HasTracker(const FUTracker* tracker) const; }; /** An object set Each set has access to a list of unique objects. When the objects are created/released: they will inform the list. @ingroup FUtils */ class FCOLLADA_EXPORT FUTracker { public: /** Destructor. */ virtual ~FUTracker() {} /** Callback when an object tracked by this tracker is being released. @param object A tracked object. */ virtual void OnObjectReleased(FUTrackable* object) = 0; /** Retrieves whether an object is tracked by this tracker. @param object An object. */ virtual bool TracksObject(const FUTrackable* object) const { return object != NULL ? object->HasTracker(this) : false; } protected: /** Adds an object to be tracked. @param object The object to track. */ void TrackObject(FUTrackable* object) { if (object) object->AddTracker(this); } /** Stops tracking an object @param object The object to stop tracking. */ void UntrackObject(FUTrackable* object) { if (object) object->RemoveTracker(this); } }; /** A tracked object pointer The reverse idea of a smart pointer: if the object pointed to by the pointer is released, the pointer will become NULL. @ingroup FUtils */ template class FUTrackedPtr : public FUTracker { protected: /** The tracked pointer. */ ObjectClass* ptr; public: /** Copy constructor. - @param _ptr The object to track. This pointer can be NULL to indicate + @param pObj The object to track. This pointer can be NULL to indicate that no object should be tracked at this time. */ - FUTrackedPtr(ObjectClass* _ptr = NULL) : ptr(_ptr) + FUTrackedPtr(ObjectClass* pObj = nullptr) : ptr(pObj) { - if (ptr != NULL) FUTracker::TrackObject((FUTrackable*) ptr); - ptr = ptr; + if (pObj != nullptr) + FUTracker::TrackObject(static_cast(pObj)); } /** Destructor. Stops the tracking of the pointer. */ ~FUTrackedPtr() { - if (ptr != NULL) FUTracker::UntrackObject((FUTrackable*) ptr); - ptr = NULL; + if (ptr != nullptr) FUTracker::UntrackObject((FUTrackable*) ptr); + ptr = nullptr; } /** Assigns this tracking pointer a new object to track. @param _ptr The new object to track. @return This reference. */ FUTrackedPtr& operator=(ObjectClass* _ptr) { if (ptr != NULL) FUTracker::UntrackObject((FUTrackable*) ptr); ptr = _ptr; if (ptr != NULL) FUTracker::TrackObject((FUTrackable*) ptr); return *this; } inline FUTrackedPtr& operator=(const FUTrackedPtr& _ptr) { return operator=(_ptr.ptr); } /**< See above. */ /** Retrieves whether an object is tracked by this tracker. @param object An object. */ virtual bool TracksObject(const FUTrackable* object) const { return (FUTrackable*) ptr == object; } /** Accesses the tracked object. @return The tracked object. */ inline ObjectClass& operator*() { FUAssert(ptr != NULL, return *ptr); return *ptr; } inline const ObjectClass& operator*() const { FUAssert(ptr != NULL, return *ptr); return *ptr; } /**< See above. */ inline ObjectClass* operator->() { return ptr; } /**< See above. */ inline const ObjectClass* operator->() const { return ptr; } /**< See above. */ inline operator ObjectClass*() { return ptr; } /**< See above. */ inline operator const ObjectClass*() const { return ptr; } /**< See above. */ protected: /** Callback when an object tracked by this tracker is being released. @param object A contained object. */ virtual void OnObjectReleased(FUTrackable* object) { FUAssert(TracksObject(object), return); ptr = NULL; } }; /** An object list. Based on top of our modified version of the STL vector class, this contained object list holds pointers to some FUTrackable derived class and automatically removes objects when they are deleted. @ingroup FUtils */ template class FUTrackedList : private fm::pvector, FUTracker { public: typedef fm::pvector Parent; typedef ObjectClass* item; typedef const ObjectClass* const_item; typedef item* iterator; typedef const_item* const_iterator; /** Destructor. */ virtual ~FUTrackedList() { clear(); } /** Clears the object tracked by this object list. */ void clear() { for (iterator it = begin(); it != end(); ++it) { FUTracker::UntrackObject((FUTrackable*) (*it)); } Parent::clear(); } - + /** Retrieves the first element of the container. @return The first element in the container. */ ObjectClass*& front() { return (ObjectClass*&) Parent::front(); } const ObjectClass*& front() const { return (const ObjectClass*&) Parent::front(); } /**< See above. */ /** Retrieves the last element of the container. @return The last element in the container. */ ObjectClass*& back() { return (ObjectClass*&) Parent::back(); } const ObjectClass*& back() const { return (const ObjectClass*&) Parent::back(); } /**< See above. */ /** Retrieves an indexed object in the list. @param index An index. @return The given object. */ inline ObjectClass* at(size_t index) { return (ObjectClass*) Parent::at(index); } inline const ObjectClass* at(size_t index) const { return (const ObjectClass*) Parent::at(index); } /**< See above. */ template inline ObjectClass* operator[](INTEGER index) { return at(index); } /**< See above. */ template inline const ObjectClass* operator[](INTEGER index) const { return at(index); } /**< See above. */ /** Retrieves an iterator for the first element in the list. @return an iterator for the first element in the list. */ inline iterator begin() { return (iterator) Parent::begin(); } inline const_iterator begin() const { return (const_iterator) Parent::begin(); } /**< See above. */ - + /** Retrieves an iterator for the element after the last element in the list. @return an iterator for the element after the last element in the list. */ inline iterator end() { return (iterator) Parent::end(); } inline const_iterator end() const { return (const_iterator) Parent::end(); } /**< See above. */ - + /** Retrieves an iterator for a given element in the list. @param item An item of the list. @return An iterator for the given item. If the item is not found in the list, the end() iterator is returned. */ inline iterator find(const ObjectClass* item) { return (iterator) Parent::find(item); } inline const_iterator find(const ObjectClass* item) const { return (const_iterator) Parent::find(item); } /**< See above. */ /** Adds an object to the container's containment list. @param object An object to contain. */ inline void push_back(ObjectClass* object) { FUTracker::TrackObject((FUTrackable*) object); Parent::push_back(object); } /** Inserts an object in the container's containment list. @param _iterator The iterator after which to insert the object. @param object An object to insert. @return The iterator to the inserted object. */ iterator insert(iterator _iterator, ObjectClass* object) { FUTracker::TrackObject(object); return (iterator) Parent::insert(_iterator, object); } /** Inserts an object in the container's containment list. @param index Where to insert the object. @param object An object to insert. */ inline void insert(size_t index, ObjectClass* object) { insert(begin() + index, object); } /** Inserts a list of object in the container's containment list. @param _where The iterator after which to insert the object. @param _startIterator The iterator for the first object to insert. @param _endIterator The iterator just passed the last object. This object will not be inserted. */ template void insert(iterator _where, _It _startIterator, _It _endIterator) { if (_startIterator < _endIterator) { size_t relativeWhere = _where - begin(); size_t count = _endIterator - _startIterator; Parent::insert(Parent::begin() + relativeWhere, count); _where = begin() + relativeWhere; for (; _startIterator != _endIterator; ++_startIterator, ++_where) { *_where = const_cast((const ObjectClass*)(*_startIterator)); FUTracker::TrackObject(const_cast((const FUTrackable*) (*_startIterator))); } } } /** Removes the last value of the tracked object list. */ void pop_back() { if (!Parent::empty()) { FUTracker::UntrackObject(back()); Parent::pop_back(); } } - + /** Removes the value at the given position within the list. @param _it The list position for the value to remove. */ iterator erase(iterator _it) { FUTracker::UntrackObject((FUTrackable*) *_it); return (iterator) Parent::erase(_it); } /** Removes a range of values from the list. @param first The list position of the first value to remove. @param last The list position just passed the last value to remove. */ inline void erase(iterator first, iterator last) { for (iterator it = first; it != last; ++it) FUTracker::UntrackObject((FUTrackable*) *it); Parent::erase(first, last); } /** Removes a range of values from the list. @param first The index of the first value to remove. @param last The index just passed the last value to remove. */ inline void erase(size_t first, size_t last) { erase(begin() + first, begin() + last); } /** Removes a value contained within the list, once. @param value The value, contained within the list, to erase from it. @return Whether the value was found and erased from the list. */ inline bool erase(const ObjectClass* value) { iterator it = Parent::find(value); if (it != Parent::end()) { FUTracker::UntrackObject((FUTrackable*) *it); Parent::erase(it); return true; } return false; } /** Removes an indexed value contained within the list. @param index The index of the value to erase. */ inline void erase(size_t index) { erase(begin() + index); } /** Retrieves whether an object is contained by this container. @param object An object. */ virtual bool TracksObject(const FUTrackable* object) const { return Parent::contains((ObjectClass*) object); } /** Clones a list of tracked objects. This list will stop tracking all its current tracked objects and will start tracking the objects within the other list. @param other A second list of tracked objects. @return This list. */ FUTrackedList& operator= (const FUTrackedList& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } inline bool empty() const { return Parent::empty(); } /**< Inherited from pvector. */ inline size_t size() const { return Parent::size(); } /**< Inherited from pvector. */ void reserve(size_t count) { Parent::reserve(count); } /**< Inherited from pvector. */ inline bool contains(const ObjectClass* value) const { return Parent::contains(value); } /**< Inherited from pvector. */ /** Releases a value contained within a list. Use this function only if there is no duplicate pointers within the list. @param value The value, contained within the list, to release. @return Whether the value was found and released. */ inline bool release(const ObjectClass* value) { ObjectClass** it = find(value); if (it != Parent::end()) { erase(it); ((FUTrackable*) value)->Release(); return true; } return false; } /** Removes the first value of the tracked object list. */ void pop_front() { if (!Parent::empty()) { FUTracker::UntrackObject(front()); Parent::pop_front(); } } protected: /** Removes an object from the container's containment list. @param object A contained object. */ virtual void OnObjectReleased(FUTrackable* object) { FUAssert(TracksObject(object), return); Parent::erase((ObjectClass*) object); } }; #endif // _FU_TRACKER_H_