1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-20 10:11:33 +00:00

Merge branch 'journalcase' into 'master'

Remove dialogue related instances of getRefIdString

See merge request OpenMW/openmw!2999
This commit is contained in:
elsid 2023-05-07 14:49:49 +00:00
commit 188de0d8d4
10 changed files with 50 additions and 56 deletions

View file

@ -408,12 +408,12 @@ namespace MWDialogue
updateActorKnownTopics(); updateActorKnownTopics();
std::list<std::string> keywordList; std::list<std::string> keywordList;
const auto& store = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>();
for (const auto& [topic, topicInfo] : mActorKnownTopics) for (const auto& [topic, topicInfo] : mActorKnownTopics)
{ {
// does the player know the topic? // does the player know the topic?
if (mKnownTopics.count(topic)) if (mKnownTopics.contains(topic))
keywordList.push_back(topic.getRefIdString()); keywordList.push_back(store.find(topic)->mStringId);
} }
// sort again, because the previous sort was case-sensitive // sort again, because the previous sort was case-sensitive

View file

@ -50,13 +50,12 @@ namespace MWDialogue
const auto& keywordSearch const auto& keywordSearch
= MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().getDialogIdKeywordSearch(); = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().getDialogIdKeywordSearch();
std::vector<KeywordSearch<std::string, int /*unused*/>::Match> matches; std::vector<KeywordSearch<int /*unused*/>::Match> matches;
keywordSearch.highlightKeywords(text.begin(), text.end(), matches); keywordSearch.highlightKeywords(text.begin(), text.end(), matches);
for (std::vector<KeywordSearch<std::string, int /*unused*/>::Match>::const_iterator it = matches.begin(); for (const auto& match : matches)
it != matches.end(); ++it)
{ {
tokens.emplace_back(std::string(it->mBeg, it->mEnd), Token::ImplicitKeyword); tokens.emplace_back(std::string(match.mBeg, match.mEnd), Token::ImplicitKeyword);
} }
} }

View file

