1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-07-21 05:14:10 +00:00

Moved templated code around a bit.

This commit is contained in:
cc9cii 2015-04-12 10:52:01 +10:00
parent 4b9c9bf095
commit 41b368a759
5 changed files with 536 additions and 433 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 pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection idadapterimp
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world

View file

@ -169,7 +169,8 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct NestedParentColumn : public Column<ESXRecordT> struct NestedParentColumn : public Column<ESXRecordT>
{ {
NestedParentColumn (int id) : Column<ESXRecordT> (id, Display_NestedHeader, Flag_Dialogue) NestedParentColumn (int id) : Column<ESXRecordT> (id,
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)
{} {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const

View file

@ -112,7 +112,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
NestedParentColumn<ESM::Faction> *reactions = NestedParentColumn<ESM::Faction> *reactions =
new NestedParentColumn<ESM::Faction> (Columns::ColumnId_FactionReactions); new NestedParentColumn<ESM::Faction> (Columns::ColumnId_FactionReactions);
mFactions.addColumn (reactions); mFactions.addColumn (reactions);
mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter<ESM::Faction> ())); mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ()));
mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn(
new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String));
mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn(
@ -160,7 +160,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
NestedParentColumn<ESM::Region> *soundList = NestedParentColumn<ESM::Region> *soundList =
new NestedParentColumn<ESM::Region> (Columns::ColumnId_RegionSounds); new NestedParentColumn<ESM::Region> (Columns::ColumnId_RegionSounds);
mRegions.addColumn (soundList); mRegions.addColumn (soundList);
mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter<ESM::Region> ())); mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ()));
mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(
new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String));
mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(
@ -335,7 +335,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridPoints); new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridPoints);
mPathgrids.addColumn (pointList); mPathgrids.addColumn (pointList);
// new object deleted in dtor of SubCellCollection<T,A> // new object deleted in dtor of SubCellCollection<T,A>
mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter<Pathgrid> ())); mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ()));
// new objects deleted in dtor of NestableColumn // new objects deleted in dtor of NestableColumn
// WARNING: The order of the columns below are assumed in PathgridPointListAdapter // WARNING: The order of the columns below are assumed in PathgridPointListAdapter
mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(
@ -350,7 +350,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
NestedParentColumn<Pathgrid> *edgeList = NestedParentColumn<Pathgrid> *edgeList =
new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridEdges); new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridEdges);
mPathgrids.addColumn (edgeList); mPathgrids.addColumn (edgeList);
mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter<Pathgrid> ())); mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ()));
mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(
new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false)); new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false));
mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(

View file

@ -0,0 +1,457 @@
#include "idadapterimp.hpp"
#include <components/esm/loadregn.hpp>
#include <components/esm/loadfact.hpp>
#include "idcollection.hpp"
#include "pathgrid.hpp"
namespace CSMWorld
{
PathgridPointListAdapter::PathgridPointListAdapter () {}
void PathgridPointListAdapter::addNestedRow(Record<Pathgrid>& record, int position) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
// blank row
ESM::Pathgrid::Point point;
point.mX = 0;
point.mY = 0;
point.mZ = 0;
point.mAutogenerated = 0;
point.mConnectionNum = 0;
point.mUnknown = 0;
// inserting a point should trigger re-indexing of the edges
//
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (;iter != pathgrid.mEdges.end(); ++iter)
{
if ((*iter).mV0 >= position)
(*iter).mV0++;
if ((*iter).mV1 >= position)
(*iter).mV1++;
}
points.insert(points.begin()+position, point);
pathgrid.mData.mS2 += 1; // increment the number of points
record.setModified (pathgrid);
}
void PathgridPointListAdapter::removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (points.size()))
throw std::runtime_error ("index out of range");
// deleting a point should trigger re-indexing of the edges
// dangling edges are not allowed and hence removed
//
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (; iter != pathgrid.mEdges.end();)
{
if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove))
iter = pathgrid.mEdges.erase(iter);
else
{
if ((*iter).mV0 > rowToRemove)
(*iter).mV0--;
if ((*iter).mV1 > rowToRemove)
(*iter).mV1--;
++iter;
}
}
points.erase(points.begin()+rowToRemove);
pathgrid.mData.mS2 -= 1; // decrement the number of points
record.setModified (pathgrid);
}
void PathgridPointListAdapter::setNestedTable(Record<Pathgrid>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mPoints =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mPoints;
record.get().mData.mS2 =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mData.mS2;
// also update edges in case points were added/removed
record.get().mEdges =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mEdges;
}
NestedTableWrapperBase* PathgridPointListAdapter::nestedTable(const Record<Pathgrid>& record) const
{
// deleted by dtor of NestedTableStoring
return new PathgridPointsWrap(record.get());
}
QVariant PathgridPointListAdapter::getNestedData(const Record<Pathgrid>& record,
int subRowIndex, int subColIndex) const
{
ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return point.mX;
case 2: return point.mY;
case 3: return point.mZ;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
}
void PathgridPointListAdapter::setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: point.mX = value.toInt(); break;
case 2: point.mY = value.toInt(); break;
case 3: point.mZ = value.toInt(); break;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
pathgrid.mPoints[subRowIndex] = point;
record.setModified (pathgrid);
}
int PathgridPointListAdapter::getNestedColumnsCount(const Record<Pathgrid>& record) const
{
return 4;
}
int PathgridPointListAdapter::getNestedRowsCount(const Record<Pathgrid>& record) const
{
return static_cast<int>(record.get().mPoints.size());
}
PathgridEdgeListAdapter::PathgridEdgeListAdapter () {}
// ToDo: seems to be auto-sorted in the dialog table display after insertion
void PathgridEdgeListAdapter::addNestedRow(Record<Pathgrid>& record, int position) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges;
// blank row
ESM::Pathgrid::Edge edge;
edge.mV0 = 0;
edge.mV1 = 0;
// NOTE: inserting a blank edge does not really make sense, perhaps this should be a
// logic_error exception
//
// Currently the code assumes that the end user to know what he/she is doing.
// e.g. Edges come in pairs, from points a->b and b->a
edges.insert(edges.begin()+position, edge);
record.setModified (pathgrid);
}
void PathgridEdgeListAdapter::removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (edges.size()))
throw std::runtime_error ("index out of range");
edges.erase(edges.begin()+rowToRemove);
record.setModified (pathgrid);
}
void PathgridEdgeListAdapter::setNestedTable(Record<Pathgrid>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mEdges =
static_cast<const NestedTableWrapper<ESM::Pathgrid::EdgeList> &>(nestedTable).mNestedTable;
}
NestedTableWrapperBase* PathgridEdgeListAdapter::nestedTable(const Record<Pathgrid>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<ESM::Pathgrid::EdgeList>(record.get().mEdges);
}
QVariant PathgridEdgeListAdapter::getNestedData(const Record<Pathgrid>& record,
int subRowIndex, int subColIndex) const
{
Pathgrid pathgrid = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return edge.mV0;
case 2: return edge.mV1;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
}
// ToDo: detect duplicates in mEdges
void PathgridEdgeListAdapter::setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
Pathgrid pathgrid = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: edge.mV0 = value.toInt(); break;
case 2: edge.mV1 = value.toInt(); break;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
pathgrid.mEdges[subRowIndex] = edge;
record.setModified (pathgrid);
}
int PathgridEdgeListAdapter::getNestedColumnsCount(const Record<Pathgrid>& record) const
{
return 3;
}
int PathgridEdgeListAdapter::getNestedRowsCount(const Record<Pathgrid>& record) const
{
return static_cast<int>(record.get().mEdges.size());
}
FactionReactionsAdapter::FactionReactionsAdapter () {}
void FactionReactionsAdapter::addNestedRow(Record<ESM::Faction>& record, int position) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
// blank row
reactions.insert(std::make_pair("", 0));
record.setModified (faction);
}
void FactionReactionsAdapter::removeNestedRow(Record<ESM::Faction>& record, int rowToRemove) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < rowToRemove; ++i)
iter++;
reactions.erase(iter);
record.setModified (faction);
}
void FactionReactionsAdapter::setNestedTable(Record<ESM::Faction>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mReactions =
static_cast<const NestedTableWrapper<std::map<std::string, int> >&>(nestedTable).mNestedTable;
}
NestedTableWrapperBase* FactionReactionsAdapter::nestedTable(const Record<ESM::Faction>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::map<std::string, int> >(record.get().mReactions);
}
QVariant FactionReactionsAdapter::getNestedData(const Record<ESM::Faction>& record,
int subRowIndex, int subColIndex) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::const_iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
switch (subColIndex)
{
case 0: return QString((*iter).first.c_str());
case 1: return (*iter).second;
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
}
void FactionReactionsAdapter::setNestedData(Record<ESM::Faction>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
std::string factionId = (*iter).first;
int reaction = (*iter).second;
switch (subColIndex)
{
case 0:
{
reactions.erase(iter);
reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction));
break;
}
case 1:
{
reactions[factionId] = value.toInt();
break;
}
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
record.setModified (faction);
}
int FactionReactionsAdapter::getNestedColumnsCount(const Record<ESM::Faction>& record) const
{
return 2;
}
int FactionReactionsAdapter::getNestedRowsCount(const Record<ESM::Faction>& record) const
{
return static_cast<int>(record.get().mReactions.size());
}
RegionSoundListAdapter::RegionSoundListAdapter () {}
void RegionSoundListAdapter::addNestedRow(Record<ESM::Region>& record, int position) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
// blank row
ESM::Region::SoundRef soundRef;
soundRef.mSound.assign("");
soundRef.mChance = 0;
soundList.insert(soundList.begin()+position, soundRef);
record.setModified (region);
}
void RegionSoundListAdapter::removeNestedRow(Record<ESM::Region>& record, int rowToRemove) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
soundList.erase(soundList.begin()+rowToRemove);
record.setModified (region);
}
void RegionSoundListAdapter::setNestedTable(Record<ESM::Region>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mSoundList =
static_cast<const NestedTableWrapper<std::vector<ESM::Region::SoundRef> >&>(nestedTable).mNestedTable;
}
NestedTableWrapperBase* RegionSoundListAdapter::nestedTable(const Record<ESM::Region>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::Region::SoundRef> >(record.get().mSoundList);
}
QVariant RegionSoundListAdapter::getNestedData(const Record<ESM::Region>& record,
int subRowIndex, int subColIndex) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
ESM::Region::SoundRef soundRef = soundList[subRowIndex];
switch (subColIndex)
{
case 0: return QString(soundRef.mSound.toString().c_str());
case 1: return soundRef.mChance;
default: throw std::runtime_error("Region sounds subcolumn index out of range");
}
}
void RegionSoundListAdapter::setNestedData(Record<ESM::Region>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
ESM::Region::SoundRef soundRef = soundList[subRowIndex];
switch (subColIndex)
{
case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break;
case 1: soundRef.mChance = static_cast<unsigned char>(value.toInt()); break;
default: throw std::runtime_error("Region sounds subcolumn index out of range");
}
region.mSoundList[subRowIndex] = soundRef;
record.setModified (region);
}
int RegionSoundListAdapter::getNestedColumnsCount(const Record<ESM::Region>& record) const
{
return 2;
}
int RegionSoundListAdapter::getNestedRowsCount(const Record<ESM::Region>& record) const
{
return static_cast<int>(record.get().mSoundList.size());
}
}

