Added: #1440 Initial parsing of references

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 12 years ago
parent c037ac9334
commit 12690604ee

@ -56,7 +56,7 @@ namespace BUILTIN {
// Chunk identifiers // Chunk identifiers
#define PMB_REFERENCES_2034_CHUNK_ID 0x2034 #define PMB_REFERENCES_2034_CHUNK_ID 0x2034
#define PMB_REFERENCES_2035_CHUNK_ID 0x2034 #define PMB_REFERENCES_2035_CHUNK_ID 0x2035
#define PMB_204B_EQUALS_2E_CHUNK_ID 0x204B #define PMB_204B_EQUALS_2E_CHUNK_ID 0x204B
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -70,7 +70,15 @@ CReferenceMaker::CReferenceMaker()
CReferenceMaker::~CReferenceMaker() CReferenceMaker::~CReferenceMaker()
{ {
if (!m_ChunksOwnsPointers)
{
delete m_References2034;
m_References2034 = NULL;
delete m_References2035;
m_References2035 = NULL;
delete m_204B_Equals_2E;
m_204B_Equals_2E = NULL;
}
} }
const ucchar *CReferenceMaker::DisplayName = ucstring("ReferenceMaker").c_str(); const ucchar *CReferenceMaker::DisplayName = ucstring("ReferenceMaker").c_str();
@ -84,20 +92,38 @@ const CReferenceMakerSuperClassDesc ReferenceMakerSuperClassDesc(&ReferenceMaker
void CReferenceMaker::parse(uint16 version, TParseLevel level) void CReferenceMaker::parse(uint16 version, TParseLevel level)
{ {
CAnimatable::parse(version, level); CAnimatable::parse(version, level);
if (!m_ChunksOwnsPointers)
{
m_References2034 = static_cast<CStorageArray<sint32> *>(getChunk(PMB_REFERENCES_2034_CHUNK_ID));
m_References2035 = static_cast<CStorageArray<sint32> *>(getChunk(PMB_REFERENCES_2035_CHUNK_ID));
if (m_References2034) nlassert(m_References2035 == NULL); // Apparently, there can be only one.
if (m_References2035) nlassert(m_References2034 == NULL);
m_204B_Equals_2E = static_cast<CStorageValue<uint8> *>(getChunk(PMB_204B_EQUALS_2E_CHUNK_ID));
if (m_204B_Equals_2E) nlassert(m_204B_Equals_2E->Value == 0x2e); // Really, let me know when it has another value.
// TODO: Parse contents
}
} }
void CReferenceMaker::clean() void CReferenceMaker::clean()
{ {
CAnimatable::clean(); CAnimatable::clean();
// TODO: Delete unnecessary stuff
} }
void CReferenceMaker::build(uint16 version) void CReferenceMaker::build(uint16 version)
{ {
CAnimatable::build(version); CAnimatable::build(version);
// TODO: Build contents
if (m_References2034) putChunk(PMB_REFERENCES_2034_CHUNK_ID, m_References2034);
if (m_References2035) putChunk(PMB_REFERENCES_2035_CHUNK_ID, m_References2035);
if (m_204B_Equals_2E) putChunk(PMB_204B_EQUALS_2E_CHUNK_ID, m_204B_Equals_2E);
} }
void CReferenceMaker::disown() void CReferenceMaker::disown()
{ {
m_References2034 = NULL;
m_References2035 = NULL;
m_204B_Equals_2E = NULL;
CAnimatable::disown(); CAnimatable::disown();
} }
@ -120,12 +146,31 @@ const ISceneClassDesc *CReferenceMaker::classDesc() const
void CReferenceMaker::toStringLocal(std::ostream &ostream, const std::string &pad) const void CReferenceMaker::toStringLocal(std::ostream &ostream, const std::string &pad) const
{ {
CAnimatable::toStringLocal(ostream, pad); CAnimatable::toStringLocal(ostream, pad);
if (m_References2034)
{
ostream << "\n" << pad << "References 0x2034: ";
m_References2034->toString(ostream, pad + "\t");
}
if (m_References2035)
{
ostream << "\n" << pad << "References 0x2035: ";
m_References2035->toString(ostream, pad + "\t");
}
if (m_204B_Equals_2E)
{
ostream << "\n" << pad << "0x204B Equals 0x2E (46): ";
m_204B_Equals_2E->toString(ostream, pad + "\t");
}
} }
IStorageObject *CReferenceMaker::createChunkById(uint16 id, bool container) IStorageObject *CReferenceMaker::createChunkById(uint16 id, bool container)
{ {
switch (id) switch (id)
{ {
case PMB_REFERENCES_2034_CHUNK_ID:
return new CStorageArray<sint32>();
case PMB_REFERENCES_2035_CHUNK_ID:
return new CStorageArray<sint32>();
case PMB_204B_EQUALS_2E_CHUNK_ID: case PMB_204B_EQUALS_2E_CHUNK_ID:
return new CStorageValue<uint8>(); return new CStorageValue<uint8>();
} }

@ -34,6 +34,7 @@
// NeL includes // NeL includes
// Project includes // Project includes
#include "../storage_array.h"
#include "animatable.h" #include "animatable.h"
namespace PIPELINE { namespace PIPELINE {
@ -73,6 +74,11 @@ protected:
// inherited // inherited
virtual IStorageObject *createChunkById(uint16 id, bool container); virtual IStorageObject *createChunkById(uint16 id, bool container);
private:
CStorageArray<sint32> *m_References2034;
CStorageArray<sint32> *m_References2035;
CStorageValue<uint8> *m_204B_Equals_2E;
}; /* class CReferenceMaker */ }; /* class CReferenceMaker */
typedef CSceneClassDesc<CReferenceMaker> CReferenceMakerClassDesc; typedef CSceneClassDesc<CReferenceMaker> CReferenceMakerClassDesc;

@ -32,7 +32,6 @@
// STL includes // STL includes
// NeL includes // NeL includes
#include <nel/misc/smart_ptr.h>
// Project includes // Project includes
#include "reference_maker.h" #include "reference_maker.h"
@ -45,16 +44,9 @@ namespace BUILTIN {
* \brief CReferenceTarget * \brief CReferenceTarget
* \date 2012-08-22 08:53GMT * \date 2012-08-22 08:53GMT
* \author Jan Boon (Kaetemi) * \author Jan Boon (Kaetemi)
* This class counts the reference. It is recommended to use CRefPtr<T> * Dummy class, supposed to send or receive events or something.
* to refer to any pointers to classes inherited from this class.
* NOTE: CRefPtr<T> does not delete the class when references go to
* zero. When you remove a class from the scene, the class will be
* deleted if the reference count is zero. Otherwise, you are
* responsible for deleting it (for example, if you keep the class
* backed up in an undo stack for undeletion). You may use CSmartPtr<T>
* when the class is no longer owned by the scene container.
*/ */
class CReferenceTarget : public CReferenceMaker, public NLMISC::CRefCount class CReferenceTarget : public CReferenceMaker
{ {
public: public:
CReferenceTarget(); CReferenceTarget();

@ -56,10 +56,10 @@ namespace STORAGE {
// #define nldebug nlerror // #define nldebug nlerror
// Chunk identifiers // Chunk identifiers
#define NLMAXFILE_APP_DATA_HEADER_CHUNK_ID 0x0100 #define PMBS_APP_DATA_HEADER_CHUNK_ID 0x0100
#define NLMAXFILE_APP_DATA_ENTRY_CHUNK_ID 0x0110 #define PMBS_APP_DATA_ENTRY_CHUNK_ID 0x0110
#define NLMAXFILE_APP_DATA_ENTRY_KEY_CHUNK_ID 0x0120 #define PMBS_APP_DATA_ENTRY_KEY_CHUNK_ID 0x0120
#define NLMAXFILE_APP_DATA_ENTRY_VALUE_CHUNK_ID 0x0130 #define PMBS_APP_DATA_ENTRY_VALUE_CHUNK_ID 0x0130
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -164,14 +164,14 @@ void CAppData::parse(uint16 version, TParseLevel level)
// Header // Header
TStorageObjectContainer::iterator it = m_Chunks.begin(); TStorageObjectContainer::iterator it = m_Chunks.begin();
if (it->first != NLMAXFILE_APP_DATA_HEADER_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, NLMAXFILE_APP_DATA_HEADER_CHUNK_ID); disown(); return; } if (it->first != PMBS_APP_DATA_HEADER_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, PMBS_APP_DATA_HEADER_CHUNK_ID); disown(); return; }
uint32 headerSize = static_cast<CStorageValue<uint32> *>(it->second)->Value; uint32 headerSize = static_cast<CStorageValue<uint32> *>(it->second)->Value;
++it; ++it;
// Entries // Entries
for (TStorageObjectContainer::iterator end = m_Chunks.end(); it != end; ++it) for (TStorageObjectContainer::iterator end = m_Chunks.end(); it != end; ++it)
{ {
if (it->first != NLMAXFILE_APP_DATA_ENTRY_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, NLMAXFILE_APP_DATA_ENTRY_CHUNK_ID); disown(); return; } if (it->first != PMBS_APP_DATA_ENTRY_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, PMBS_APP_DATA_ENTRY_CHUNK_ID); disown(); return; }
CAppDataEntry *entry = static_cast<CAppDataEntry *>(it->second); CAppDataEntry *entry = static_cast<CAppDataEntry *>(it->second);
TKey key(entry->key()->ClassId, entry->key()->SuperClassId, entry->key()->SubId); TKey key(entry->key()->ClassId, entry->key()->SuperClassId, entry->key()->SubId);
if (m_Entries.find(key) != m_Entries.end()) { nlwarning("Duplicate entry"); disown(); return; } if (m_Entries.find(key) != m_Entries.end()) { nlwarning("Duplicate entry"); disown(); return; }
@ -190,7 +190,7 @@ void CAppData::clean()
{ {
if (m_ChunksOwnsPointers) { nldebug("Not parsed, or disowned"); return; } // Must have local ownership if (m_ChunksOwnsPointers) { nldebug("Not parsed, or disowned"); return; } // Must have local ownership
if (m_Chunks.size() == 0) { nlwarning("Already cleaned (or did not build due to coding error)"); return; } // Already cleaned if (m_Chunks.size() == 0) { nlwarning("Already cleaned (or did not build due to coding error)"); return; } // Already cleaned
if (m_Chunks.begin()->first != NLMAXFILE_APP_DATA_HEADER_CHUNK_ID) { nlerror("Bad id %x, expected %x", (uint32)m_Chunks.begin()->first, NLMAXFILE_APP_DATA_HEADER_CHUNK_ID); return; } // Cannot happen, because we won't have local ownership if parsing failed if (m_Chunks.begin()->first != PMBS_APP_DATA_HEADER_CHUNK_ID) { nlerror("Bad id %x, expected %x", (uint32)m_Chunks.begin()->first, PMBS_APP_DATA_HEADER_CHUNK_ID); return; } // Cannot happen, because we won't have local ownership if parsing failed
delete m_Chunks.begin()->second; // Delete the header chunk, since we own it delete m_Chunks.begin()->second; // Delete the header chunk, since we own it
m_Chunks.clear(); // Clear the remaining chunks m_Chunks.clear(); // Clear the remaining chunks
} }
@ -204,11 +204,11 @@ void CAppData::build(uint16 version)
// Set up the header in the chunks container // Set up the header in the chunks container
CStorageValue<uint32> *headerSize = new CStorageValue<uint32>(); // Owned locally, not by m_Chunks CStorageValue<uint32> *headerSize = new CStorageValue<uint32>(); // Owned locally, not by m_Chunks
headerSize->Value = m_Entries.size(); headerSize->Value = m_Entries.size();
m_Chunks.push_back(TStorageObjectWithId(NLMAXFILE_APP_DATA_HEADER_CHUNK_ID, headerSize)); m_Chunks.push_back(TStorageObjectWithId(PMBS_APP_DATA_HEADER_CHUNK_ID, headerSize));
// Set up the entries // Set up the entries
for (TMap::iterator it = m_Entries.begin(), end = m_Entries.end(); it != end; ++it) for (TMap::iterator it = m_Entries.begin(), end = m_Entries.end(); it != end; ++it)
m_Chunks.push_back(TStorageObjectWithId(NLMAXFILE_APP_DATA_ENTRY_CHUNK_ID, it->second)); m_Chunks.push_back(TStorageObjectWithId(PMBS_APP_DATA_ENTRY_CHUNK_ID, it->second));
} }
void CAppData::disown() void CAppData::disown()
@ -304,11 +304,11 @@ IStorageObject *CAppData::createChunkById(uint16 id, bool container)
{ {
switch (id) switch (id)
{ {
case NLMAXFILE_APP_DATA_HEADER_CHUNK_ID: case PMBS_APP_DATA_HEADER_CHUNK_ID:
nlassert(!container); nlassert(!container);
return new CStorageValue<uint32>(); return new CStorageValue<uint32>();
break; break;
case NLMAXFILE_APP_DATA_ENTRY_CHUNK_ID: case PMBS_APP_DATA_ENTRY_CHUNK_ID:
nlassert(container); nlassert(container);
return new CAppDataEntry(); return new CAppDataEntry();
break; break;
@ -397,11 +397,11 @@ void CAppDataEntry::parse(uint16 version, TParseLevel level)
if (m_Chunks.size() != 2) { nlwarning("Bad container size"); disown(); return; } if (m_Chunks.size() != 2) { nlwarning("Bad container size"); disown(); return; }
TStorageObjectContainer::iterator it = m_Chunks.begin(); TStorageObjectContainer::iterator it = m_Chunks.begin();
if (it->first != NLMAXFILE_APP_DATA_ENTRY_KEY_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, NLMAXFILE_APP_DATA_ENTRY_KEY_CHUNK_ID); disown(); return; } if (it->first != PMBS_APP_DATA_ENTRY_KEY_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, PMBS_APP_DATA_ENTRY_KEY_CHUNK_ID); disown(); return; }
m_Key = static_cast<CAppDataEntryKey *>(it->second); m_Key = static_cast<CAppDataEntryKey *>(it->second);
++it; ++it;
if (it->first != NLMAXFILE_APP_DATA_ENTRY_VALUE_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, NLMAXFILE_APP_DATA_ENTRY_VALUE_CHUNK_ID); disown(); return; } if (it->first != PMBS_APP_DATA_ENTRY_VALUE_CHUNK_ID) { nlwarning("Bad id %x, expected %x", (uint32)it->first, PMBS_APP_DATA_ENTRY_VALUE_CHUNK_ID); disown(); return; }
m_Value = static_cast<CStorageRaw *>(it->second); m_Value = static_cast<CStorageRaw *>(it->second);
// m_ChunksOwnsPointers = false; // m_ChunksOwnsPointers = false;
@ -436,9 +436,9 @@ void CAppDataEntry::init()
{ {
nlassert(m_Chunks.size() == 0); nlassert(m_Chunks.size() == 0);
m_Key = new CAppDataEntryKey(); m_Key = new CAppDataEntryKey();
m_Chunks.push_back(TStorageObjectWithId(NLMAXFILE_APP_DATA_ENTRY_KEY_CHUNK_ID, m_Key)); m_Chunks.push_back(TStorageObjectWithId(PMBS_APP_DATA_ENTRY_KEY_CHUNK_ID, m_Key));
m_Value = new CStorageRaw(); m_Value = new CStorageRaw();
m_Chunks.push_back(TStorageObjectWithId(NLMAXFILE_APP_DATA_ENTRY_VALUE_CHUNK_ID, m_Value)); m_Chunks.push_back(TStorageObjectWithId(PMBS_APP_DATA_ENTRY_VALUE_CHUNK_ID, m_Value));
} }
CAppDataEntryKey *CAppDataEntry::key() CAppDataEntryKey *CAppDataEntry::key()
@ -455,10 +455,10 @@ IStorageObject *CAppDataEntry::createChunkById(uint16 id, bool container)
{ {
switch (id) switch (id)
{ {
case NLMAXFILE_APP_DATA_ENTRY_KEY_CHUNK_ID: case PMBS_APP_DATA_ENTRY_KEY_CHUNK_ID:
nlassert(!container); nlassert(!container);
return new CAppDataEntryKey(); return new CAppDataEntryKey();
case NLMAXFILE_APP_DATA_ENTRY_VALUE_CHUNK_ID: case PMBS_APP_DATA_ENTRY_VALUE_CHUNK_ID:
nlassert(!container); nlassert(!container);
return new CStorageRaw(); return new CStorageRaw();
} }

@ -181,12 +181,6 @@ void CSceneClass::init()
IStorageObject *CSceneClass::createChunkById(uint16 id, bool container) IStorageObject *CSceneClass::createChunkById(uint16 id, bool container)
{ {
// Temporary
/*switch (id)
{
case NLMAXFILE_APP_DATA_CHUNK_ID:
return new BUILTIN::STORAGE::CAppData();
}*/
return CStorageContainer::createChunkById(id, container); return CStorageContainer::createChunkById(id, container);
} }

@ -33,6 +33,7 @@
// NeL includes // NeL includes
#include <nel/misc/class_id.h> #include <nel/misc/class_id.h>
#include <nel/misc/smart_ptr.h>
// Project includes // Project includes
#include "typedefs.h" #include "typedefs.h"
@ -49,9 +50,18 @@ class ISceneClassDesc;
* \brief CSceneClass * \brief CSceneClass
* \date 2012-08-19 19:25GMT * \date 2012-08-19 19:25GMT
* \author Jan Boon (Kaetemi) * \author Jan Boon (Kaetemi)
* CSceneClass * It is recommended to use CRefPtr<T> to refer to any pointers to
* classes inherited from this class.
* NOTE: CRefPtr<T> does not delete the class when references go to
* zero. When you remove a class from the scene, the class will be
* deleted if the reference count is zero. Otherwise, you are
* responsible for deleting it (for example, if you keep the class
* backed up in an undo stack for undeletion). You may use CSmartPtr<T>
* when the class is no longer owned by the scene container.
* CRefPtr<T> is a safe handle, which you can use to verify if the class
* has been deleted or not, similar to AnimHandle in max.
*/ */
class CSceneClass : public CStorageContainer class CSceneClass : public CStorageContainer, public NLMISC::CRefCount
{ {
public: public:
CSceneClass(); CSceneClass();

@ -83,7 +83,7 @@ void CSceneClassRegistry::remove(const NLMISC::CClassId classId)
/// Add a superclass to the registry /// Add a superclass to the registry
void CSceneClassRegistry::add(const ISuperClassDesc *desc) void CSceneClassRegistry::add(const ISuperClassDesc *desc)
{ {
nldebug("Register superclass 0x%x", desc->superClassId()); // nldebug("Register superclass 0x%x", desc->superClassId());
if (m_SuperClassDescriptions.find(desc->superClassId()) != m_SuperClassDescriptions.end()) { nlerror("Already added this superclass to the registry"); return; } if (m_SuperClassDescriptions.find(desc->superClassId()) != m_SuperClassDescriptions.end()) { nlerror("Already added this superclass to the registry"); return; }
m_SuperClassDescriptions[desc->superClassId()] = desc; m_SuperClassDescriptions[desc->superClassId()] = desc;
} }

@ -79,7 +79,7 @@ std::string CStorageArray<T>::className() const
template <typename T> template <typename T>
void CStorageArray<T>::serial(NLMISC::IStream &stream) void CStorageArray<T>::serial(NLMISC::IStream &stream)
{ {
for (typename TTypeArray::const_iterator it = Value.begin(), end = Value.end(); it != end; ++it) for (typename TTypeArray::iterator it = Value.begin(), end = Value.end(); it != end; ++it)
{ {
stream.serial(*it); stream.serial(*it);
} }
@ -102,8 +102,8 @@ void CStorageArray<T>::toString(std::ostream &ostream, const std::string &pad) c
template <typename T> template <typename T>
void CStorageArray<T>::setSize(sint32 size) void CStorageArray<T>::setSize(sint32 size)
{ {
if ((sizeof(TType) % size) != 0) if (size % (sizeof(TType)) != 0)
nlerror("Size does not match value type"); nlerror("Size %i is not a multiple of value type size %i", size, sizeof(TType));
Value.resize(size / sizeof(TType)); Value.resize(size / sizeof(TType));
} }

Loading…
Cancel
Save