mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-22 11:23:27 -04:00
Remove journal iterator methods
This commit is contained in:
parent
4fd9e5b2bb
commit
15eecec196
@ -36,11 +36,8 @@ namespace MWBase
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::deque<MWDialogue::StampedJournalEntry> TEntryContainer;
|
typedef std::deque<MWDialogue::StampedJournalEntry> TEntryContainer;
|
||||||
typedef TEntryContainer::const_iterator TEntryIter;
|
|
||||||
typedef std::map<ESM::RefId, MWDialogue::Quest> TQuestContainer; // topic, quest
|
typedef std::map<ESM::RefId, MWDialogue::Quest> TQuestContainer; // topic, quest
|
||||||
typedef TQuestContainer::const_iterator TQuestIter;
|
|
||||||
typedef std::map<ESM::RefId, MWDialogue::Topic> TTopicContainer; // topic-id, topic-content
|
typedef std::map<ESM::RefId, MWDialogue::Topic> TTopicContainer; // topic-id, topic-content
|
||||||
typedef TTopicContainer::const_iterator TTopicIter;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Journal() {}
|
Journal() {}
|
||||||
@ -71,32 +68,12 @@ namespace MWBase
|
|||||||
///< Removes the last topic response added for the given topicId and actor name.
|
///< Removes the last topic response added for the given topicId and actor name.
|
||||||
/// \note topicId must be lowercase
|
/// \note topicId must be lowercase
|
||||||
|
|
||||||
virtual TEntryIter begin() const = 0;
|
|
||||||
///< Iterator pointing to the begin of the main journal.
|
|
||||||
///
|
|
||||||
/// \note Iterators to main journal entries will never become invalid.
|
|
||||||
|
|
||||||
virtual TEntryIter end() const = 0;
|
|
||||||
///< Iterator pointing past the end of the main journal.
|
|
||||||
|
|
||||||
virtual const TEntryContainer& getEntries() const = 0;
|
virtual const TEntryContainer& getEntries() const = 0;
|
||||||
|
|
||||||
virtual TQuestIter questBegin() const = 0;
|
|
||||||
///< Iterator pointing to the first quest (sorted by topic ID)
|
|
||||||
|
|
||||||
virtual TQuestIter questEnd() const = 0;
|
|
||||||
///< Iterator pointing past the last quest.
|
|
||||||
|
|
||||||
virtual TTopicIter topicBegin() const = 0;
|
|
||||||
///< Iterator pointing to the first topic (sorted by topic ID)
|
|
||||||
///
|
|
||||||
/// \note The topic ID is identical with the user-visible topic string.
|
|
||||||
|
|
||||||
virtual TTopicIter topicEnd() const = 0;
|
|
||||||
///< Iterator pointing past the last topic.
|
|
||||||
|
|
||||||
virtual const TTopicContainer& getTopics() const = 0;
|
virtual const TTopicContainer& getTopics() const = 0;
|
||||||
|
|
||||||
|
virtual const TQuestContainer& getQuests() const = 0;
|
||||||
|
|
||||||
virtual int countSavedGameRecords() const = 0;
|
virtual int countSavedGameRecords() const = 0;
|
||||||
|
|
||||||
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
||||||
|
@ -264,24 +264,13 @@ namespace MWDialogue
|
|||||||
|
|
||||||
bool DialogueManager::inJournal(const ESM::RefId& topicId, const ESM::RefId& infoId) const
|
bool DialogueManager::inJournal(const ESM::RefId& topicId, const ESM::RefId& infoId) const
|
||||||
{
|
{
|
||||||
const MWDialogue::Topic* topicHistory = nullptr;
|
|
||||||
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
||||||
for (auto it = journal->topicBegin(); it != journal->topicEnd(); ++it)
|
const auto topic = journal->getTopics().find(topicId);
|
||||||
|
if (topic != journal->getTopics().end())
|
||||||
{
|
{
|
||||||
if (it->first == topicId)
|
return std::ranges::find_if(topic->second, [&](const MWDialogue::Entry& entry) {
|
||||||
{
|
return entry.mInfoId == infoId;
|
||||||
topicHistory = &it->second;
|
}) != topic->second.end();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!topicHistory)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (const auto& topic : *topicHistory)
|
|
||||||
{
|
|
||||||
if (topic.mInfoId == infoId)
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,8 @@ namespace MWDialogue
|
|||||||
if (infoId.empty())
|
if (infoId.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (ESM::Dialogue::InfoContainer::const_iterator iter(dialogue->mInfo.begin());
|
for (const ESM::DialInfo& info : dialogue->mInfo)
|
||||||
iter != dialogue->mInfo.end(); ++iter)
|
if (info.mId == infoId)
|
||||||
if (iter->mId == infoId)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +82,8 @@ namespace MWDialogue
|
|||||||
{
|
{
|
||||||
// bail out if we already have heard this...
|
// bail out if we already have heard this...
|
||||||
const ESM::RefId& infoId = JournalEntry::idFromIndex(id, index);
|
const ESM::RefId& infoId = JournalEntry::idFromIndex(id, index);
|
||||||
for (TEntryIter i = mJournal.begin(); i != mJournal.end(); ++i)
|
for (const JournalEntry& entry : mJournal)
|
||||||
if (i->mTopic == id && i->mInfoId == infoId)
|
if (entry.mTopic == id && entry.mInfoId == infoId)
|
||||||
{
|
{
|
||||||
if (getJournalIndex(id) < index)
|
if (getJournalIndex(id) < index)
|
||||||
{
|
{
|
||||||
@ -152,95 +151,61 @@ namespace MWDialogue
|
|||||||
return iter->second.getIndex();
|
return iter->second.getIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
Journal::TEntryIter Journal::begin() const
|
|
||||||
{
|
|
||||||
return mJournal.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
Journal::TEntryIter Journal::end() const
|
|
||||||
{
|
|
||||||
return mJournal.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
Journal::TQuestIter Journal::questBegin() const
|
|
||||||
{
|
|
||||||
return mQuests.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
Journal::TQuestIter Journal::questEnd() const
|
|
||||||
{
|
|
||||||
return mQuests.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
Journal::TTopicIter Journal::topicBegin() const
|
|
||||||
{
|
|
||||||
return mTopics.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
Journal::TTopicIter Journal::topicEnd() const
|
|
||||||
{
|
|
||||||
return mTopics.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Journal::countSavedGameRecords() const
|
int Journal::countSavedGameRecords() const
|
||||||
{
|
{
|
||||||
int count = static_cast<int>(mQuests.size());
|
std::size_t count = mQuests.size();
|
||||||
|
|
||||||
for (TQuestIter iter(mQuests.begin()); iter != mQuests.end(); ++iter)
|
for (const auto& [_, quest] : mQuests)
|
||||||
count += std::distance(iter->second.begin(), iter->second.end());
|
count += quest.size();
|
||||||
|
|
||||||
count += std::distance(mJournal.begin(), mJournal.end());
|
count += mJournal.size();
|
||||||
|
|
||||||
for (TTopicIter iter(mTopics.begin()); iter != mTopics.end(); ++iter)
|
for (const auto& [_, topic] : mTopics)
|
||||||
count += std::distance(iter->second.begin(), iter->second.end());
|
count += topic.size();
|
||||||
|
|
||||||
return count;
|
return static_cast<int>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Journal::write(ESM::ESMWriter& writer, Loading::Listener& progress) const
|
void Journal::write(ESM::ESMWriter& writer, Loading::Listener& progress) const
|
||||||
{
|
{
|
||||||
for (TQuestIter iter(mQuests.begin()); iter != mQuests.end(); ++iter)
|
for (const auto& [_, quest] : mQuests)
|
||||||
{
|
{
|
||||||
const Quest& quest = iter->second;
|
|
||||||
|
|
||||||
ESM::QuestState state;
|
ESM::QuestState state;
|
||||||
quest.write(state);
|
quest.write(state);
|
||||||
writer.startRecord(ESM::REC_QUES);
|
writer.startRecord(ESM::REC_QUES);
|
||||||
state.save(writer);
|
state.save(writer);
|
||||||
writer.endRecord(ESM::REC_QUES);
|
writer.endRecord(ESM::REC_QUES);
|
||||||
|
|
||||||
for (Topic::TEntryIter entryIter(quest.begin()); entryIter != quest.end(); ++entryIter)
|
for (const Entry& questEntry : quest)
|
||||||
{
|
{
|
||||||
ESM::JournalEntry entry;
|
ESM::JournalEntry entry;
|
||||||
entry.mType = ESM::JournalEntry::Type_Quest;
|
entry.mType = ESM::JournalEntry::Type_Quest;
|
||||||
entry.mTopic = quest.getTopic();
|
entry.mTopic = quest.getTopic();
|
||||||
entryIter->write(entry);
|
questEntry.write(entry);
|
||||||
writer.startRecord(ESM::REC_JOUR);
|
writer.startRecord(ESM::REC_JOUR);
|
||||||
entry.save(writer);
|
entry.save(writer);
|
||||||
writer.endRecord(ESM::REC_JOUR);
|
writer.endRecord(ESM::REC_JOUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TEntryIter iter(mJournal.begin()); iter != mJournal.end(); ++iter)
|
for (const StampedJournalEntry& journalEntry : mJournal)
|
||||||
{
|
{
|
||||||
ESM::JournalEntry entry;
|
ESM::JournalEntry entry;
|
||||||
entry.mType = ESM::JournalEntry::Type_Journal;
|
entry.mType = ESM::JournalEntry::Type_Journal;
|
||||||
iter->write(entry);
|
journalEntry.write(entry);
|
||||||
writer.startRecord(ESM::REC_JOUR);
|
writer.startRecord(ESM::REC_JOUR);
|
||||||
entry.save(writer);
|
entry.save(writer);
|
||||||
writer.endRecord(ESM::REC_JOUR);
|
writer.endRecord(ESM::REC_JOUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TTopicIter iter(mTopics.begin()); iter != mTopics.end(); ++iter)
|
for (const auto& [_, topic] : mTopics)
|
||||||
{
|
{
|
||||||
const Topic& topic = iter->second;
|
for (const Entry& topicEntry : topic)
|
||||||
|
|
||||||
for (Topic::TEntryIter entryIter(topic.begin()); entryIter != topic.end(); ++entryIter)
|
|
||||||
{
|
{
|
||||||
ESM::JournalEntry entry;
|
ESM::JournalEntry entry;
|
||||||
entry.mType = ESM::JournalEntry::Type_Topic;
|
entry.mType = ESM::JournalEntry::Type_Topic;
|
||||||
entry.mTopic = topic.getTopic();
|
entry.mTopic = topic.getTopic();
|
||||||
entryIter->write(entry);
|
topicEntry.write(entry);
|
||||||
writer.startRecord(ESM::REC_JOUR);
|
writer.startRecord(ESM::REC_JOUR);
|
||||||
entry.save(writer);
|
entry.save(writer);
|
||||||
writer.endRecord(ESM::REC_JOUR);
|
writer.endRecord(ESM::REC_JOUR);
|
||||||
|
@ -47,32 +47,12 @@ namespace MWDialogue
|
|||||||
///< Removes the last topic response added for the given topicId and actor name.
|
///< Removes the last topic response added for the given topicId and actor name.
|
||||||
/// \note topicId must be lowercase
|
/// \note topicId must be lowercase
|
||||||
|
|
||||||
TEntryIter begin() const override;
|
|
||||||
///< Iterator pointing to the begin of the main journal.
|
|
||||||
///
|
|
||||||
/// \note Iterators to main journal entries will never become invalid.
|
|
||||||
|
|
||||||
TEntryIter end() const override;
|
|
||||||
///< Iterator pointing past the end of the main journal.
|
|
||||||
|
|
||||||
const TEntryContainer& getEntries() const override { return mJournal; }
|
const TEntryContainer& getEntries() const override { return mJournal; }
|
||||||
|
|
||||||
TQuestIter questBegin() const override;
|
|
||||||
///< Iterator pointing to the first quest (sorted by topic ID)
|
|
||||||
|
|
||||||
TQuestIter questEnd() const override;
|
|
||||||
///< Iterator pointing past the last quest.
|
|
||||||
|
|
||||||
TTopicIter topicBegin() const override;
|
|
||||||
///< Iterator pointing to the first topic (sorted by topic ID)
|
|
||||||
///
|
|
||||||
/// \note The topic ID is identical with the user-visible topic string.
|
|
||||||
|
|
||||||
TTopicIter topicEnd() const override;
|
|
||||||
///< Iterator pointing past the last topic.
|
|
||||||
|
|
||||||
const TTopicContainer& getTopics() const override { return mTopics; }
|
const TTopicContainer& getTopics() const override { return mTopics; }
|
||||||
|
|
||||||
|
const TQuestContainer& getQuests() const override { return mQuests; }
|
||||||
|
|
||||||
int countSavedGameRecords() const override;
|
int countSavedGameRecords() const override;
|
||||||
|
|
||||||
void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override;
|
void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override;
|
||||||
|
@ -29,12 +29,12 @@ namespace MWGui
|
|||||||
|
|
||||||
JournalViewModelImpl() { mKeywordSearchLoaded = false; }
|
JournalViewModelImpl() { mKeywordSearchLoaded = false; }
|
||||||
|
|
||||||
virtual ~JournalViewModelImpl() {}
|
virtual ~JournalViewModelImpl() = default;
|
||||||
|
|
||||||
/// \todo replace this nasty BS
|
/// \todo replace this nasty BS
|
||||||
static Utf8Span toUtf8Span(std::string_view str)
|
static Utf8Span toUtf8Span(std::string_view str)
|
||||||
{
|
{
|
||||||
if (str.size() == 0)
|
if (str.empty())
|
||||||
return Utf8Span(Utf8Point(nullptr), Utf8Point(nullptr));
|
return Utf8Span(Utf8Point(nullptr), Utf8Point(nullptr));
|
||||||
|
|
||||||
Utf8Point point = reinterpret_cast<Utf8Point>(str.data());
|
Utf8Point point = reinterpret_cast<Utf8Point>(str.data());
|
||||||
@ -56,8 +56,8 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
||||||
|
|
||||||
for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i)
|
for (const auto& [_, topic] : journal->getTopics())
|
||||||
mKeywordSearch.seed(i->second.getName(), intptr_t(&i->second));
|
mKeywordSearch.seed(topic.getName(), intptr_t(&topic));
|
||||||
|
|
||||||
mKeywordSearchLoaded = true;
|
mKeywordSearchLoaded = true;
|
||||||
}
|
}
|
||||||
@ -67,25 +67,23 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
||||||
|
|
||||||
return journal->begin() == journal->end();
|
return journal->getEntries().empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename t_iterator, typename Interface>
|
template <typename EntryType, typename Interface>
|
||||||
struct BaseEntry : Interface
|
struct BaseEntry : Interface
|
||||||
{
|
{
|
||||||
typedef t_iterator iterator_t;
|
const EntryType* mEntry;
|
||||||
|
|
||||||
iterator_t mItr;
|
|
||||||
JournalViewModelImpl const* mModel;
|
JournalViewModelImpl const* mModel;
|
||||||
|
|
||||||
BaseEntry(JournalViewModelImpl const* model, iterator_t itr)
|
BaseEntry(JournalViewModelImpl const* model, const EntryType& entry)
|
||||||
: mItr(itr)
|
: mEntry(&entry)
|
||||||
, mModel(model)
|
, mModel(model)
|
||||||
, loaded(false)
|
, loaded(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~BaseEntry() {}
|
virtual ~BaseEntry() = default;
|
||||||
|
|
||||||
mutable bool loaded;
|
mutable bool loaded;
|
||||||
mutable std::string utf8text;
|
mutable std::string utf8text;
|
||||||
@ -193,58 +191,48 @@ namespace MWGui
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void visitQuestNames(bool active_only, std::function<void(std::string_view, bool)> visitor) const override
|
void visitQuestNames(bool activeOnly, std::function<void(std::string_view, bool)> visitor) const override
|
||||||
{
|
{
|
||||||
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
||||||
|
|
||||||
std::set<std::string, std::less<>> visitedQuests;
|
std::set<std::string_view, Misc::StringUtils::CiComp> visitedQuests;
|
||||||
|
|
||||||
// Note that for purposes of the journal GUI, quests are identified by the name, not the ID, so several
|
// Note that for purposes of the journal GUI, quests are identified by the name, not the ID, so several
|
||||||
// different quest IDs can end up in the same quest log. A quest log should be considered finished
|
// different quest IDs can end up in the same quest log. A quest log should be considered finished
|
||||||
// when any quest ID in that log is finished.
|
// when any quest ID in that log is finished.
|
||||||
for (MWBase::Journal::TQuestIter i = journal->questBegin(); i != journal->questEnd(); ++i)
|
for (const auto& [_, quest] : journal->getQuests())
|
||||||
{
|
{
|
||||||
const MWDialogue::Quest& quest = i->second;
|
|
||||||
|
|
||||||
bool isFinished = false;
|
|
||||||
for (MWBase::Journal::TQuestIter j = journal->questBegin(); j != journal->questEnd(); ++j)
|
|
||||||
{
|
|
||||||
if (quest.getName() == j->second.getName() && j->second.isFinished())
|
|
||||||
isFinished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active_only && isFinished)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Unfortunately Morrowind.esm has no quest names, since the quest book was added with tribunal.
|
// Unfortunately Morrowind.esm has no quest names, since the quest book was added with tribunal.
|
||||||
// Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not
|
// Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not
|
||||||
// supposed to appear in the quest book.
|
// supposed to appear in the quest book.
|
||||||
if (!quest.getName().empty())
|
if (quest.getName().empty())
|
||||||
{
|
continue;
|
||||||
// Don't list the same quest name twice
|
// Don't list the same quest name twice
|
||||||
if (visitedQuests.find(quest.getName()) != visitedQuests.end())
|
if (!visitedQuests.insert(quest.getName()).second)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool isFinished = std::ranges::find_if(journal->getQuests(), [&](const auto& pair) {
|
||||||
|
return pair.second.isFinished()
|
||||||
|
&& Misc::StringUtils::ciEqual(quest.getName(), pair.second.getName());
|
||||||
|
}) != journal->getQuests().end();
|
||||||
|
|
||||||
|
if (activeOnly && isFinished)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
visitor(quest.getName(), isFinished);
|
visitor(quest.getName(), isFinished);
|
||||||
|
|
||||||
visitedQuests.emplace(quest.getName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename iterator_t>
|
struct JournalEntryImpl : BaseEntry<MWDialogue::StampedJournalEntry, JournalEntry>
|
||||||
struct JournalEntryImpl : BaseEntry<iterator_t, JournalEntry>
|
|
||||||
{
|
{
|
||||||
using BaseEntry<iterator_t, JournalEntry>::mItr;
|
|
||||||
|
|
||||||
mutable std::string timestamp_buffer;
|
mutable std::string timestamp_buffer;
|
||||||
|
|
||||||
JournalEntryImpl(JournalViewModelImpl const* model, iterator_t itr)
|
JournalEntryImpl(JournalViewModelImpl const* model, const MWDialogue::StampedJournalEntry& entry)
|
||||||
: BaseEntry<iterator_t, JournalEntry>(model, itr)
|
: BaseEntry(model, entry)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getText() const override { return mItr->getText(); }
|
std::string getText() const override { return mEntry->getText(); }
|
||||||
|
|
||||||
Utf8Span timestamp() const override
|
Utf8Span timestamp() const override
|
||||||
{
|
{
|
||||||
@ -254,9 +242,9 @@ namespace MWGui
|
|||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
||||||
os << mItr->mDayOfMonth << ' '
|
os << mEntry->mDayOfMonth << ' '
|
||||||
<< MWBase::Environment::get().getWorld()->getTimeManager()->getMonthName(mItr->mMonth) << " ("
|
<< MWBase::Environment::get().getWorld()->getTimeManager()->getMonthName(mEntry->mMonth) << " ("
|
||||||
<< dayStr << " " << (mItr->mDay) << ')';
|
<< dayStr << " " << (mEntry->mDay) << ')';
|
||||||
|
|
||||||
timestamp_buffer = os.str();
|
timestamp_buffer = os.str();
|
||||||
}
|
}
|
||||||
@ -273,31 +261,33 @@ namespace MWGui
|
|||||||
if (!questName.empty())
|
if (!questName.empty())
|
||||||
{
|
{
|
||||||
std::vector<MWDialogue::Quest const*> quests;
|
std::vector<MWDialogue::Quest const*> quests;
|
||||||
for (MWBase::Journal::TQuestIter questIt = journal->questBegin(); questIt != journal->questEnd();
|
for (const auto& [_, quest] : journal->getQuests())
|
||||||
++questIt)
|
|
||||||
{
|
{
|
||||||
if (Misc::StringUtils::ciEqual(questIt->second.getName(), questName))
|
if (Misc::StringUtils::ciEqual(quest.getName(), questName))
|
||||||
quests.push_back(&questIt->second);
|
quests.push_back(&quest);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end(); ++i)
|
for (const MWDialogue::StampedJournalEntry& journalEntry : journal->getEntries())
|
||||||
{
|
{
|
||||||
for (std::vector<MWDialogue::Quest const*>::iterator questIt = quests.begin();
|
for (const MWDialogue::Quest* quest : quests)
|
||||||
questIt != quests.end(); ++questIt)
|
|
||||||
{
|
{
|
||||||
MWDialogue::Quest const* quest = *questIt;
|
if (quest->getTopic() != journalEntry.mTopic)
|
||||||
for (MWDialogue::Topic::TEntryIter j = quest->begin(); j != quest->end(); ++j)
|
continue;
|
||||||
|
for (const MWDialogue::Entry& questEntry : *quest)
|
||||||
{
|
{
|
||||||
if (i->mInfoId == j->mInfoId)
|
if (journalEntry.mInfoId == questEntry.mInfoId)
|
||||||
visitor(JournalEntryImpl<MWBase::Journal::TEntryIter>(this, i));
|
{
|
||||||
|
visitor(JournalEntryImpl(this, journalEntry));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end(); ++i)
|
for (const MWDialogue::StampedJournalEntry& journalEntry : journal->getEntries())
|
||||||
visitor(JournalEntryImpl<MWBase::Journal::TEntryIter>(this, i));
|
visitor(JournalEntryImpl(this, journalEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,41 +302,40 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
||||||
|
|
||||||
for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i)
|
for (const auto& [_, topic] : journal->getTopics())
|
||||||
{
|
{
|
||||||
Utf8Stream stream(i->second.getName());
|
Utf8Stream stream(topic.getName());
|
||||||
Utf8Stream::UnicodeChar first = Utf8Stream::toLowerUtf8(stream.peek());
|
Utf8Stream::UnicodeChar first = Utf8Stream::toLowerUtf8(stream.peek());
|
||||||
|
|
||||||
if (first != Utf8Stream::toLowerUtf8(character))
|
if (first != Utf8Stream::toLowerUtf8(character))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
visitor(i->second.getName());
|
visitor(topic.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TopicEntryImpl : BaseEntry<MWDialogue::Topic::TEntryIter, TopicEntry>
|
struct TopicEntryImpl : BaseEntry<MWDialogue::Entry, TopicEntry>
|
||||||
{
|
{
|
||||||
MWDialogue::Topic const& mTopic;
|
MWDialogue::Topic const& mTopic;
|
||||||
|
|
||||||
TopicEntryImpl(JournalViewModelImpl const* model, MWDialogue::Topic const& topic, iterator_t itr)
|
TopicEntryImpl(
|
||||||
: BaseEntry(model, itr)
|
JournalViewModelImpl const* model, MWDialogue::Topic const& topic, const MWDialogue::Entry& entry)
|
||||||
|
: BaseEntry(model, entry)
|
||||||
, mTopic(topic)
|
, mTopic(topic)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getText() const override { return mItr->getText(); }
|
std::string getText() const override { return mEntry->getText(); }
|
||||||
|
|
||||||
Utf8Span source() const override { return toUtf8Span(mItr->mActorName); }
|
Utf8Span source() const override { return toUtf8Span(mEntry->mActorName); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void visitTopicEntries(TopicId topicId, std::function<void(TopicEntry const&)> visitor) const override
|
void visitTopicEntries(TopicId topicId, std::function<void(TopicEntry const&)> visitor) const override
|
||||||
{
|
{
|
||||||
typedef MWDialogue::Topic::TEntryIter iterator_t;
|
|
||||||
|
|
||||||
MWDialogue::Topic const& topic = *reinterpret_cast<MWDialogue::Topic const*>(topicId);
|
MWDialogue::Topic const& topic = *reinterpret_cast<MWDialogue::Topic const*>(topicId);
|
||||||
|
|
||||||
for (iterator_t i = topic.begin(); i != topic.end(); ++i)
|
for (const MWDialogue::Entry& entry : topic)
|
||||||
visitor(TopicEntryImpl(this, topic, i));
|
visitor(TopicEntryImpl(this, topic, entry));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ namespace MWGui
|
|||||||
virtual bool isEmpty() const = 0;
|
virtual bool isEmpty() const = 0;
|
||||||
|
|
||||||
/// walks the active and optionally completed, quests providing the name and completed status
|
/// walks the active and optionally completed, quests providing the name and completed status
|
||||||
virtual void visitQuestNames(bool active_only, std::function<void(std::string_view, bool)> visitor) const = 0;
|
virtual void visitQuestNames(bool activeOnly, std::function<void(std::string_view, bool)> visitor) const = 0;
|
||||||
|
|
||||||
/// walks over the journal entries related to all quests with the given name
|
/// walks over the journal entries related to all quests with the given name
|
||||||
/// If \a questName is empty, simply visits all journal entries
|
/// If \a questName is empty, simply visits all journal entries
|
||||||
|
@ -435,11 +435,9 @@ namespace
|
|||||||
ESM::RefId topic = ESM::RefId::stringRefId(topicIdString);
|
ESM::RefId topic = ESM::RefId::stringRefId(topicIdString);
|
||||||
const MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
const MWBase::Journal* journal = MWBase::Environment::get().getJournal();
|
||||||
intptr_t topicId = 0; /// \todo get rid of intptr ids
|
intptr_t topicId = 0; /// \todo get rid of intptr ids
|
||||||
for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i)
|
const auto it = journal->getTopics().find(topic);
|
||||||
{
|
if (it != journal->getTopics().end())
|
||||||
if (i->first == topic)
|
topicId = intptr_t(&it->second);
|
||||||
topicId = intptr_t(&i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyTopicClicked(topicId);
|
notifyTopicClicked(topicId);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ namespace
|
|||||||
const MWDialogue::Topic& getTopicDataOrThrow(const ESM::RefId& topicId, const MWBase::Journal* journal)
|
const MWDialogue::Topic& getTopicDataOrThrow(const ESM::RefId& topicId, const MWBase::Journal* journal)
|
||||||
{
|
{
|
||||||
const auto it = journal->getTopics().find(topicId);
|
const auto it = journal->getTopics().find(topicId);
|
||||||
if (it == journal->topicEnd())
|
if (it == journal->getTopics().end())
|
||||||
throw std::runtime_error("Topic " + topicId.toDebugString() + " could not be found in the journal");
|
throw std::runtime_error("Topic " + topicId.toDebugString() + " could not be found in the journal");
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
@ -151,17 +151,17 @@ namespace MWLua
|
|||||||
= [journal](
|
= [journal](
|
||||||
const MWLua::Topics& topicEntriesStore, std::string_view givenTopicId) -> const MWDialogue::Topic* {
|
const MWLua::Topics& topicEntriesStore, std::string_view givenTopicId) -> const MWDialogue::Topic* {
|
||||||
const auto it = journal->getTopics().find(ESM::RefId::deserializeText(givenTopicId));
|
const auto it = journal->getTopics().find(ESM::RefId::deserializeText(givenTopicId));
|
||||||
if (it == journal->topicEnd())
|
if (it == journal->getTopics().end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &it->second;
|
return &it->second;
|
||||||
};
|
};
|
||||||
topicsBindingsClass[sol::meta_function::length]
|
topicsBindingsClass[sol::meta_function::length]
|
||||||
= [journal](const MWLua::Topics&) -> size_t { return journal->getTopics().size(); };
|
= [journal](const MWLua::Topics&) -> size_t { return journal->getTopics().size(); };
|
||||||
topicsBindingsClass[sol::meta_function::pairs] = [journal](const MWLua::Topics&) {
|
topicsBindingsClass[sol::meta_function::pairs] = [journal](const MWLua::Topics&) {
|
||||||
MWBase::Journal::TTopicIter iterator = journal->topicBegin();
|
auto iterator = journal->getTopics().begin();
|
||||||
return sol::as_function(
|
return sol::as_function(
|
||||||
[iterator, journal]() mutable -> std::pair<sol::optional<std::string>, const MWDialogue::Topic*> {
|
[iterator, journal]() mutable -> std::pair<sol::optional<std::string>, const MWDialogue::Topic*> {
|
||||||
if (iterator != journal->topicEnd())
|
if (iterator != journal->getTopics().end())
|
||||||
{
|
{
|
||||||
return { iterator->first.serializeText(), &((iterator++)->second) };
|
return { iterator->first.serializeText(), &((iterator++)->second) };
|
||||||
}
|
}
|
||||||
@ -306,8 +306,8 @@ namespace MWLua
|
|||||||
};
|
};
|
||||||
quests[sol::meta_function::pairs] = [journal](const Quests& self) {
|
quests[sol::meta_function::pairs] = [journal](const Quests& self) {
|
||||||
std::vector<ESM::RefId> ids;
|
std::vector<ESM::RefId> ids;
|
||||||
for (auto it = journal->questBegin(); it != journal->questEnd(); ++it)
|
for (const auto& [id, _] : journal->getQuests())
|
||||||
ids.push_back(it->first);
|
ids.push_back(id);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
return [ids = std::move(ids), i,
|
return [ids = std::move(ids), i,
|
||||||
allowChanges = self.mMutable]() mutable -> sol::optional<std::tuple<std::string, Quest>> {
|
allowChanges = self.mMutable]() mutable -> sol::optional<std::tuple<std::string, Quest>> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user