mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 02:53:54 +00:00
20da0892ef
Slowly moving through the open-cs errors Good progress in openCS Very good progress on openCS Getting closer with openCS OpenCS compiles and runs! Didn't have time to test it all though ix openMW everything compiles on windows?? Fix gcc Fix Clang
168 lines
5.1 KiB
C++
168 lines
5.1 KiB
C++
#ifndef CSM_WOLRD_IDCOLLECTION_H
|
|
#define CSM_WOLRD_IDCOLLECTION_H
|
|
|
|
#include <filesystem>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include <apps/opencs/model/world/record.hpp>
|
|
|
|
#include <components/esm/esmcommon.hpp>
|
|
#include <components/esm3/loadland.hpp>
|
|
|
|
#include "collection.hpp"
|
|
#include "land.hpp"
|
|
#include "pathgrid.hpp"
|
|
|
|
namespace ESM
|
|
{
|
|
class ESMReader;
|
|
}
|
|
|
|
namespace CSMWorld
|
|
{
|
|
struct Pathgrid;
|
|
|
|
/// \brief Single type collection of top level records
|
|
template <typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT>>
|
|
class IdCollection : public Collection<ESXRecordT, IdAccessorT>
|
|
{
|
|
virtual void loadRecord(ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted);
|
|
|
|
public:
|
|
/// \return Index of loaded record (-1 if no record was loaded)
|
|
int load(ESM::ESMReader& reader, bool base);
|
|
|
|
/// \param index Index at which the record can be found.
|
|
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
|
|
/// does not have an index
|
|
///
|
|
/// \return index
|
|
int load(const ESXRecordT& record, bool base, int index = -2);
|
|
|
|
bool tryDelete(const std::string& id);
|
|
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
|
|
///
|
|
/// \return Has the ID been deleted?
|
|
};
|
|
|
|
template <typename ESXRecordT, typename IdAccessorT>
|
|
void IdCollection<ESXRecordT, IdAccessorT>::loadRecord(ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted)
|
|
{
|
|
record.load(reader, isDeleted);
|
|
}
|
|
|
|
template <>
|
|
inline void IdCollection<Land, IdAccessor<Land>>::loadRecord(Land& record, ESM::ESMReader& reader, bool& isDeleted)
|
|
{
|
|
record.load(reader, isDeleted);
|
|
|
|
// Load all land data for now. A future optimisation may only load non-base data
|
|
// if a suitable mechanism for avoiding race conditions can be established.
|
|
int flags = ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX;
|
|
record.loadData(flags);
|
|
|
|
// Prevent data from being reloaded.
|
|
record.mContext.filename.clear();
|
|
}
|
|
|
|
template <typename ESXRecordT, typename IdAccessorT>
|
|
int IdCollection<ESXRecordT, IdAccessorT>::load(ESM::ESMReader& reader, bool base)
|
|
{
|
|
ESXRecordT record;
|
|
bool isDeleted = false;
|
|
|
|
loadRecord(record, reader, isDeleted);
|
|
|
|
ESM::RefId id = IdAccessorT().getId(record);
|
|
int index = this->searchId(id);
|
|
|
|
if (isDeleted)
|
|
{
|
|
if (index == -1)
|
|
{
|
|
// deleting a record that does not exist
|
|
// ignore it for now
|
|
/// \todo report the problem to the user
|
|
return -1;
|
|
}
|
|
|
|
if (base)
|
|
{
|
|
this->removeRows(index, 1);
|
|
return -1;
|
|
}
|
|
|
|
auto baseRecord = std::make_unique<Record<ESXRecordT>>(this->getRecord(index));
|
|
baseRecord->mState = RecordBase::State_Deleted;
|
|
this->setRecord(index, std::move(baseRecord));
|
|
return index;
|
|
}
|
|
|
|
return load(record, base, index);
|
|
}
|
|
|
|
template <typename ESXRecordT, typename IdAccessorT>
|
|
int IdCollection<ESXRecordT, IdAccessorT>::load(const ESXRecordT& record, bool base, int index)
|
|
{
|
|
if (index == -2) // index unknown
|
|
index = this->searchId(IdAccessorT().getId(record));
|
|
|
|
if (index == -1)
|
|
{
|
|
// new record
|
|
auto record2 = std::make_unique<Record<ESXRecordT>>();
|
|
record2->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
|
(base ? record2->mBase : record2->mModified) = record;
|
|
|
|
index = this->getSize();
|
|
this->appendRecord(std::move(record2));
|
|
}
|
|
else
|
|
{
|
|
// old record
|
|
auto record2 = std::make_unique<Record<ESXRecordT>>(Collection<ESXRecordT, IdAccessorT>::getRecord(index));
|
|
|
|
if (base)
|
|
record2->mBase = record;
|
|
else
|
|
record2->setModified(record);
|
|
|
|
this->setRecord(index, std::move(record2));
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
template <typename ESXRecordT, typename IdAccessorT>
|
|
bool IdCollection<ESXRecordT, IdAccessorT>::tryDelete(const std::string& id)
|
|
{
|
|
int index = this->searchId(id);
|
|
|
|
if (index == -1)
|
|
return false;
|
|
|
|
const Record<ESXRecordT>& record = Collection<ESXRecordT, IdAccessorT>::getRecord(index);
|
|
|
|
if (record.isDeleted())
|
|
return false;
|
|
|
|
if (record.mState == RecordBase::State_ModifiedOnly)
|
|
{
|
|
Collection<ESXRecordT, IdAccessorT>::removeRows(index, 1);
|
|
}
|
|
else
|
|
{
|
|
auto record2 = std::make_unique<Record<ESXRecordT>>(Collection<ESXRecordT, IdAccessorT>::getRecord(index));
|
|
record2->mState = RecordBase::State_Deleted;
|
|
this->setRecord(index, std::move(record2));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template <>
|
|
int IdCollection<Pathgrid, IdAccessor<Pathgrid>>::load(ESM::ESMReader& reader, bool base);
|
|
}
|
|
|
|
#endif
|