2 * \file scene_class.cpp
4 * \date 2012-08-20 09:07GMT
5 * \author Jan Boon (Kaetemi)
10 * Copyright (C) 2012 by authors
12 * This file is part of RYZOM CORE PIPELINE.
13 * RYZOM CORE PIPELINE is free software: you can redistribute it
14 * and/or modify it under the terms of the GNU Affero General Public
15 * License as published by the Free Software Foundation, either
16 * version 3 of the License, or (at your option) any later version.
18 * RYZOM CORE PIPELINE is distributed in the hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
20 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
23 * You should have received a copy of the GNU Affero General Public
24 * License along with RYZOM CORE PIPELINE. If not, see
25 * <http://www.gnu.org/licenses/>.
28 #include <nel/misc/types_nl.h>
29 #include "scene_class.h"
35 // #include <nel/misc/debug.h>
40 // using namespace NLMISC;
45 ////////////////////////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////////////////////////
47 ////////////////////////////////////////////////////////////////////////
49 // Elevate warnings to errors in this file for stricter reading
51 #define nlwarning nlerror
53 // Elevate debug to error in this file for debugging
55 // #define nldebug nlerror
60 ////////////////////////////////////////////////////////////////////////
61 ////////////////////////////////////////////////////////////////////////
62 ////////////////////////////////////////////////////////////////////////
64 CSceneClass::CSceneClass(CScene
*scene
) : m_Scene(scene
)
69 CSceneClass::~CSceneClass()
71 if (!m_ChunksOwnsPointers
)
73 for (TStorageObjectContainer::iterator it
= m_OrphanedChunks
.begin(), end
= m_OrphanedChunks
.end(); it
!= end
; ++it
)
75 m_OrphanedChunks
.clear();
76 for (std::vector
<IStorageObject
*>::iterator it
= m_ArchivedChunks
.begin(), end
= m_ArchivedChunks
.end(); it
!= end
; ++it
)
78 m_ArchivedChunks
.clear();
82 std::string
CSceneClass::className() const
84 return classDesc()->internalName();
87 void CSceneClass::toString(std::ostream
&ostream
, const std::string
&pad
) const
89 if (m_ChunksOwnsPointers
)
91 CStorageContainer::toString(ostream
, pad
);
98 ss
<< std::hex
<< std::setfill('0');
99 ss
<< std::setw(16) << (uint64
)(void *)this;
103 ostream
<< "(" << className() << ": " << ucstring(classDesc()->displayName()).toUtf8() << ", " << classDesc()->classId().toString() << ", 0x";
105 std::stringstream ss
;
106 ss
<< std::hex
<< std::setfill('0');
107 ss
<< std::setw(8) << classDesc()->superClassId();
110 ostream
<< ", " << ucstring(classDesc()->dllPluginDesc()->internalName()).toUtf8() << ") [" << m_OrphanedChunks
.size() << "] { ";
111 toStringLocal(ostream
, pad
);
113 std::string padpad
= pad
+ "\t";
115 for (TStorageObjectContainer::const_iterator it
= m_OrphanedChunks
.begin(), end
= m_OrphanedChunks
.end(); it
!= end
; ++it
)
117 std::stringstream ss
;
118 ss
<< std::hex
<< std::setfill('0');
119 ss
<< std::setw(4) << it
->first
;
120 ostream
<< "\n" << pad
<< "Orphan[" << i
<< "] 0x" << ss
.str() << ": ";
121 it
->second
->toString(ostream
, padpad
);
128 void CSceneClass::parse(uint16 version
, uint filter
)
130 // Cannot be parsed yet
131 if (!m_ChunksOwnsPointers
) { nlerror("Already parsed"); return; } // Already parsed, illegal to call twice
133 // Parse all child chunks
134 CStorageContainer::parse(version
);
136 // Orphanize all child chunk
137 m_OrphanedChunks
.insert(m_OrphanedChunks
.end(), m_Chunks
.begin(), m_Chunks
.end());
140 m_ChunksOwnsPointers
= false;
142 // Inheriting classes take control from here on, they should check
143 // m_ChunksOwnsPointers to be false before taking action, in case
144 // a subclass called disown due to failure.
147 void CSceneClass::clean()
149 if (m_ChunksOwnsPointers
) { nldebug("Not parsed, or disowned"); return; } // Must have local ownership, parsing may have failed
150 if (m_Chunks
.size() == 0 && m_OrphanedChunks
.size() != 0) { nlwarning("Already cleaned"); return; } // Already cleaned, should not call twice, not reliable because not all chunks have child chunks
152 // Clear unneeded references from the parent
155 // Clean owned child chunks
156 for (TStorageObjectContainer::const_iterator it
= m_OrphanedChunks
.begin(), end
= m_OrphanedChunks
.end(); it
!= end
; ++it
)
158 if (it
->second
->isContainer())
160 static_cast<CStorageContainer
*>(it
->second
)->clean();
164 // Erase archived chunks, they must have been parsed perfectly
165 for (std::vector
<IStorageObject
*>::iterator it
= m_ArchivedChunks
.begin(), end
= m_ArchivedChunks
.end(); it
!= end
; ++it
)
167 m_ArchivedChunks
.clear();
170 void CSceneClass::build(uint16 version
, uint filter
)
172 // Must be clean first
173 if (!m_ChunksOwnsPointers
&& m_Chunks
.size() != 0) { nlerror("Not cleaned"); return; } // Cannot call twice, illegal call
174 if (m_Chunks
.size() != 0) { nldebug("Not parsed, or disowned"); return; } // Don't have local ownership, parsing may have failed, the built version is implicitly up to date
176 // Store orphan chunks
177 m_Chunks
.insert(m_Chunks
.end(), m_OrphanedChunks
.begin(), m_OrphanedChunks
.end());
179 // Build the orphan chunks (this is a little trick to do it this
180 // way here, don't do this from subclasses)
181 CStorageContainer::build(version
);
183 // Set the insertion pointer before the orphans
184 m_PutChunkInsert
= m_Chunks
.begin();
186 // Inheriting classes take control from here on, so the build is
187 // called to owned subclasses from the putChunk function.
190 void CSceneClass::disown()
192 if (m_ChunksOwnsPointers
) { nldebug("Not parsed"); }
193 if (!m_ChunksOwnsPointers
&& (m_Chunks
.size() < m_OrphanedChunks
.size())) { nlerror("Not built"); return; } // If chunks is not the owner, built chunks must match the parsed data. This check is not fully reliable
195 // Clear local references
196 m_OrphanedChunks
.clear();
197 m_ArchivedChunks
.clear();
200 m_ChunksOwnsPointers
= true;
203 CStorageContainer::disown();
206 void CSceneClass::init()
208 // Nothing to do here!
211 IStorageObject
*CSceneClass::createChunkById(uint16 id
, bool container
)
213 return CStorageContainer::createChunkById(id
, container
);
216 const ucstring
CSceneClass::DisplayName
= ucstring("Invalid Scene Class");
217 const char *CSceneClass::InternalName
= "SceneClass";
218 const NLMISC::CClassId
CSceneClass::ClassId
= NLMISC::CClassId::Null
; // This class is invalid
219 const TSClassId
CSceneClass::SuperClassId
= 0x0000; // This class is invalid
222 static const CSceneClassDesc
<CSceneClass
> SceneClassDesc(static_cast<const IDllPluginDescInternal
*>(&DllPluginDescBuiltin
));
223 } /* anonymous namespace */
225 bool CSceneClass::inherits(const NLMISC::CClassId classId
) const
230 const ISceneClassDesc
*CSceneClass::classDesc() const
232 return static_cast<const ISceneClassDesc
*>(&SceneClassDesc
);
235 void CSceneClass::toStringLocal(std::ostream
&ostream
, const std::string
&pad
, uint filter
) const
237 // Nothing to do here...
240 IStorageObject
*CSceneClass::getChunk(uint16 id
)
242 if (m_OrphanedChunks
.begin()->first
== id
)
244 IStorageObject
*result
= m_OrphanedChunks
.begin()->second
;
245 m_OrphanedChunks
.pop_front();
250 for (TStorageObjectContainer::iterator it
= m_OrphanedChunks
.begin(), end
= m_OrphanedChunks
.end(); it
!= end
; ++it
)
254 nlwarning("Try to get chunk with 0x%x id, but found 0x%x instead. Found the correct chunk at a different position. Unknown chunks, or chunks out of order", (uint32
)id
, (uint32
)m_OrphanedChunks
.begin()->first
);
255 IStorageObject
*result
= it
->second
;
256 m_OrphanedChunks
.erase(it
);
261 // nldebug("Chunk 0x%x not found, this is allowed, returning NULL", (uint32)id);
265 void CSceneClass::putChunk(uint16 id
, IStorageObject
*storageObject
)
267 if (storageObject
->isContainer())
269 static_cast<CStorageContainer
*>(storageObject
)->build(VersionUnknown
); // FIXME
271 m_OrphanedChunks
.insert(m_PutChunkInsert
, TStorageObjectWithId(id
, storageObject
));
274 uint16
CSceneClass::peekChunk()
276 if (m_OrphanedChunks
.size())
277 return m_OrphanedChunks
.begin()->first
;
281 ////////////////////////////////////////////////////////////////////////
282 ////////////////////////////////////////////////////////////////////////
283 ////////////////////////////////////////////////////////////////////////
285 } /* namespace MAX */
286 } /* namespace PIPELINE */