View file

@ -4,8 +4,6 @@
#include <QVariant> #include <QVariant>
#include <components/esm/loadpgrd.hpp> #include <components/esm/loadpgrd.hpp>
#include <components/esm/loadregn.hpp>
#include <components/esm/loadfact.hpp>
#include <components/esm/effectlist.hpp> #include <components/esm/effectlist.hpp>
#include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back #include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back
#include <components/esm/loadskil.hpp> // for converting skill names #include <components/esm/loadskil.hpp> // for converting skill names
@ -14,83 +12,15 @@
#include "idadapter.hpp" #include "idadapter.hpp"
#include "nestedtablewrapper.hpp" #include "nestedtablewrapper.hpp"
namespace ESM
{
struct Faction;
struct Region;
}
namespace CSMWorld namespace CSMWorld
{ {
template<typename ESXRecordT> struct Pathgrid;
class PathgridPointListAdapter : public NestedIdAdapter<ESXRecordT>
{
public:
PathgridPointListAdapter () {}
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
// blank row
ESM::Pathgrid::Point point;
point.mX = 0;
point.mY = 0;
point.mZ = 0;
point.mAutogenerated = 0;
point.mConnectionNum = 0;
point.mUnknown = 0;
// inserting a point should trigger re-indexing of the edges
//
// FIXME: undo does not restore edges table view
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (;iter != pathgrid.mEdges.end(); ++iter)
{
if ((*iter).mV0 >= position)
(*iter).mV0++;
if ((*iter).mV1 >= position)
(*iter).mV1++;
}
points.insert(points.begin()+position, point);
pathgrid.mData.mS2 += 1; // increment the number of points
record.setModified (pathgrid);
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (points.size()))
throw std::runtime_error ("index out of range");
// deleting a point should trigger re-indexing of the edges
// dangling edges are not allowed and hence removed
//
// FIXME: undo does not restore edges table view
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (; iter != pathgrid.mEdges.end();)
{
if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove))
iter = pathgrid.mEdges.erase(iter);
else
{
if ((*iter).mV0 > rowToRemove)
(*iter).mV0--;
if ((*iter).mV1 > rowToRemove)
(*iter).mV1--;
++iter;
}
}
points.erase(points.begin()+rowToRemove);
pathgrid.mData.mS2 -= 1; // decrement the number of points
record.setModified (pathgrid);
}
struct PathgridPointsWrap : public NestedTableWrapperBase struct PathgridPointsWrap : public NestedTableWrapperBase
{ {
@ -107,389 +37,104 @@ namespace CSMWorld
} }
}; };
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const class PathgridPointListAdapter : public NestedIdAdapter<Pathgrid>
{
record.get().mPoints =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mPoints;
record.get().mData.mS2 =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mData.mS2;
// also update edges in case points were added/removed
record.get().mEdges =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mEdges;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new PathgridPointsWrap(record.get());
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return point.mX;
case 2: return point.mY;
case 3: return point.mZ;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
}
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: point.mX = value.toInt(); break;
case 2: point.mY = value.toInt(); break;
case 3: point.mZ = value.toInt(); break;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
pathgrid.mPoints[subRowIndex] = point;
record.setModified (pathgrid);
}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 4;
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mPoints.size());
}
};
template<typename ESXRecordT>
class PathgridEdgeListAdapter : public NestedIdAdapter<ESXRecordT>
{ {
public: public:
PathgridEdgeListAdapter () {} PathgridPointListAdapter ();
// FIXME: seems to be auto-sorted in the dialog table display after insertion virtual void addNestedRow(Record<Pathgrid>& record, int position) const;
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; virtual void removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const;
// blank row virtual void setNestedTable(Record<Pathgrid>& record,
ESM::Pathgrid::Edge edge; const NestedTableWrapperBase& nestedTable) const;
edge.mV0 = 0;
edge.mV1 = 0;
// NOTE: inserting a blank edge does not really make sense, perhaps this should be a virtual NestedTableWrapperBase* nestedTable(const Record<Pathgrid>& record) const;
// logic_error exception
//
// Currently the code assumes that the end user to know what he/she is doing.
// e.g. Edges come in pairs, from points a->b and b->a
edges.insert(edges.begin()+position, edge);
record.setModified (pathgrid); virtual QVariant getNestedData(const Record<Pathgrid>& record,
} int subRowIndex, int subColIndex) const;
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const virtual void setNestedData(Record<Pathgrid>& record,
{ const QVariant& value, int subRowIndex, int subColIndex) const;
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; virtual int getNestedColumnsCount(const Record<Pathgrid>& record) const;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (edges.size())) virtual int getNestedRowsCount(const Record<Pathgrid>& record) const;
throw std::runtime_error ("index out of range");
edges.erase(edges.begin()+rowToRemove);
record.setModified (pathgrid);
}
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mEdges =
static_cast<const NestedTableWrapper<ESM::Pathgrid::EdgeList> &>(nestedTable).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<ESM::Pathgrid::EdgeList>(record.get().mEdges);
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return edge.mV0;
case 2: return edge.mV1;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
}
// FIXME: detect duplicates in mEdges
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: edge.mV0 = value.toInt(); break;
case 2: edge.mV1 = value.toInt(); break;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
pathgrid.mEdges[subRowIndex] = edge;
record.setModified (pathgrid);
}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 3;
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mEdges.size());
}
}; };
template<typename ESXRecordT> class PathgridEdgeListAdapter : public NestedIdAdapter<Pathgrid>
class FactionReactionsAdapter : public NestedIdAdapter<ESXRecordT>
{ {
public: public:
FactionReactionsAdapter () {} PathgridEdgeListAdapter ();
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const virtual void addNestedRow(Record<Pathgrid>& record, int position) const;
{
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions; virtual void removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const;
// blank row virtual void setNestedTable(Record<Pathgrid>& record,
reactions.insert(std::make_pair("", 0)); const NestedTableWrapperBase& nestedTable) const;
record.setModified (faction); virtual NestedTableWrapperBase* nestedTable(const Record<Pathgrid>& record) const;
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const virtual QVariant getNestedData(const Record<Pathgrid>& record,
{ int subRowIndex, int subColIndex) const;
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions; virtual void setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (reactions.size())) virtual int getNestedColumnsCount(const Record<Pathgrid>& record) const;
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies? virtual int getNestedRowsCount(const Record<Pathgrid>& record) const;
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < rowToRemove; ++i)
iter++;
reactions.erase(iter);
record.setModified (faction);
}
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mReactions =
static_cast<const NestedTableWrapper<std::map<std::string, int> >&>(nestedTable).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::map<std::string, int> >(record.get().mReactions);
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::const_iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
switch (subColIndex)
{
case 0: return QString((*iter).first.c_str());
case 1: return (*iter).second;
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
}
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
std::string factionId = (*iter).first;
int reaction = (*iter).second;
switch (subColIndex)
{
case 0:
{
reactions.erase(iter);
reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction));
break;
}
case 1:
{
reactions[factionId] = value.toInt();
break;
}
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
record.setModified (faction);
}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 2;
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mReactions.size());
}
}; };
template<typename ESXRecordT> class FactionReactionsAdapter : public NestedIdAdapter<ESM::Faction>
class RegionSoundListAdapter : public NestedIdAdapter<ESXRecordT>
{ {
public: public:
RegionSoundListAdapter () {} FactionReactionsAdapter ();
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const virtual void addNestedRow(Record<ESM::Faction>& record, int position) const;
virtual void removeNestedRow(Record<ESM::Faction>& record, int rowToRemove) const;
virtual void setNestedTable(Record<ESM::Faction>& record,
const NestedTableWrapperBase& nestedTable) const;
virtual NestedTableWrapperBase* nestedTable(const Record<ESM::Faction>& record) const;
virtual QVariant getNestedData(const Record<ESM::Faction>& record,
int subRowIndex, int subColIndex) const;
virtual void setNestedData(Record<ESM::Faction>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const Record<ESM::Faction>& record) const;
virtual int getNestedRowsCount(const Record<ESM::Faction>& record) const;
};
class RegionSoundListAdapter : public NestedIdAdapter<ESM::Region>
{ {
ESXRecordT region = record.get(); public:
RegionSoundListAdapter ();
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList; virtual void addNestedRow(Record<ESM::Region>& record, int position) const;
// blank row virtual void removeNestedRow(Record<ESM::Region>& record, int rowToRemove) const;
typename ESXRecordT::SoundRef soundRef;
soundRef.mSound.assign("");
soundRef.mChance = 0;
soundList.insert(soundList.begin()+position, soundRef); virtual void setNestedTable(Record<ESM::Region>& record,
const NestedTableWrapperBase& nestedTable) const;
record.setModified (region); virtual NestedTableWrapperBase* nestedTable(const Record<ESM::Region>& record) const;
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const virtual QVariant getNestedData(const Record<ESM::Region>& record,
{ int subRowIndex, int subColIndex) const;
ESXRecordT region = record.get();
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList; virtual void setNestedData(Record<ESM::Region>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (soundList.size())) virtual int getNestedColumnsCount(const Record<ESM::Region>& record) const;
throw std::runtime_error ("index out of range");
soundList.erase(soundList.begin()+rowToRemove); virtual int getNestedRowsCount(const Record<ESM::Region>& record) const;
record.setModified (region);
}
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mSoundList =
static_cast<const NestedTableWrapper<std::vector<typename ESXRecordT::SoundRef> >&>(nestedTable).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<typename ESXRecordT::SoundRef> >(record.get().mSoundList);
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESXRecordT region = record.get();
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex];
switch (subColIndex)
{
case 0: return QString(soundRef.mSound.toString().c_str());
case 1: return soundRef.mChance;
default: throw std::runtime_error("Region sounds subcolumn index out of range");
}
}
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT region = record.get();
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex];
switch (subColIndex)
{
case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break;
case 1: soundRef.mChance = static_cast<unsigned char>(value.toInt()); break;
default: throw std::runtime_error("Region sounds subcolumn index out of range");
}
region.mSoundList[subRowIndex] = soundRef;
record.setModified (region);
}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 2;
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mSoundList.size());
}
}; };
template<typename ESXRecordT> template<typename ESXRecordT>