mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-19 17:11:33 +00:00
Dialogue: improve conflict resolution for chains of overlapping keywords (unit test for such a case will follow)
This commit is contained in:
parent
65ab31eae6
commit
ce2cbab402
1 changed files with 38 additions and 23 deletions
|
@ -66,8 +66,14 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sortMatches(const Match& left, const Match& right)
|
||||||
|
{
|
||||||
|
return left.mBeg < right.mBeg;
|
||||||
|
}
|
||||||
|
|
||||||
void highlightKeywords (Point beg, Point end, std::vector<Match>& out)
|
void highlightKeywords (Point beg, Point end, std::vector<Match>& out)
|
||||||
{
|
{
|
||||||
|
std::vector<Match> matches;
|
||||||
for (Point i = beg; i != end; ++i)
|
for (Point i = beg; i != end; ++i)
|
||||||
{
|
{
|
||||||
// check if previous character marked start of new word
|
// check if previous character marked start of new word
|
||||||
|
@ -144,42 +150,51 @@ public:
|
||||||
match.mValue = candidate->second.mValue;
|
match.mValue = candidate->second.mValue;
|
||||||
match.mBeg = i;
|
match.mBeg = i;
|
||||||
match.mEnd = k;
|
match.mEnd = k;
|
||||||
out.push_back(match);
|
matches.push_back(match);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve overlapping keywords
|
// resolve overlapping keywords
|
||||||
for (typename std::vector<Match>::iterator it = out.begin(); it != out.end();)
|
while (matches.size())
|
||||||
{
|
{
|
||||||
|
int longestKeywordSize = 0;
|
||||||
|
typename std::vector<Match>::iterator longestKeyword;
|
||||||
|
for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end(); ++it)
|
||||||
|
{
|
||||||
|
int size = it->mEnd - it->mBeg;
|
||||||
|
if (size > longestKeywordSize)
|
||||||
|
{
|
||||||
|
longestKeywordSize = size;
|
||||||
|
longestKeyword = it;
|
||||||
|
}
|
||||||
|
|
||||||
typename std::vector<Match>::iterator next = it;
|
typename std::vector<Match>::iterator next = it;
|
||||||
++next;
|
++next;
|
||||||
|
|
||||||
if (next == out.end())
|
if (next == matches.end())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (it->mEnd <= next->mBeg)
|
if (it->mEnd <= next->mBeg)
|
||||||
{
|
{
|
||||||
|
break; // no overlap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Match keyword = *longestKeyword;
|
||||||
|
matches.erase(longestKeyword);
|
||||||
|
out.push_back(keyword);
|
||||||
|
// erase anything that overlaps with the keyword we just added to the output
|
||||||
|
for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end();)
|
||||||
|
{
|
||||||
|
if (it->mBeg < keyword.mEnd && it->mEnd > keyword.mBeg)
|
||||||
|
it = matches.erase(it);
|
||||||
|
else
|
||||||
++it;
|
++it;
|
||||||
continue; // no overlap
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// prefer the longer keyword
|
|
||||||
int size = it->mEnd - it->mBeg;
|
|
||||||
int nextSize = next->mEnd - next->mBeg;
|
|
||||||
if (size >= nextSize) // if both are the same length, then prefer the first keyword
|
|
||||||
{
|
|
||||||
out.erase(next);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
it = out.erase(it);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(out.begin(), out.end(), sortMatches);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue