1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-05 03:45:35 +00:00

Changed over the remaining RefId adapters. Fixed issue where map entries were overwriting the same key...

This commit is contained in:
cc9cii 2015-04-13 06:39:38 +10:00
parent 7ccf53e750
commit a976dca27b
9 changed files with 422 additions and 669 deletions

View file

@ -25,7 +25,7 @@ opencs_units (model/world
opencs_units_noqt (model/world opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection nestedcoladapterimp pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world

View file

@ -1,8 +0,0 @@
#include "nestedadapters.hpp"
CSMWorld::HelperBase::HelperBase(CSMWorld::UniversalId::Type type)
: mType(type)
{}
CSMWorld::HelperBase::~HelperBase()
{}

View file

@ -1,420 +0,0 @@
#ifndef CSM_WORLD_NESTEDADAPTERS_H
#define CSM_WORLD_NESTEDADAPTERS_H
#include <vector>
#include <string>
#include <stdexcept>
#include "universalid.hpp"
#include "nestedtablewrapper.hpp"
#include "record.hpp"
#include "refiddata.hpp"
#include "refidadapter.hpp"
#include <components/esm/loadcont.hpp>
#include <components/esm/defs.hpp>
#include <components/esm/loadnpc.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/effectlist.hpp>
#include <components/esm/loadmgef.hpp>
#include <QVariant>
/*! \brief
* Nested adapter redirects responsibility to the helper class. Helper classes are polymorhpic (vide HelperBase and CastableHelper) and most likely templates.
*/
namespace CSMWorld
{
class RefIdColumn;
class HelperBase
{
protected:
const CSMWorld::UniversalId::Type mType;
public:
HelperBase(CSMWorld::UniversalId::Type type);
virtual ~HelperBase();
virtual void setNestedTable(RefIdData& data,
int index,
const NestedTableWrapperBase& nestedTable) = 0;
virtual NestedTableWrapperBase* nestedTable(const RefIdData& data,
int index) const = 0;
virtual QVariant getNestedData(const CSMWorld::RefIdData& data,
int index,
int subRowIndex,
int subColIndex) const = 0;
virtual void removeNestedRow (RefIdData& data,
int index,
int rowToRemove) const = 0;
virtual void setNestedData (RefIdData& data,
int index,
const QVariant& value,
int subRowIndex,
int subColIndex) const = 0;
virtual void addNestedRow (RefIdData& data,
int index,
int position) const = 0;
virtual int getNestedColumnsCount(const RefIdData& data) const = 0;
virtual int getNestedRowsCount(const RefIdData& data,
int index) const = 0;
};
template <typename ESXRecordT>
class CastableHelper : public HelperBase
{
public:
CastableHelper(CSMWorld::UniversalId::Type type)
: HelperBase(type) {}
protected:
const Record<ESXRecordT>& getRecord(const RefIdData& data, int index) const
{
return dynamic_cast<const Record<ESXRecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, mType)));
}
Record<ESXRecordT>& getRecord(RefIdData& data, int index) const
{
return dynamic_cast<Record<ESXRecordT>&> (
data.getRecord (RefIdData::LocalIndex (index, mType)));
}
};
template <typename ESXRecordT>
class SpellsHelper : public CastableHelper<ESXRecordT>
{
public:
SpellsHelper(CSMWorld::UniversalId::Type type)
: CastableHelper<ESXRecordT>(type) {}
virtual void setNestedTable(RefIdData& data,
int index,
const NestedTableWrapperBase& nestedTable)
{
CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList =
(static_cast<const NestedTableWrapper<std::vector<std::string> >&>(nestedTable)).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const RefIdData& data,
int index) const
{
return new NestedTableWrapper<std::vector<std::string> >(CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList);
}
virtual QVariant getNestedData(const CSMWorld::RefIdData& data,
int index,
int subRowIndex,
int subColIndex) const
{
const std::string& content = CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList.at(subRowIndex);
if (subColIndex == 0)
{
return QString::fromUtf8(content.c_str());
}
throw std::logic_error("Trying to access non-existing column in the nested table!");
}
virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const
{
std::vector<std::string>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList;
list.erase (list.begin () + rowToRemove);
}
void setNestedData (RefIdData& data,
int index,
const QVariant& value,
int subRowIndex,
int subColIndex) const
{
if (subColIndex == 0)
{
CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList.at(subRowIndex) = std::string(value.toString().toUtf8());
}
else
throw std::logic_error("Trying to access non-existing column in the nested table!");
}
virtual void addNestedRow (RefIdData& data, int index, int position) const
{
std::vector<std::string>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList;
std::string newString;
if (position >= (int)list.size())
{
list.push_back(newString);
return;
}
list.insert(list.begin()+position, newString);
}
virtual int getNestedColumnsCount(const RefIdData& data) const
{
return 1;
}
virtual int getNestedRowsCount(const RefIdData& data,
int index) const
{
return CastableHelper<ESXRecordT>::getRecord(data, index).get().mSpells.mList.size();
}
};
template <typename ESXRecordT>
class DestinationsHelper : public CastableHelper<ESXRecordT>
{
public:
DestinationsHelper(CSMWorld::UniversalId::Type type)
: CastableHelper<ESXRecordT>(type) {}
virtual void setNestedTable(RefIdData& data,
int index,
const NestedTableWrapperBase& nestedTable)
{
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList =
(static_cast<const NestedTableWrapper<std::vector<ESM::Transport::Dest> >&>(nestedTable)).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const RefIdData& data,
int index) const
{
return new NestedTableWrapper<std::vector<ESM::Transport::Dest> >(CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList);
}
virtual QVariant getNestedData(const CSMWorld::RefIdData& data,
int index,
int subRowIndex,
int subColIndex) const
{
const ESM::Transport::Dest& content = CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex);
switch (subColIndex)
{
case 0:
return QString::fromUtf8(content.mCellName.c_str());
case 1:
return content.mPos.pos[0];
case 2:
return content.mPos.pos[1];
case 3:
return content.mPos.pos[2];
case 4:
return content.mPos.rot[0];
case 5:
return content.mPos.rot[1];
case 6:
return content.mPos.rot[2];
default:
throw std::logic_error("Trying to access non-existing column in the nested table!");
}
}
virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const
{
std::vector<ESM::Transport::Dest>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList;
list.erase (list.begin () + rowToRemove);
}
void setNestedData (RefIdData& data,
int index,
const QVariant& value,
int subRowIndex,
int subColIndex) const
{
switch(subColIndex)
{
case 0:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData());
break;
case 1:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[0] = value.toFloat();
break;
case 2:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[1] = value.toFloat();
break;
case 3:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[2] = value.toFloat();
break;
case 4:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[0] = value.toFloat();
break;
case 5:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[1] = value.toFloat();
break;
case 6:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[2] = value.toFloat();
break;
default:
throw std::logic_error("Trying to access non-existing column in the nested table!");
}
}
virtual void addNestedRow (RefIdData& data, int index, int position) const
{
std::vector<ESM::Transport::Dest>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList;
ESM::Position newPos;
for (unsigned i = 0; i < 3; ++i)
{
newPos.pos[i] = 0;
newPos.rot[i] = 0;
}
ESM::Transport::Dest newRow;
newRow.mPos = newPos;
newRow.mCellName = "";
if (position >= (int)list.size())
{
list.push_back(newRow);
return;
}
list.insert(list.begin()+position, newRow);
}
virtual int getNestedColumnsCount(const RefIdData& data) const
{
return 7;
}
virtual int getNestedRowsCount(const RefIdData& data,
int index) const
{
return CastableHelper<ESXRecordT>::getRecord(data, index).get().mTransport.mList.size();
}
};
template <typename ESXRecordT>
class InventoryHelper : public CastableHelper<ESXRecordT>
{
public:
InventoryHelper(CSMWorld::UniversalId::Type type)
: CastableHelper<ESXRecordT>(type) {}
virtual void setNestedTable(RefIdData& data,
int index,
const NestedTableWrapperBase& nestedTable)
{
CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList =
(static_cast<const NestedTableWrapper<std::vector<ESM::ContItem> >&>(nestedTable)).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const RefIdData& data,
int index) const
{
return new NestedTableWrapper<std::vector<ESM::ContItem> >(CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList);
}
virtual QVariant getNestedData(const CSMWorld::RefIdData& data,
int index,
int subRowIndex,
int subColIndex) const
{
const ESM::ContItem& content = CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList.at(subRowIndex);
switch (subColIndex)
{
case 0:
return QString::fromUtf8(content.mItem.toString().c_str());
case 1:
return content.mCount;
default:
throw std::logic_error("Trying to access non-existing column in the nested table!");
}
}
virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const
{
std::vector<ESM::ContItem>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList;
list.erase (list.begin () + rowToRemove);
}
void setNestedData (RefIdData& data,
int index,
const QVariant& value,
int subRowIndex,
int subColIndex) const
{
switch(subColIndex)
{
case 0:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData()));
break;
case 1:
CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt();
break;
default:
throw std::logic_error("Trying to access non-existing column in the nested table!");
}
}
virtual void addNestedRow (RefIdData& data, int index, int position) const
{
std::vector<ESM::ContItem>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList;
ESM::ContItem newRow = {0, {""}};
if (position >= (int)list.size())
{
list.push_back(newRow);
return;
}
list.insert(list.begin()+position, newRow);
}
virtual int getNestedColumnsCount(const RefIdData& data) const
{
return 2;
}
virtual int getNestedRowsCount(const RefIdData& data,
int index) const
{
return CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList.size();
}
};
}
#endif

