1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 02:53:54 +00:00
openmw/apps/opencs/model/world/idcollection.hpp
fteppe 20da0892ef openMW_test_suite compiles and runs
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
2022-12-27 19:15:55 +01:00

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