You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/apps/opencs/model/world/infocollection.hpp

92 lines
3.5 KiB
C++

#ifndef CSM_WOLRD_INFOCOLLECTION_H
#define CSM_WOLRD_INFOCOLLECTION_H
#include <string_view>
#include <unordered_map>
#include "collection.hpp"
#include "info.hpp"
namespace ESM
{
struct Dialogue;
}
namespace CSMWorld
{
template <>
void Collection<Info, IdAccessor<Info>>::removeRows(int index, int count);
template <>
void Collection<Info, IdAccessor<Info>>::insertRecord(
std::unique_ptr<RecordBase> record, int index, UniversalId::Type type);
template <>
bool Collection<Info, IdAccessor<Info>>::reorderRowsImp(int baseIndex, const std::vector<int>& newOrder);
class InfoCollection : public Collection<Info, IdAccessor<Info>>
{
public:
typedef std::vector<std::unique_ptr<Record<Info>>>::const_iterator RecordConstIterator;
typedef std::pair<RecordConstIterator, RecordConstIterator> Range;
private:
// The general strategy is to keep the records in Collection kept in order (within
// a topic group) while the index lookup maps are not ordered. It is assumed that
// each topic has a small number of infos, which allows the use of vectors for
// iterating through them without too much penalty.
//
// NOTE: topic string as well as id string are stored in lower case.
std::unordered_map<std::string, std::vector<std::pair<std::string, int>>> mInfoIndex;
void load(const Info& record, bool base);
int getInfoIndex(std::string_view id, std::string_view topic) const;
///< Return index for record \a id or -1 (if not present; deleted records are considered)
///
/// \param id info ID without topic prefix
//
/// \attention id and topic are assumed to be in lower case
public:
int getInsertIndex(const std::string& id, UniversalId::Type type = UniversalId::Type_None,
RecordBase* record = nullptr) const override;
///< \param type Will be ignored, unless the collection supports multiple record types
///
/// Works like getAppendIndex unless an overloaded method uses the record pointer
/// to get additional info about the record that results in an alternative index.
int getAppendIndex(const std::string& id, UniversalId::Type type) const override
{
return getInsertIndex(id, type);
}
bool reorderRows(int baseIndex, const std::vector<int>& newOrder) override;
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
///
/// \return Success?
void load(ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue);
Range getTopicRange(const std::string& topic) const;
///< Return iterators that point to the beginning and past the end of the range for
/// the given topic.
void removeDialogueInfos(const std::string& dialogueId);
void removeRows(int index, int count) override;
void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) override;
int searchId(std::string_view id) const override;
void appendRecord(std::unique_ptr<RecordBase> record, UniversalId::Type type = UniversalId::Type_None) override;
void insertRecord(
std::unique_ptr<RecordBase> record, int index, UniversalId::Type type = UniversalId::Type_None) override;
};
}
#endif