@ -13,11 +13,11 @@
namespace MWDialogue namespace MWDialogue
{ {
template <typename string_t, typename value_t> template <typename value_t>
class KeywordSearch class KeywordSearch
{ {
public: public:
typedef typename string_t::const_iterator Point; using Point = std::string::const_iterator;
struct Match struct Match
{ {
@ -26,11 +26,11 @@ namespace MWDialogue
value_t mValue; value_t mValue;
}; };
void seed(string_t keyword, value_t value) void seed(std::string_view keyword, value_t value)
{ {
if (keyword.empty()) if (keyword.empty())
return; return;
seed_impl(std::move(keyword), std::move(value), 0, mRoot); seed_impl(keyword, std::move(value), 0, mRoot);
} }
void clear() void clear()
@ -39,23 +39,21 @@ namespace MWDialogue
mRoot.mKeyword.clear(); mRoot.mKeyword.clear();
} }
bool containsKeyword(const string_t& keyword, value_t& value) bool containsKeyword(std::string_view keyword, value_t& value)
{ {
typename Entry::childen_t::iterator current; auto it = keyword.begin();
typename Entry::childen_t::iterator next; auto current = mRoot.mChildren.find(Misc::StringUtils::toLower(*it));
current = mRoot.mChildren.find(Misc::StringUtils::toLower(*keyword.begin()));
if (current == mRoot.mChildren.end()) if (current == mRoot.mChildren.end())
return false; return false;
else if (current->second.mKeyword.size() && Misc::StringUtils::ciEqual(current->second.mKeyword, keyword)) else if (Misc::StringUtils::ciEqual(current->second.mKeyword, keyword))
{ {
value = current->second.mValue; value = current->second.mValue;
return true; return true;
} }
for (Point i = ++keyword.begin(); i != keyword.end(); ++i) for (++it; it != keyword.end(); ++it)
{ {
next = current->second.mChildren.find(Misc::StringUtils::toLower(*i)); auto next = current->second.mChildren.find(Misc::StringUtils::toLower(*it));
if (next == current->second.mChildren.end()) if (next == current->second.mChildren.end())
return false; return false;
if (Misc::StringUtils::ciEqual(next->second.mKeyword, keyword)) if (Misc::StringUtils::ciEqual(next->second.mKeyword, keyword))
@ -116,14 +114,12 @@ namespace MWDialogue
// candidates first // candidates first
std::reverse(candidates.begin(), candidates.end()); std::reverse(candidates.begin(), candidates.end());
for (typename std::vector<std::pair<int, typename Entry::childen_t::const_iterator>>::iterator it for (const auto& [pos, c] : candidates)
= candidates.begin();
it != candidates.end(); ++it)
{ {
candidate = it->second; candidate = c;
// try to match the rest of the keyword // try to match the rest of the keyword
Point k = i + it->first; Point k = i + pos;
typename string_t::const_iterator t = candidate->second.mKeyword.begin() + (k - i); Point t = candidate->second.mKeyword.begin() + (k - i);
while (k != end && t != candidate->second.mKeyword.end()) while (k != end && t != candidate->second.mKeyword.end())
{ {
@ -196,12 +192,12 @@ namespace MWDialogue
{ {
typedef std::map<wchar_t, Entry> childen_t; typedef std::map<wchar_t, Entry> childen_t;
string_t mKeyword; std::string mKeyword;
value_t mValue; value_t mValue;
childen_t mChildren; childen_t mChildren;
}; };
void seed_impl(string_t keyword, value_t value, size_t depth, Entry& entry) void seed_impl(std::string_view keyword, value_t value, size_t depth, Entry& entry)
{ {
int ch = Misc::StringUtils::toLower(keyword.at(depth)); int ch = Misc::StringUtils::toLower(keyword.at(depth));
@ -210,7 +206,7 @@ namespace MWDialogue
if (j == entry.mChildren.end()) if (j == entry.mChildren.end())
{ {
entry.mChildren[ch].mValue = std::move(value); entry.mChildren[ch].mValue = std::move(value);
entry.mChildren[ch].mKeyword = std::move(keyword); entry.mChildren[ch].mKeyword = keyword;
} }
else else
{ {
@ -219,22 +215,21 @@ namespace MWDialogue
if (keyword == j->second.mKeyword) if (keyword == j->second.mKeyword)
throw std::runtime_error("duplicate keyword inserted"); throw std::runtime_error("duplicate keyword inserted");
value_t pushValue = j->second.mValue; const auto& pushKeyword = j->second.mKeyword;
string_t pushKeyword = j->second.mKeyword;
if (depth >= pushKeyword.size()) if (depth >= pushKeyword.size())
throw std::runtime_error("unexpected"); throw std::runtime_error("unexpected");
if (depth + 1 < pushKeyword.size()) if (depth + 1 < pushKeyword.size())
{ {
seed_impl(std::move(pushKeyword), std::move(pushValue), depth + 1, j->second); seed_impl(pushKeyword, j->second.mValue, depth + 1, j->second);
j->second.mKeyword.clear(); j->second.mKeyword.clear();
} }
} }
if (depth + 1 == keyword.size()) if (depth + 1 == keyword.size())
j->second.mKeyword = value; j->second.mKeyword = value;
else // depth+1 < keyword.size() else // depth+1 < keyword.size()
seed_impl(std::move(keyword), std::move(value), depth + 1, j->second); seed_impl(keyword, std::move(value), depth + 1, j->second);
} }
} }

View file

@ -156,7 +156,7 @@ namespace MWDialogue
else else
{ {
errorHandler.reset(); errorHandler.reset();
errorHandler.setContext(info.mId.getRefIdString() + " in " + topic.mId.getRefIdString()); errorHandler.setContext(info.mId.getRefIdString() + " in " + topic.mStringId);
if (!test(ptr, info, compiled, total, extensions, compilerContext, errorHandler)) if (!test(ptr, info, compiled, total, extensions, compilerContext, errorHandler))
Log(Debug::Error) << "Test failed for " << info.mId << " in " << topic.mId << '\n' Log(Debug::Error) << "Test failed for " << info.mId << " in " << topic.mId << '\n'
<< info.mResultScript; << info.mResultScript;

View file

@ -11,7 +11,7 @@ namespace MWDialogue
Topic::Topic(const ESM::RefId& topic) Topic::Topic(const ESM::RefId& topic)
: mTopic(topic) : mTopic(topic)
, mName(MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().find(topic)->mId.getRefIdString()) , mName(MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().find(topic)->mStringId)
{ {
} }

View file

@ -108,7 +108,7 @@ namespace MWGui
void activated() override; void activated() override;
}; };
typedef MWDialogue::KeywordSearch<std::string, intptr_t> KeywordSearchT; typedef MWDialogue::KeywordSearch<intptr_t> KeywordSearchT;
struct DialogueText struct DialogueText
{ {

View file

@ -21,7 +21,7 @@ namespace MWGui
struct JournalViewModelImpl : JournalViewModel struct JournalViewModelImpl : JournalViewModel
{ {
typedef MWDialogue::KeywordSearch<std::string, intptr_t> KeywordSearchT; typedef MWDialogue::KeywordSearch<intptr_t> KeywordSearchT;
mutable bool mKeywordSearchLoaded; mutable bool mKeywordSearchLoaded;
mutable KeywordSearchT mKeywordSearch; mutable KeywordSearchT mKeywordSearch;
@ -56,7 +56,7 @@ 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 (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i)
mKeywordSearch.seed(i->first.getRefIdString(), intptr_t(&i->second)); mKeywordSearch.seed(i->second.getName(), intptr_t(&i->second));
mKeywordSearchLoaded = true; mKeywordSearchLoaded = true;
} }
@ -312,7 +312,7 @@ namespace MWGui
for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i) for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i)
{ {
Utf8Stream stream(i->first.getRefIdString().c_str()); Utf8Stream stream(i->second.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))

View file

@ -1142,7 +1142,7 @@ namespace MWWorld
list.push_back(dialogue->mId); list.push_back(dialogue->mId);
} }
const MWDialogue::KeywordSearch<std::string, int>& Store<ESM::Dialogue>::getDialogIdKeywordSearch() const const MWDialogue::KeywordSearch<int>& Store<ESM::Dialogue>::getDialogIdKeywordSearch() const
{ {
if (mKeywordSearchModFlag) if (mKeywordSearchModFlag)
{ {
@ -1151,7 +1151,7 @@ namespace MWWorld
std::vector<std::string> keywordList; std::vector<std::string> keywordList;
keywordList.reserve(getSize()); keywordList.reserve(getSize());
for (const auto& it : *this) for (const auto& it : *this)
keywordList.push_back(Misc::StringUtils::lowerCase(it.mId.getRefIdString())); keywordList.push_back(Misc::StringUtils::lowerCase(it.mStringId));
sort(keywordList.begin(), keywordList.end()); sort(keywordList.begin(), keywordList.end());
for (const auto& it : keywordList) for (const auto& it : keywordList)

View file

@ -512,7 +512,7 @@ namespace MWWorld
std::vector<ESM::Dialogue*> mShared; std::vector<ESM::Dialogue*> mShared;
mutable bool mKeywordSearchModFlag; mutable bool mKeywordSearchModFlag;
mutable MWDialogue::KeywordSearch<std::string, int /*unused*/> mKeywordSearch; mutable MWDialogue::KeywordSearch<int /*unused*/> mKeywordSearch;
public: public:
Store(); Store();
@ -535,7 +535,7 @@ namespace MWWorld
void listIdentifier(std::vector<ESM::RefId>& list) const override; void listIdentifier(std::vector<ESM::RefId>& list) const override;
const MWDialogue::KeywordSearch<std::string, int>& getDialogIdKeywordSearch() const; const MWDialogue::KeywordSearch<int>& getDialogIdKeywordSearch() const;
}; };
template <> template <>

View file

@ -12,14 +12,14 @@ protected:
TEST_F(KeywordSearchTest, keyword_test_conflict_resolution) TEST_F(KeywordSearchTest, keyword_test_conflict_resolution)
{ {
// test to make sure the longest keyword in a chain of conflicting keywords gets chosen // test to make sure the longest keyword in a chain of conflicting keywords gets chosen
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("foo bar", 0); search.seed("foo bar", 0);
search.seed("bar lock", 0); search.seed("bar lock", 0);
search.seed("lock switch", 0); search.seed("lock switch", 0);
std::string text = "foo bar lock switch"; std::string text = "foo bar lock switch";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
// Should contain: "foo bar", "lock switch" // Should contain: "foo bar", "lock switch"
@ -30,13 +30,13 @@ TEST_F(KeywordSearchTest, keyword_test_conflict_resolution)
TEST_F(KeywordSearchTest, keyword_test_conflict_resolution2) TEST_F(KeywordSearchTest, keyword_test_conflict_resolution2)
{ {
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("the dwemer", 0); search.seed("the dwemer", 0);
search.seed("dwemer language", 0); search.seed("dwemer language", 0);
std::string text = "the dwemer language"; std::string text = "the dwemer language";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
EXPECT_EQ(matches.size(), 1); EXPECT_EQ(matches.size(), 1);
@ -47,14 +47,14 @@ TEST_F(KeywordSearchTest, keyword_test_conflict_resolution3)
{ {
// testing that the longest keyword is chosen, rather than maximizing the // testing that the longest keyword is chosen, rather than maximizing the
// amount of highlighted characters by highlighting the first and last keyword // amount of highlighted characters by highlighting the first and last keyword
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("foo bar", 0); search.seed("foo bar", 0);
search.seed("bar lock", 0); search.seed("bar lock", 0);
search.seed("lock so", 0); search.seed("lock so", 0);
std::string text = "foo bar lock so"; std::string text = "foo bar lock so";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
EXPECT_EQ(matches.size(), 1); EXPECT_EQ(matches.size(), 1);
@ -64,7 +64,7 @@ TEST_F(KeywordSearchTest, keyword_test_conflict_resolution3)
TEST_F(KeywordSearchTest, keyword_test_utf8_word_begin) TEST_F(KeywordSearchTest, keyword_test_utf8_word_begin)
{ {
// We make sure that the search works well even if the character is not ASCII // We make sure that the search works well even if the character is not ASCII
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("états", 0); search.seed("états", 0);
search.seed("ïrradiés", 0); search.seed("ïrradiés", 0);
search.seed("ça nous déçois", 0); search.seed("ça nous déçois", 0);
@ -74,7 +74,7 @@ TEST_F(KeywordSearchTest, keyword_test_utf8_word_begin)
= "les nations unis ont réunis le monde entier, états units inclus pour parler du problème des gens ïrradiés " = "les nations unis ont réunis le monde entier, états units inclus pour parler du problème des gens ïrradiés "
"et ça nous déçois"; "et ça nous déçois";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
EXPECT_EQ(matches.size(), 3); EXPECT_EQ(matches.size(), 3);
@ -86,12 +86,12 @@ TEST_F(KeywordSearchTest, keyword_test_utf8_word_begin)
TEST_F(KeywordSearchTest, keyword_test_non_alpha_non_whitespace_word_begin) TEST_F(KeywordSearchTest, keyword_test_non_alpha_non_whitespace_word_begin)
{ {
// We make sure that the search works well even if the separator is not a whitespace // We make sure that the search works well even if the separator is not a whitespace
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("Report to caius cosades", 0); search.seed("Report to caius cosades", 0);
std::string text = "I was told to \"Report to caius cosades\""; std::string text = "I was told to \"Report to caius cosades\"";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
EXPECT_EQ(matches.size(), 1); EXPECT_EQ(matches.size(), 1);
@ -101,13 +101,13 @@ TEST_F(KeywordSearchTest, keyword_test_non_alpha_non_whitespace_word_begin)
TEST_F(KeywordSearchTest, keyword_test_russian_non_ascii_before) TEST_F(KeywordSearchTest, keyword_test_russian_non_ascii_before)
{ {
// We make sure that the search works well even if the separator is not a whitespace with russian chars // We make sure that the search works well even if the separator is not a whitespace with russian chars
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("Доложить Каю Косадесу", 0); search.seed("Доложить Каю Косадесу", 0);
std::string text std::string text
= "Что? Да. Я Кай Косадес. То есть как это, вам велели «Доложить Каю Косадесу»? О чем вы говорите?"; = "Что? Да. Я Кай Косадес. То есть как это, вам велели «Доложить Каю Косадесу»? О чем вы говорите?";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
EXPECT_EQ(matches.size(), 1); EXPECT_EQ(matches.size(), 1);
@ -117,13 +117,13 @@ TEST_F(KeywordSearchTest, keyword_test_russian_non_ascii_before)
TEST_F(KeywordSearchTest, keyword_test_russian_ascii_before) TEST_F(KeywordSearchTest, keyword_test_russian_ascii_before)
{ {
// We make sure that the search works well even if the separator is not a whitespace with russian chars // We make sure that the search works well even if the separator is not a whitespace with russian chars
MWDialogue::KeywordSearch<std::string, int> search; MWDialogue::KeywordSearch<int> search;
search.seed("Доложить Каю Косадесу", 0); search.seed("Доложить Каю Косадесу", 0);
std::string text std::string text
= "Что? Да. Я Кай Косадес. То есть как это, вам велели 'Доложить Каю Косадесу'? О чем вы говорите?"; = "Что? Да. Я Кай Косадес. То есть как это, вам велели 'Доложить Каю Косадесу'? О чем вы говорите?";
std::vector<MWDialogue::KeywordSearch<std::string, int>::Match> matches; std::vector<MWDialogue::KeywordSearch<int>::Match> matches;
search.highlightKeywords(text.begin(), text.end(), matches); search.highlightKeywords(text.begin(), text.end(), matches);
EXPECT_EQ(matches.size(), 1); EXPECT_EQ(matches.size(), 1);