mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Add Database::user_general_messages()
This commit is contained in:
@@ -178,6 +178,19 @@ public:
|
||||
virtual std::vector<Message> GetGeneralMessages(
|
||||
bool evaluateConditions = false) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Get all general messages listed in the loaded userlist.
|
||||
* @param evaluateConditions
|
||||
* If true, any metadata conditions are evaluated before the metadata
|
||||
* is returned, otherwise unevaluated metadata is returned. Evaluating
|
||||
* general message conditions also clears the condition cache before
|
||||
* evaluating conditions.
|
||||
* @returns A vector of messages supplied in the userlist but not attached to
|
||||
* any particular plugin.
|
||||
*/
|
||||
virtual std::vector<Message> GetUserGeneralMessages(
|
||||
bool evaluateConditions = false) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Gets the groups that are defined in the loaded metadata lists.
|
||||
* @param includeUserMetadata
|
||||
|
||||
@@ -95,6 +95,16 @@ std::vector<Message> Database::GetGeneralMessages(
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Message> Database::GetUserGeneralMessages(
|
||||
bool evaluateConditions) const {
|
||||
try {
|
||||
return convert<Message>(
|
||||
database_->user_general_messages(evaluateConditions));
|
||||
} catch (const ::rust::Error& e) {
|
||||
std::rethrow_exception(mapError(e));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Group> Database::GetGroups(bool includeUserMetadata) const {
|
||||
try {
|
||||
return convert<Group>(database_->groups(includeUserMetadata));
|
||||
|
||||
@@ -38,6 +38,9 @@ public:
|
||||
std::vector<Message> GetGeneralMessages(
|
||||
bool evaluateConditions = false) const override;
|
||||
|
||||
std::vector<Message> GetUserGeneralMessages(
|
||||
bool evaluateConditions = false) const override;
|
||||
|
||||
std::vector<Group> GetGroups(bool includeUserMetadata = true) const override;
|
||||
std::vector<Group> GetUserGroups() const override;
|
||||
void SetUserGroups(const std::vector<Group>& groups) override;
|
||||
|
||||
@@ -144,6 +144,20 @@ impl Database {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn user_general_messages(
|
||||
&self,
|
||||
evaluate_conditions: bool,
|
||||
) -> Result<Vec<Message>, VerboseError> {
|
||||
Ok(self
|
||||
.0
|
||||
.read()
|
||||
.map_err(DatabaseLockPoisonError::from)?
|
||||
.user_general_messages(to_eval_mode(evaluate_conditions))?
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub fn groups(&self, include_user_metadata: bool) -> Result<Vec<Group>, VerboseError> {
|
||||
Ok(self
|
||||
.0
|
||||
|
||||
@@ -276,6 +276,8 @@ mod ffi {
|
||||
|
||||
pub fn general_messages(&self, evaluate_conditions: bool) -> Result<Vec<Message>>;
|
||||
|
||||
pub fn user_general_messages(&self, evaluate_conditions: bool) -> Result<Vec<Message>>;
|
||||
|
||||
pub fn groups(&self, include_user_metadata: bool) -> Result<Vec<Group>>;
|
||||
|
||||
pub fn user_groups(&self) -> Result<Vec<Group>>;
|
||||
|
||||
@@ -566,6 +566,21 @@ TEST_P(
|
||||
EXPECT_TRUE(messages.empty());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getUserGeneralMessagesShouldGetGeneralMessagesFromTheUserlistOnly) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(GenerateUserlist());
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().LoadUserlist(userlistPath_));
|
||||
|
||||
auto messages = handle_->GetDatabase().GetUserGeneralMessages();
|
||||
|
||||
std::vector<Message> expectedMessages({
|
||||
Message(MessageType::say, generalUserlistMessage),
|
||||
});
|
||||
EXPECT_EQ(expectedMessages, messages);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getPluginMetadataShouldReturnAnEmptyOptionalIfThePluginHasNoMetadata) {
|
||||
EXPECT_FALSE(handle_->GetDatabase().GetPluginMetadata(blankEsm));
|
||||
|
||||
@@ -183,6 +183,19 @@ impl Database {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn user_general_messages(
|
||||
&self,
|
||||
evaluate_conditions: EvalMode,
|
||||
) -> Result<Vec<Message>, VerboseError> {
|
||||
self.0
|
||||
.read()
|
||||
.map_err(DatabaseLockPoisonError::from)?
|
||||
.user_general_messages(evaluate_conditions.into())
|
||||
.map(|v| v.into_iter().map(Into::into).collect())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn groups(&self, include_user_metadata: MergeMode) -> Result<Vec<Group>, VerboseError> {
|
||||
Ok(self
|
||||
|
||||
@@ -148,6 +148,18 @@ impl Database {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn user_general_messages(
|
||||
&self,
|
||||
evaluate_conditions: bool,
|
||||
) -> Result<Vec<Message>, VerboseError> {
|
||||
self.0
|
||||
.read()
|
||||
.map_err(DatabaseLockPoisonError::from)?
|
||||
.user_general_messages(to_eval_mode(evaluate_conditions))
|
||||
.map(|v| v.into_iter().map(Into::into).collect())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn groups(&self, include_user_metadata: bool) -> Result<Vec<Group>, VerboseError> {
|
||||
Ok(self
|
||||
.0
|
||||
|
||||
+88
-17
@@ -194,23 +194,26 @@ impl Database {
|
||||
&self,
|
||||
evaluate_conditions: EvalMode,
|
||||
) -> Result<Vec<Message>, ConditionEvaluationError> {
|
||||
let messages_iter = self
|
||||
.masterlist
|
||||
.messages()
|
||||
.iter()
|
||||
.chain(self.userlist.messages());
|
||||
process_messages(
|
||||
self.masterlist
|
||||
.messages()
|
||||
.iter()
|
||||
.chain(self.userlist.messages()),
|
||||
&self.condition_evaluator_state,
|
||||
evaluate_conditions,
|
||||
)
|
||||
}
|
||||
|
||||
if evaluate_conditions == EvalMode::Evaluate {
|
||||
let messages = messages_iter
|
||||
.filter_map(|m| {
|
||||
filter_map_on_condition(m, m.condition(), &self.condition_evaluator_state)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(messages)
|
||||
} else {
|
||||
Ok(messages_iter.cloned().collect())
|
||||
}
|
||||
/// Get all general messages listed in the loaded userlist.
|
||||
pub fn user_general_messages(
|
||||
&self,
|
||||
evaluate_conditions: EvalMode,
|
||||
) -> Result<Vec<Message>, ConditionEvaluationError> {
|
||||
process_messages(
|
||||
self.userlist.messages().iter(),
|
||||
&self.condition_evaluator_state,
|
||||
evaluate_conditions,
|
||||
)
|
||||
}
|
||||
|
||||
/// Gets the groups that are defined in the loaded metadata lists.
|
||||
@@ -281,7 +284,7 @@ impl Database {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a plugin's metadata loaded from the given userlist.
|
||||
/// Get a plugin's metadata loaded from the loaded userlist.
|
||||
pub fn plugin_user_metadata(
|
||||
&self,
|
||||
plugin_name: &str,
|
||||
@@ -379,6 +382,22 @@ fn merge_groups(lhs: &[Group], rhs: &[Group]) -> Vec<Group> {
|
||||
groups
|
||||
}
|
||||
|
||||
fn process_messages<'a, I: Iterator<Item = &'a Message>>(
|
||||
messages_iter: I,
|
||||
condition_evaluator_state: &loot_condition_interpreter::State,
|
||||
evaluate_conditions: EvalMode,
|
||||
) -> Result<Vec<Message>, ConditionEvaluationError> {
|
||||
if evaluate_conditions == EvalMode::Evaluate {
|
||||
let messages = messages_iter
|
||||
.filter_map(|m| filter_map_on_condition(m, m.condition(), condition_evaluator_state))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(messages)
|
||||
} else {
|
||||
Ok(messages_iter.cloned().collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
@@ -1039,6 +1058,58 @@ plugins:
|
||||
}
|
||||
}
|
||||
|
||||
mod user_general_messages {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn user_general_messages_should_return_only_general_messages_in_the_userlist() {
|
||||
let fixture = Fixture::new(GameType::Oblivion);
|
||||
let mut database = fixture.database();
|
||||
|
||||
database.load_masterlist(&fixture.metadata_path).unwrap();
|
||||
|
||||
let userlist_path = fixture.inner.local_path.join("userlist.yaml");
|
||||
std::fs::write(
|
||||
&userlist_path,
|
||||
"globals: [{type: say, content: 'A user message', condition: 'file(\"missing.esp\")'}]",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
database.load_userlist(&userlist_path).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
&[Message::new(MessageType::Say, "A user message".into())
|
||||
.with_condition("file(\"missing.esp\")".into())],
|
||||
database
|
||||
.user_general_messages(EvalMode::DoNotEvaluate)
|
||||
.unwrap()
|
||||
.as_slice()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_filter_out_messages_with_false_conditions_when_evaluating_conditions() {
|
||||
let fixture = Fixture::new(GameType::Oblivion);
|
||||
let mut database = fixture.database();
|
||||
|
||||
let userlist_path = fixture.inner.local_path.join("userlist.yaml");
|
||||
std::fs::write(
|
||||
&userlist_path,
|
||||
"globals: [{type: say, content: 'A user message', condition: 'file(\"missing.esp\")'}]",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
database.load_userlist(&userlist_path).unwrap();
|
||||
|
||||
assert!(
|
||||
database
|
||||
.user_general_messages(EvalMode::Evaluate)
|
||||
.unwrap()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mod groups {
|
||||
use super::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user