Get rid of reinterpret cast.

new-script-api
Kyle Cooley 7 years ago
parent 50d9d9f78f
commit 4921e7f5c1

@ -1,6 +1,7 @@
#include "columnimp.hpp" #include "columnimp.hpp"
#include <stdexcept> #include <stdexcept>
#include <QVector>
namespace CSMWorld namespace CSMWorld
{ {
@ -86,33 +87,32 @@ namespace CSMWorld
const int Size = Land::LAND_GLOBAL_MAP_LOD_SIZE; const int Size = Land::LAND_GLOBAL_MAP_LOD_SIZE;
const Land& land = record.get(); const Land& land = record.get();
DataType values(Size, 0);
if (land.isDataLoaded(Land::DATA_WNAM)) if (land.isDataLoaded(Land::DATA_WNAM))
{ {
// Note: original data is signed for (int i = 0; i < Size; ++i)
const char* rawData = reinterpret_cast<const char*>(&land.mWnam[0]); values[i] = land.mWnam[i];
return QByteArray(rawData, Size);
}
else
{
// Return a blank array
return QByteArray(Size, 0);
} }
QVariant variant;
variant.setValue(values);
return variant;
} }
void LandMapLodColumn::set(Record<Land>& record, const QVariant& data) void LandMapLodColumn::set(Record<Land>& record, const QVariant& data)
{ {
QByteArray array = data.toByteArray(); DataType values = data.value<DataType>();
const signed char* rawData = reinterpret_cast<const signed char*>(array.data());
if (array.count() != Land::LAND_GLOBAL_MAP_LOD_SIZE) if (values.size() != Land::LAND_GLOBAL_MAP_LOD_SIZE)
throw std::runtime_error("invalid land map LOD data"); throw std::runtime_error("invalid land map LOD data");
Land copy = record.get(); Land copy = record.get();
copy.setDataLoaded(Land::DATA_WNAM); copy.setDataLoaded(Land::DATA_WNAM);
for (int i = 0; i < array.count(); ++i) for (int i = 0; i < values.size(); ++i)
{ {
copy.mWnam[i] = rawData[i]; copy.mWnam[i] = values[i];
} }
record.setModified(copy); record.setModified(copy);
@ -134,33 +134,32 @@ namespace CSMWorld
const int Size = Land::LAND_NUM_VERTS * 3; const int Size = Land::LAND_NUM_VERTS * 3;
const Land& land = record.get(); const Land& land = record.get();
DataType values(Size, 0);
if (land.isDataLoaded(Land::DATA_VNML)) if (land.isDataLoaded(Land::DATA_VNML))
{ {
// Note: original data is signed for (int i = 0; i < Size; ++i)
const char* rawData = reinterpret_cast<const char*>(&land.getLandData()->mNormals[0]); values[i] = land.getLandData()->mNormals[i];
return QByteArray(rawData, Size);
}
else
{
// Return a blank array
return QByteArray(Size, 0);
} }
QVariant variant;
variant.setValue(values);
return variant;
} }
void LandNormalsColumn::set(Record<Land>& record, const QVariant& data) void LandNormalsColumn::set(Record<Land>& record, const QVariant& data)
{ {
QByteArray array = data.toByteArray(); DataType values = data.value<DataType>();
const signed char* rawData = reinterpret_cast<const signed char*>(array.data());
if (array.count() != Land::LAND_NUM_VERTS * 3) if (values.size() != Land::LAND_NUM_VERTS * 3)
throw std::runtime_error("invalid land normals data"); throw std::runtime_error("invalid land normals data");
Land copy = record.get(); Land copy = record.get();
copy.setDataLoaded(Land::DATA_VNML); copy.setDataLoaded(Land::DATA_VNML);
for (int i = 0; i < array.count(); ++i) for (int i = 0; i < values.size(); ++i)
{ {
copy.getLandData()->mNormals[i] = rawData[i]; copy.getLandData()->mNormals[i] = values[i];
} }
record.setModified(copy); record.setModified(copy);
@ -179,36 +178,35 @@ namespace CSMWorld
QVariant LandHeightsColumn::get(const Record<Land>& record) const QVariant LandHeightsColumn::get(const Record<Land>& record) const
{ {
const int Size = Land::LAND_NUM_VERTS * sizeof(float); const int Size = Land::LAND_NUM_VERTS;
const Land& land = record.get(); const Land& land = record.get();
DataType values(Size, 0);
if (land.isDataLoaded(Land::DATA_VHGT)) if (land.isDataLoaded(Land::DATA_VHGT))
{ {
// Note: original data is float for (int i = 0; i < Size; ++i)
const char* rawData = reinterpret_cast<const char*>(&land.getLandData()->mHeights[0]); values[i] = land.getLandData()->mHeights[i];
return QByteArray(rawData, Size);
}
else
{
return QByteArray(Size, 0);
} }
QVariant variant;
variant.setValue(values);
return variant;
} }
void LandHeightsColumn::set(Record<Land>& record, const QVariant& data) void LandHeightsColumn::set(Record<Land>& record, const QVariant& data)
{ {
QByteArray array = data.toByteArray(); DataType values = data.value<DataType>();
const float* rawData = reinterpret_cast<const float*>(array.data());
if (array.count() != Land::LAND_NUM_VERTS * sizeof(float)) if (values.size() != Land::LAND_NUM_VERTS)
throw std::runtime_error("invalid land heights data"); throw std::runtime_error("invalid land heights data");
Land copy = record.get(); Land copy = record.get();
copy.setDataLoaded(Land::DATA_VHGT); copy.setDataLoaded(Land::DATA_VHGT);
int count = array.count() / sizeof(float); for (int i = 0; i < values.size(); ++i)
for (int i = 0; i < count; ++i)
{ {
copy.getLandData()->mHeights[i] = rawData[i]; copy.getLandData()->mHeights[i] = values[i];
} }
record.setModified(copy); record.setModified(copy);
@ -230,32 +228,32 @@ namespace CSMWorld
const int Size = Land::LAND_NUM_VERTS * 3; const int Size = Land::LAND_NUM_VERTS * 3;
const Land& land = record.get(); const Land& land = record.get();
DataType values(Size, 0);
if (land.isDataLoaded(Land::DATA_VCLR)) if (land.isDataLoaded(Land::DATA_VCLR))
{ {
// Note: original data is unsigned char for (int i = 0; i < Size; ++i)
const char* rawData = reinterpret_cast<const char*>(&land.getLandData()->mColours[0]); values[i] = land.getLandData()->mColours[i];
return QByteArray(rawData, Size);
}
else
{
return QByteArray(Size, 0);
} }
QVariant variant;
variant.setValue(values);
return variant;
} }
void LandColoursColumn::set(Record<Land>& record, const QVariant& data) void LandColoursColumn::set(Record<Land>& record, const QVariant& data)
{ {
QByteArray array = data.toByteArray(); DataType values = data.value<DataType>();
const unsigned char* rawData = reinterpret_cast<const unsigned char*>(array.data());
if (array.count() != Land::LAND_NUM_VERTS * 3) if (values.size() != Land::LAND_NUM_VERTS * 3)
throw std::runtime_error("invalid land colours data"); throw std::runtime_error("invalid land colours data");
Land copy = record.get(); Land copy = record.get();
copy.setDataLoaded(Land::DATA_VCLR); copy.setDataLoaded(Land::DATA_VCLR);
for (int i = 0; i < array.count(); ++i) for (int i = 0; i < values.size(); ++i)
{ {
copy.getLandData()->mColours[i] = rawData[i]; copy.getLandData()->mColours[i] = values[i];
} }
record.setModified(copy); record.setModified(copy);
@ -274,36 +272,35 @@ namespace CSMWorld
QVariant LandTexturesColumn::get(const Record<Land>& record) const QVariant LandTexturesColumn::get(const Record<Land>& record) const
{ {
const int Size = Land::LAND_NUM_TEXTURES * sizeof(uint16_t); const int Size = Land::LAND_NUM_TEXTURES;
const Land& land = record.get(); const Land& land = record.get();
DataType values(Size, 0);
if (land.isDataLoaded(Land::DATA_VTEX)) if (land.isDataLoaded(Land::DATA_VTEX))
{ {
// Note: original data is uint16_t for (int i = 0; i < Size; ++i)
const char* rawData = reinterpret_cast<const char*>(&land.getLandData()->mTextures[0]); values[i] = land.getLandData()->mTextures[i];
return QByteArray(rawData, Size);
}
else
{
return QByteArray(Size, 0);
} }
QVariant variant;
variant.setValue(values);
return variant;
} }
void LandTexturesColumn::set(Record<Land>& record, const QVariant& data) void LandTexturesColumn::set(Record<Land>& record, const QVariant& data)
{ {
QByteArray array = data.toByteArray(); DataType values = data.value<DataType>();
const uint16_t* rawData = reinterpret_cast<const uint16_t*>(array.data());
if (array.count() != Land::LAND_NUM_TEXTURES * sizeof(uint16_t)) if (values.size() != Land::LAND_NUM_TEXTURES)
throw std::runtime_error("invalid land textures data"); throw std::runtime_error("invalid land textures data");
Land copy = record.get(); Land copy = record.get();
copy.setDataLoaded(Land::DATA_VTEX); copy.setDataLoaded(Land::DATA_VTEX);
int count = array.count() / sizeof(uint16_t); for (int i = 0; i < values.size(); ++i)
for (int i = 0; i < count; ++i)
{ {
copy.getLandData()->mTextures[i] = rawData[i]; copy.getLandData()->mTextures[i] = values[i];
} }
record.setModified(copy); record.setModified(copy);

@ -2,10 +2,12 @@
#define CSM_WOLRD_COLUMNIMP_H #define CSM_WOLRD_COLUMNIMP_H
#include <cassert> #include <cassert>
#include <cstdint>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <QColor> #include <QColor>
#include <QVector>
#include <components/esm/loadbody.hpp> #include <components/esm/loadbody.hpp>
#include <components/esm/loadskil.hpp> #include <components/esm/loadskil.hpp>
@ -2470,6 +2472,8 @@ namespace CSMWorld
struct LandMapLodColumn : public Column<Land> struct LandMapLodColumn : public Column<Land>
{ {
using DataType = QVector<signed char>;
LandMapLodColumn(); LandMapLodColumn();
QVariant get(const Record<Land>& record) const override; QVariant get(const Record<Land>& record) const override;
@ -2479,6 +2483,8 @@ namespace CSMWorld
struct LandNormalsColumn : public Column<Land> struct LandNormalsColumn : public Column<Land>
{ {
using DataType = QVector<signed char>;
LandNormalsColumn(); LandNormalsColumn();
QVariant get(const Record<Land>& record) const override; QVariant get(const Record<Land>& record) const override;
@ -2488,6 +2494,8 @@ namespace CSMWorld
struct LandHeightsColumn : public Column<Land> struct LandHeightsColumn : public Column<Land>
{ {
using DataType = QVector<float>;
LandHeightsColumn(); LandHeightsColumn();
QVariant get(const Record<Land>& record) const override; QVariant get(const Record<Land>& record) const override;
@ -2497,6 +2505,8 @@ namespace CSMWorld
struct LandColoursColumn : public Column<Land> struct LandColoursColumn : public Column<Land>
{ {
using DataType = QVector<unsigned char>;
LandColoursColumn(); LandColoursColumn();
QVariant get(const Record<Land>& record) const override; QVariant get(const Record<Land>& record) const override;
@ -2506,6 +2516,8 @@ namespace CSMWorld
struct LandTexturesColumn : public Column<Land> struct LandTexturesColumn : public Column<Land>
{ {
using DataType = QVector<uint16_t>;
LandTexturesColumn(); LandTexturesColumn();
QVariant get(const Record<Land>& record) const override; QVariant get(const Record<Land>& record) const override;

@ -58,23 +58,21 @@ void CSMWorld::ImportLandTexturesCommand::redo()
// Original data // Original data
int textureColumn = mLands.findColumnIndex(Columns::ColumnId_LandTexturesIndex); int textureColumn = mLands.findColumnIndex(Columns::ColumnId_LandTexturesIndex);
mOld = mLands.data(mLands.getModelIndex(getOriginId(), textureColumn)).toByteArray(); mOld = mLands.data(mLands.getModelIndex(getOriginId(), textureColumn)).value<DataType>();
const uint16_t* textureData = reinterpret_cast<uint16_t*>(mOld.data());
// Need to make a copy so the old values can be looked up // Need to make a copy so the old values can be looked up
QByteArray newTextureByteArray(mOld.data(), mOld.size()); DataType copy(mOld);
uint16_t* newTextureData = reinterpret_cast<uint16_t*>(newTextureByteArray.data());
// Perform touch/copy/etc... // Perform touch/copy/etc...
onRedo(); onRedo();
// Find all indices used // Find all indices used
std::unordered_set<int> texIndices; std::unordered_set<int> texIndices;
for (int i = 0; i < Land::LAND_NUM_TEXTURES; ++i) for (int i = 0; i < mOld.size(); ++i)
{ {
// All indices are offset by 1 for a default texture // All indices are offset by 1 for a default texture
if (textureData[i] > 0) if (mOld[i] > 0)
texIndices.insert(textureData[i] - 1); texIndices.insert(mOld[i] - 1);
} }
std::vector<std::string> oldTextures; std::vector<std::string> oldTextures;
@ -97,8 +95,8 @@ void CSMWorld::ImportLandTexturesCommand::redo()
for (int i = 0; i < Land::LAND_NUM_TEXTURES; ++i) for (int i = 0; i < Land::LAND_NUM_TEXTURES; ++i)
{ {
// All indices are offset by 1 for a default texture // All indices are offset by 1 for a default texture
if (textureData[i] == oldIndex + 1) if (mOld[i] == oldIndex + 1)
newTextureData[i] = newIndex + 1; copy[i] = newIndex + 1;
} }
} }
} }
@ -107,14 +105,18 @@ void CSMWorld::ImportLandTexturesCommand::redo()
int stateColumn = mLands.findColumnIndex(Columns::ColumnId_Modification); int stateColumn = mLands.findColumnIndex(Columns::ColumnId_Modification);
mOldState = mLands.data(mLands.getModelIndex(getDestinationId(), stateColumn)).toInt(); mOldState = mLands.data(mLands.getModelIndex(getDestinationId(), stateColumn)).toInt();
mLands.setData(mLands.getModelIndex(getDestinationId(), textureColumn), newTextureByteArray); QVariant variant;
variant.setValue(copy);
mLands.setData(mLands.getModelIndex(getDestinationId(), textureColumn), variant);
} }
void CSMWorld::ImportLandTexturesCommand::undo() void CSMWorld::ImportLandTexturesCommand::undo()
{ {
// Restore to previous // Restore to previous
int textureColumn = mLands.findColumnIndex(Columns::ColumnId_LandTexturesIndex); int textureColumn = mLands.findColumnIndex(Columns::ColumnId_LandTexturesIndex);
mLands.setData(mLands.getModelIndex(getDestinationId(), textureColumn), mOld); QVariant variant;
variant.setValue(mOld);
mLands.setData(mLands.getModelIndex(getDestinationId(), textureColumn), variant);
int stateColumn = mLands.findColumnIndex(Columns::ColumnId_Modification); int stateColumn = mLands.findColumnIndex(Columns::ColumnId_Modification);
mLands.setData(mLands.getModelIndex(getDestinationId(), stateColumn), mOldState); mLands.setData(mLands.getModelIndex(getDestinationId(), stateColumn), mOldState);

@ -3,12 +3,14 @@
#include "record.hpp" #include "record.hpp"
#include <cstdint>
#include <string> #include <string>
#include <map> #include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <QVariant> #include <QVariant>
#include <QVector>
#include <QUndoCommand> #include <QUndoCommand>
#include <QModelIndex> #include <QModelIndex>
@ -55,6 +57,8 @@ namespace CSMWorld
protected: protected:
using DataType = QVector<uint16_t>;
virtual const std::string& getOriginId() const = 0; virtual const std::string& getOriginId() const = 0;
virtual const std::string& getDestinationId() const = 0; virtual const std::string& getDestinationId() const = 0;
@ -63,7 +67,7 @@ namespace CSMWorld
IdTable& mLands; IdTable& mLands;
IdTable& mLtexs; IdTable& mLtexs;
QByteArray mOld; DataType mOld;
int mOldState; int mOldState;
std::vector<std::string> mCreatedTextures; std::vector<std::string> mCreatedTextures;
}; };

Loading…
Cancel
Save