View file

@ -1,9 +1,5 @@
#include "refidadapter.hpp" #include "refidadapter.hpp"
#include "nestedtablewrapper.hpp"
#include <QVariant>
CSMWorld::RefIdAdapter::RefIdAdapter() {} CSMWorld::RefIdAdapter::RefIdAdapter() {}
CSMWorld::RefIdAdapter::~RefIdAdapter() {} CSMWorld::RefIdAdapter::~RefIdAdapter() {}
@ -11,84 +7,3 @@ CSMWorld::RefIdAdapter::~RefIdAdapter() {}
CSMWorld::NestedRefIdAdapterBase::NestedRefIdAdapterBase() {} CSMWorld::NestedRefIdAdapterBase::NestedRefIdAdapterBase() {}
CSMWorld::NestedRefIdAdapterBase::~NestedRefIdAdapterBase() {} CSMWorld::NestedRefIdAdapterBase::~NestedRefIdAdapterBase() {}
CSMWorld::NestedRefIdAdapter::NestedRefIdAdapter()
{}
CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter()
{
for (unsigned i = 0; i < mAssociatedColumns.size(); ++i)
{
delete mAssociatedColumns[i].second;
}
}
void CSMWorld::NestedRefIdAdapter::setNestedData (const RefIdColumn *column, RefIdData& data, int row,
const QVariant& value, int subRowIndex, int subColIndex) const
{
getHelper(column)->setNestedData(data, row, value, subRowIndex, subColIndex);
}
QVariant CSMWorld::NestedRefIdAdapter::getNestedData(const RefIdColumn *column, const RefIdData& data,
int index, int subRowIndex, int subColIndex) const
{
return getHelper(column)->getNestedData(data, index, subRowIndex, subColIndex);
}
int CSMWorld::NestedRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return getHelper(column)->getNestedColumnsCount(data);
}
int CSMWorld::NestedRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
return getHelper(column)->getNestedRowsCount(data, index);
}
void CSMWorld::NestedRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const
{
getHelper(column)->removeNestedRow(data, index, rowToRemove);
}
void CSMWorld::NestedRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const
{
getHelper(column)->addNestedRow(data, index, position); //This code grows more boring and boring. I would love some macros.
}
void CSMWorld::NestedRefIdAdapter::setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
getHelper(column)->setNestedTable(data, index, nestedTable);
}
CSMWorld::NestedTableWrapperBase* CSMWorld::NestedRefIdAdapter::nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const
{
return getHelper(column)->nestedTable(data, index);
}
CSMWorld::HelperBase* CSMWorld::NestedRefIdAdapter::getHelper(const RefIdColumn *column) const
{
for (unsigned i = 0; i < mAssociatedColumns.size(); ++i)
{
if (mAssociatedColumns[i].first == column)
{
return mAssociatedColumns[i].second;
}
}
throw std::logic_error("No such column in the nestedrefidadapter");
return NULL;
}
void CSMWorld::NestedRefIdAdapter::setAssocColumns(const std::vector<std::pair <const RefIdColumn*, HelperBase*> >& assocColumns)
{
mAssociatedColumns = assocColumns;
}
void CSMWorld::NestedRefIdAdapter::addAssocColumn(const std::pair <const RefIdColumn*, HelperBase*>& assocColumn)
{
mAssociatedColumns.push_back(assocColumn);
}

