openmw-tes3coop/apps/opencs/model/world/nestedadaptors.hpp

188 lines
6.4 KiB
C++
Raw Normal View History

#ifndef CSM_WORLD_NESTEDADAPTORS_H
#define CSM_WORLD_NESTEDADAPTORS_H
#include <vector>
#include <stdexcept>
#include "universalid.hpp"
#include "nestedtablewrapper.hpp"
#include "record.hpp"
#include "refiddata.hpp"
#include "refidadapter.hpp"
2014-07-22 08:27:45 +00:00
#include <components/esm/loadcont.hpp>
#include <QVariant>
2014-07-23 18:33:52 +00:00
/*! \brief
* Nested adapter redirects responsibility to the helper class. Helper classes are polymorhpic (vide HelperBase and CastableHelper) and most likely templates.
*/
namespace CSMWorld
{
2014-07-22 08:27:45 +00:00
class RefIdColumn;
class HelperBase
{
2014-07-22 08:27:45 +00:00
protected:
const CSMWorld::UniversalId::Type mType;
public:
2014-07-22 08:27:45 +00:00
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;
2014-07-22 08:27:45 +00:00
virtual int getNestedColumnsCount(const RefIdData& data) const = 0;
2014-07-22 08:27:45 +00:00
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 InventoryHelper : public CastableHelper<ESXRecordT>
2014-07-22 08:27:45 +00:00
{
public:
InventoryHelper(CSMWorld::UniversalId::Type type)
: CastableHelper<ESXRecordT>(type) {}
2014-07-22 08:27:45 +00:00
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;
}
2014-07-22 08:27:45 +00:00
virtual NestedTableWrapperBase* nestedTable(const RefIdData& data,
int index) const
{
return new NestedTableWrapper<std::vector<ESM::ContItem> >(CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList);
}
2014-07-22 08:27:45 +00:00
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!");
}
}
2014-07-22 08:27:45 +00:00
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);
}
2014-07-22 08:27:45 +00:00
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!");
}
}
2014-07-22 08:27:45 +00:00
virtual void addNestedRow (RefIdData& data, int index, int position) const
2014-07-21 12:58:45 +00:00
{
std::vector<ESM::ContItem>& list = CastableHelper<ESXRecordT>::getRecord(data, index).get().mInventory.mList;
2014-07-21 12:58:45 +00:00
ESM::ContItem newRow = {0, ""};
if (position >= (int)list.size())
{
list.push_back(newRow);
return;
}
list.insert(list.begin()+position, newRow);
}
2014-07-22 08:27:45 +00:00
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