View file

@ -4,8 +4,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "nestedadapters.hpp"
/*! \brief /*! \brief
* Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model.
* Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function).
@ -77,47 +75,6 @@ namespace CSMWorld
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const = 0; const RefIdData& data, int index) const = 0;
}; };
class NestedRefIdAdapter : public NestedRefIdAdapterBase
{
std::vector<std::pair <const RefIdColumn*, HelperBase*> > mAssociatedColumns; //basically, i wanted a map, but with pointer key
public:
NestedRefIdAdapter();
virtual ~NestedRefIdAdapter();
virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data,
int index, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const;
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const;
virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const;
virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const;
virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const;
protected:
void setAssocColumns(const std::vector<std::pair <const RefIdColumn*, HelperBase*> >& assocColumns);
///The ownership of the Helper pointers is transfered.
///The ownership of the column pointers it not transfered (it is not surprising, since columns are created by collection).
///You MUST call this method to setup the nested adaptor!
void addAssocColumn(const std::pair <const RefIdColumn*, HelperBase*>& assocColumn);
///Like setAssocColumn, when it is impossible to set all columns at once
private:
HelperBase* getHelper(const RefIdColumn *column) const;
};
} }
#endif #endif

View file

@ -188,13 +188,7 @@ CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& colum
const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content) const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content)
: NameRefIdAdapter<ESM::Container> (UniversalId::Type_Container, columns), mWeight (weight), : NameRefIdAdapter<ESM::Container> (UniversalId::Type_Container, columns), mWeight (weight),
mOrganic (organic), mRespawn (respawn), mContent(content) mOrganic (organic), mRespawn (respawn), mContent(content)
{ {}
std::vector<std::pair <const RefIdColumn*, HelperBase*> > assoCol;
assoCol.push_back(std::make_pair(content, new InventoryHelper<ESM::Container>(UniversalId::Type_Container)));
setAssocColumns(assoCol);
}
QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column,
const RefIdData& data, const RefIdData& data,
@ -471,9 +465,7 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns)
CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns)
: ActorRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc, columns), mColumns (columns) : ActorRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc, columns), mColumns (columns)
{ {}
NestedRefIdAdapter::addAssocColumn(std::make_pair(columns.mDestinations, new DestinationsHelper<ESM::NPC>(UniversalId::Type_Npc)));
}
QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index)
const const
@ -496,9 +488,6 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re
if (column==mColumns.mHead) if (column==mColumns.mHead)
return QString::fromUtf8 (record.get().mHead.c_str()); return QString::fromUtf8 (record.get().mHead.c_str());
if (column==mColumns.mDestinations)
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
mColumns.mFlags.find (column); mColumns.mFlags.find (column);

View file

@ -11,12 +11,12 @@
#include <components/esm/loadnpc.hpp> #include <components/esm/loadnpc.hpp>
#include <components/esm/loadcrea.hpp> #include <components/esm/loadcrea.hpp>
#include <components/esm/loadcont.hpp> #include <components/esm/loadcont.hpp>
#include <components/esm/transport.hpp>
#include "record.hpp" #include "record.hpp"
#include "refiddata.hpp" #include "refiddata.hpp"
#include "universalid.hpp" #include "universalid.hpp"
#include "refidadapter.hpp" #include "refidadapter.hpp"
#include "nestedadapters.hpp"
namespace CSMWorld namespace CSMWorld
{ {
@ -489,6 +489,7 @@ namespace CSMWorld
const RefIdColumn *mAlarm; const RefIdColumn *mAlarm;
const RefIdColumn *mInventory; const RefIdColumn *mInventory;
const RefIdColumn *mSpells; const RefIdColumn *mSpells;
const RefIdColumn *mDestinations;
std::map<const RefIdColumn *, unsigned int> mServices; std::map<const RefIdColumn *, unsigned int> mServices;
ActorColumns (const NameColumns& base) : NameColumns (base) {} ActorColumns (const NameColumns& base) : NameColumns (base) {}
@ -496,7 +497,7 @@ namespace CSMWorld
/// \brief Adapter for actor IDs (handles common AI functionality) /// \brief Adapter for actor IDs (handles common AI functionality)
template<typename RecordT> template<typename RecordT>
class ActorRefIdAdapter : public NameRefIdAdapter<RecordT>, public NestedRefIdAdapter class ActorRefIdAdapter : public NameRefIdAdapter<RecordT>
{ {
ActorColumns mActors; ActorColumns mActors;
@ -516,14 +517,7 @@ namespace CSMWorld
ActorRefIdAdapter<RecordT>::ActorRefIdAdapter (UniversalId::Type type, ActorRefIdAdapter<RecordT>::ActorRefIdAdapter (UniversalId::Type type,
const ActorColumns& columns) const ActorColumns& columns)
: NameRefIdAdapter<RecordT> (type, columns), mActors (columns) : NameRefIdAdapter<RecordT> (type, columns), mActors (columns)
{ {}
std::vector<std::pair <const RefIdColumn*, HelperBase*> > assoCol;
assoCol.push_back(std::make_pair(mActors.mInventory, new InventoryHelper<RecordT>(type)));
assoCol.push_back(std::make_pair(mActors.mSpells, new SpellsHelper<RecordT>(type)));
setAssocColumns(assoCol);
}
template<typename RecordT> template<typename RecordT>
QVariant ActorRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data, QVariant ActorRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data,
@ -553,6 +547,9 @@ namespace CSMWorld
if (column==mActors.mSpells) if (column==mActors.mSpells)
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
if (column==mActors.mDestinations)
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
mActors.mServices.find (column); mActors.mServices.find (column);
@ -672,7 +669,7 @@ namespace CSMWorld
///< If the data type does not match an exception is thrown. ///< If the data type does not match an exception is thrown.
}; };
class ContainerRefIdAdapter : public NameRefIdAdapter<ESM::Container>, public NestedRefIdAdapter class ContainerRefIdAdapter : public NameRefIdAdapter<ESM::Container>
{ {
const RefIdColumn *mWeight; const RefIdColumn *mWeight;
const RefIdColumn *mOrganic; const RefIdColumn *mOrganic;
@ -790,7 +787,6 @@ namespace CSMWorld
const RefIdColumn *mFaction; const RefIdColumn *mFaction;
const RefIdColumn *mHair; const RefIdColumn *mHair;
const RefIdColumn *mHead; const RefIdColumn *mHead;
const RefIdColumn *mDestinations;
NpcColumns (const ActorColumns& actorColumns); NpcColumns (const ActorColumns& actorColumns);
}; };
@ -1060,6 +1056,318 @@ namespace CSMWorld
return static_cast<int>(record.get().mInventory.mList.size()); return static_cast<int>(record.get().mInventory.mList.size());
} }
}; };
template <typename ESXRecordT>
class NestedSpellRefIdAdapter : public NestedRefIdAdapterBase
{
UniversalId::Type mType;
// not implemented
NestedSpellRefIdAdapter (const NestedSpellRefIdAdapter&);
NestedSpellRefIdAdapter& operator= (const NestedSpellRefIdAdapter&);
public:
NestedSpellRefIdAdapter(UniversalId::Type type) :mType(type) {}
virtual ~NestedSpellRefIdAdapter() {}
virtual void addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT caster = record.get();
std::vector<std::string>& list = caster.mSpells.mList;
std::string newString;
if (position >= (int)list.size())
list.push_back(newString);
else
list.insert(list.begin()+position, newString);
record.setModified (caster);
}
virtual void removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT caster = record.get();
std::vector<std::string>& list = caster.mSpells.mList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
list.erase (list.begin () + rowToRemove);
record.setModified (caster);
}
virtual void setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT caster = record.get();
caster.mSpells.mList =
static_cast<const NestedTableWrapper<std::vector<std::string> >&>(nestedTable).mNestedTable;
record.setModified (caster);
}
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<std::string> >(record.get().mSpells.mList);
}
virtual QVariant getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
const std::vector<std::string>& list = record.get().mSpells.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
const std::string& content = list.at(subRowIndex);
if (subColIndex == 0)
return QString::fromUtf8(content.c_str());
else
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
virtual void setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (row, mType)));
ESXRecordT caster = record.get();
std::vector<std::string>& list = caster.mSpells.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
if (subColIndex == 0)
list.at(subRowIndex) = std::string(value.toString().toUtf8());
else
throw std::runtime_error("Trying to access non-existing column in the nested table!");
record.setModified (caster);
}
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return 1;
}
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
return static_cast<int>(record.get().mSpells.mList.size());
}
};
template <typename ESXRecordT>
class NestedTravelRefIdAdapter : public NestedRefIdAdapterBase
{
UniversalId::Type mType;
// not implemented
NestedTravelRefIdAdapter (const NestedTravelRefIdAdapter&);
NestedTravelRefIdAdapter& operator= (const NestedTravelRefIdAdapter&);
public:
NestedTravelRefIdAdapter(UniversalId::Type type) :mType(type) {}
virtual ~NestedTravelRefIdAdapter() {}
virtual void addNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int position) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT traveller = record.get();
std::vector<ESM::Transport::Dest>& list = traveller.mTransport.mList;
ESM::Position newPos;
for (unsigned i = 0; i < 3; ++i)
{
newPos.pos[i] = 0;
newPos.rot[i] = 0;
}
ESM::Transport::Dest newRow;
newRow.mPos = newPos;
newRow.mCellName = "";
if (position >= (int)list.size())
list.push_back(newRow);
else
list.insert(list.begin()+position, newRow);
record.setModified (traveller);
}
virtual void removeNestedRow (const RefIdColumn *column,
RefIdData& data, int index, int rowToRemove) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT traveller = record.get();
std::vector<ESM::Transport::Dest>& list = traveller.mTransport.mList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
list.erase (list.begin () + rowToRemove);
record.setModified (traveller);
}
virtual void setNestedTable (const RefIdColumn* column,
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
ESXRecordT traveller = record.get();
traveller.mTransport.mList =
static_cast<const NestedTableWrapper<std::vector<ESM::Transport::Dest> >&>(nestedTable).mNestedTable;
record.setModified (traveller);
}
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
const RefIdData& data, int index) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::Transport::Dest> >(record.get().mTransport.mList);
}
virtual QVariant getNestedData (const RefIdColumn *column,
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
const std::vector<ESM::Transport::Dest>& list = record.get().mTransport.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
const ESM::Transport::Dest& content = list.at(subRowIndex);
switch (subColIndex)
{
case 0:
return QString::fromUtf8(content.mCellName.c_str());
case 1:
return content.mPos.pos[0];
case 2:
return content.mPos.pos[1];
case 3:
return content.mPos.pos[2];
case 4:
return content.mPos.rot[0];
case 5:
return content.mPos.rot[1];
case 6:
return content.mPos.rot[2];
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
}
virtual void setNestedData (const RefIdColumn *column,
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
{
Record<ESXRecordT>& record =
static_cast<Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (row, mType)));
ESXRecordT traveller = record.get();
std::vector<ESM::Transport::Dest>& list = traveller.mTransport.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (list.size()))
throw std::runtime_error ("index out of range");
switch(subColIndex)
{
case 0:
list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData());
break;
case 1:
list.at(subRowIndex).mPos.pos[0] = value.toFloat();
break;
case 2:
list.at(subRowIndex).mPos.pos[1] = value.toFloat();
break;
case 3:
list.at(subRowIndex).mPos.pos[2] = value.toFloat();
break;
case 4:
list.at(subRowIndex).mPos.rot[0] = value.toFloat();
break;
case 5:
list.at(subRowIndex).mPos.rot[1] = value.toFloat();
break;
case 6:
list.at(subRowIndex).mPos.rot[2] = value.toFloat();
break;
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
record.setModified (traveller);
}
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
return 7;
}
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
const Record<ESXRecordT>& record =
static_cast<const Record<ESXRecordT>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
return static_cast<int>(record.get().mTransport.mList.size());
}
};
} }
#endif #endif

View file

@ -75,8 +75,12 @@ CSMWorld::RefIdCollection::RefIdCollection()
PotionColumns potionColumns (inventoryColumns); PotionColumns potionColumns (inventoryColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp
mNestedAdapters.insert (std::make_pair(&mColumns.back(),
new EffectsRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion))); std::map<UniversalId::Type, NestedRefIdAdapterBase*> effectsMap;
effectsMap.insert(
std::make_pair(UniversalId::Type_Potion, new EffectsRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), effectsMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/));
mColumns.back().addColumn( mColumns.back().addColumn(
@ -124,10 +128,14 @@ CSMWorld::RefIdCollection::RefIdCollection()
// Nested table // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue));
actorsColumns.mInventory = &mColumns.back(); actorsColumns.mInventory = &mColumns.back();
mNestedAdapters.insert (std::make_pair(&mColumns.back(),
new NestedInventoryRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc))); std::map<UniversalId::Type, NestedRefIdAdapterBase*> inventoryMap;
mNestedAdapters.insert (std::make_pair(&mColumns.back(), inventoryMap.insert(
new NestedInventoryRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); std::make_pair(UniversalId::Type_Npc, new NestedInventoryRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
inventoryMap.insert(
std::make_pair(UniversalId::Type_Creature, new NestedInventoryRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn( mColumns.back().addColumn(
@ -136,9 +144,42 @@ CSMWorld::RefIdCollection::RefIdCollection()
// Nested table // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue));
actorsColumns.mSpells = &mColumns.back(); actorsColumns.mSpells = &mColumns.back();
std::map<UniversalId::Type, NestedRefIdAdapterBase*> spellsMap;
spellsMap.insert(
std::make_pair(UniversalId::Type_Npc, new NestedSpellRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
spellsMap.insert(
std::make_pair(UniversalId::Type_Creature, new NestedSpellRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String));
// Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue));
actorsColumns.mDestinations = &mColumns.back();
std::map<UniversalId::Type, NestedRefIdAdapterBase*> destMap;
destMap.insert(
std::make_pair(UniversalId::Type_Npc, new NestedTravelRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
destMap.insert(
std::make_pair(UniversalId::Type_Creature, new NestedTravelRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float));
static const struct static const struct
{ {
int mName; int mName;
@ -209,8 +250,12 @@ CSMWorld::RefIdCollection::RefIdCollection()
// Nested table // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue));
const RefIdColumn *content = &mColumns.back(); const RefIdColumn *content = &mColumns.back();
mNestedAdapters.insert (std::make_pair(&mColumns.back(),
new NestedInventoryRefIdAdapter<ESM::Container> (UniversalId::Type_Container))); std::map<UniversalId::Type, NestedRefIdAdapterBase*> contMap;
contMap.insert(
std::make_pair(UniversalId::Type_Container, new NestedInventoryRefIdAdapter<ESM::Container> (UniversalId::Type_Container)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn( mColumns.back().addColumn(
@ -351,24 +396,6 @@ CSMWorld::RefIdCollection::RefIdCollection()
npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal));
// Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue));
npcColumns.mDestinations = &mColumns.back();
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float));
WeaponColumns weaponColumns (enchantableColumns); WeaponColumns weaponColumns (enchantableColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType));
@ -461,9 +488,13 @@ CSMWorld::RefIdCollection::~RefIdCollection()
iter!=mAdapters.end(); ++iter) iter!=mAdapters.end(); ++iter)
delete iter->second; delete iter->second;
for (std::map<const ColumnBase*, NestedRefIdAdapterBase* >::iterator iter (mNestedAdapters.begin()); for (std::vector<std::pair<const ColumnBase*, std::map<UniversalId::Type, NestedRefIdAdapterBase*> > >::iterator iter (mNestedAdapters.begin());
iter!=mNestedAdapters.end(); ++iter) iter!=mNestedAdapters.end(); ++iter)
delete iter->second; {
for (std::map<UniversalId::Type, NestedRefIdAdapterBase *>::iterator it ((iter->second).begin());
it!=(iter->second).end(); ++it)
delete it->second;
}
} }
int CSMWorld::RefIdCollection::getSize() const int CSMWorld::RefIdCollection::getSize() const
@ -509,15 +540,11 @@ QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subR
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{
return nestedAdapter->getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn); return nestedAdapter->getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn);
} else
throw std::runtime_error("Could not find a nestedadapter");
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second));
return adaptor.getNestedData (&mColumns.at (column), mData, localIndex.first, subRow, subColumn);
} }
void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data)
@ -533,16 +560,14 @@ void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVarian
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{ {
nestedAdapter->setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); nestedAdapter->setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn);
return; return;
} }
else
const RefIdAdapter& adaptor = findAdapter (localIndex.second); throw std::runtime_error("Could not find a nestedadapter");
dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(adaptor).setNestedData (&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn);
} }
void CSMWorld::RefIdCollection::removeRows (int index, int count) void CSMWorld::RefIdCollection::removeRows (int index, int count)
@ -554,16 +579,14 @@ void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{ {
nestedAdapter->removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); nestedAdapter->removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow);
return; return;
} }
else
const RefIdAdapter& adaptor = findAdapter (localIndex.second); throw std::runtime_error("Could not find a nestedadapter");
dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(adaptor).removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow);
} }
void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type)
@ -705,30 +728,22 @@ int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{
return nestedAdapter->getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); return nestedAdapter->getNestedRowsCount(&mColumns.at(column), mData, localIndex.first);
} else
throw std::runtime_error("Could not find a nestedadapter");
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second));
return adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first);
} }
int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{
return nestedAdapter->getNestedColumnsCount(&mColumns.at(column), mData); return nestedAdapter->getNestedColumnsCount(&mColumns.at(column), mData);
} else
throw std::runtime_error("Could not find a nestedadapter");
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second));
return adaptor.getNestedColumnsCount(&mColumns.at(column), mData);
} }
CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column) CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column)
@ -740,58 +755,56 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position)
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(col)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(col), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{ {
nestedAdapter->addNestedRow(&mColumns.at(col), mData, localIndex.first, position); nestedAdapter->addNestedRow(&mColumns.at(col), mData, localIndex.first, position);
return; return;
} }
else
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second)); throw std::runtime_error("Could not find a nestedadapter");
adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position);
} }
void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable)
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{ {
nestedAdapter->setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); nestedAdapter->setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable);
return; return;
} }
else
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second)); throw std::runtime_error("Could not find a nestedadapter");
adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable);
} }
CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second);
if (nestedAdapter) if (nestedAdapter)
{
return nestedAdapter->nestedTable(&mColumns.at(column), mData, localIndex.first); return nestedAdapter->nestedTable(&mColumns.at(column), mData, localIndex.first);
} else
throw std::runtime_error("Could not find a nestedadapter");
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second));
return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first);
} }
const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column) const const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column, UniversalId::Type type) const
{ {
std::map<const ColumnBase*, NestedRefIdAdapterBase* >::const_iterator iter = for (std::vector<std::pair<const ColumnBase*, std::map<UniversalId::Type, NestedRefIdAdapterBase*> > >::const_iterator iter (mNestedAdapters.begin());
mNestedAdapters.find (&column); iter!=mNestedAdapters.end(); ++iter)
{
if ((iter->first) == &column)
{
std::map<UniversalId::Type, NestedRefIdAdapterBase*>::const_iterator it =
(iter->second).find(type);
if (iter==mNestedAdapters.end()) if (it == (iter->second).end())
return 0; // FIXME: testing only throw std::runtime_error("No such type in the nestedadapters");
//throw std::runtime_error("No such column in the nestedadapters");
//return *iter->second; return it->second;
return iter->second; }
}
throw std::runtime_error("No such column in the nestedadapters");
} }

View file

@ -45,15 +45,14 @@ namespace CSMWorld
std::deque<RefIdColumn> mColumns; std::deque<RefIdColumn> mColumns;
std::map<UniversalId::Type, RefIdAdapter *> mAdapters; std::map<UniversalId::Type, RefIdAdapter *> mAdapters;
std::map<const ColumnBase*, NestedRefIdAdapterBase* > mNestedAdapters; std::vector<std::pair<const ColumnBase*, std::map<UniversalId::Type, NestedRefIdAdapterBase*> > > mNestedAdapters;
private: private:
const RefIdAdapter& findAdapter (UniversalId::Type) const; const RefIdAdapter& findAdapter (UniversalId::Type) const;
///< Throws an exception if no adaptor for \a Type can be found. ///< Throws an exception if no adaptor for \a Type can be found.
//const NestedRefIdAdapterBase& getNestedAdapter(const ColumnBase &column) const; const NestedRefIdAdapterBase* getNestedAdapter(const ColumnBase &column, UniversalId::Type type) const;
const NestedRefIdAdapterBase* getNestedAdapter(const ColumnBase &column) const;
public: public: