Add a mechanism for overriding and resetting variables in a derived blackboard source

This commit is contained in:
Serhii Snitsaruk 2024-01-23 17:54:20 +01:00
parent f84127657b
commit b04f7530e4
5 changed files with 28 additions and 7 deletions

View File

@ -92,9 +92,21 @@ void BlackboardSource::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
bool BlackboardSource::_property_can_revert(const StringName &p_name) const {
return base.is_valid() && base->data.has(p_name);
}
bool BlackboardSource::_property_get_revert(const StringName &p_name, Variant &r_property) const {
if (base->data.has(p_name)) {
r_property = base->data[p_name].get_value();
return true;
}
return false;
}
void BlackboardSource::set_base_source(const Ref<BlackboardSource> &p_base) {
base = p_base;
sync_base();
sync_with_base_source();
emit_changed();
}
@ -133,7 +145,10 @@ PackedStringArray BlackboardSource::list_vars() const {
return ret;
}
void BlackboardSource::sync_base() {
void BlackboardSource::sync_with_base_source() {
if (base.is_null()) {
return;
}
for (const KeyValue<String, BBVariable> &kv : base->data) {
if (!data.has(kv.key)) {
data.insert(kv.key, kv.value.duplicate());

View File

@ -22,13 +22,17 @@ class BlackboardSource : public Resource {
private:
HashMap<String, BBVariable> data;
// When base is not null, the source is considered to be derived from the base source.
// A derived source can only have variables that exist in the base source.
Ref<BlackboardSource> base;
// HashMap<String, BBVariable> overrides;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
bool _property_can_revert(const StringName &p_name) const;
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
public:
void set_base_source(const Ref<BlackboardSource> &p_base);
@ -42,7 +46,9 @@ public:
PackedStringArray list_vars() const;
bool is_empty() const { return data.is_empty(); }
void sync_base();
void sync_with_base_source();
bool is_derived() { return base.is_valid(); }
Ref<Blackboard> create_blackboard();
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite);

View File

@ -69,7 +69,7 @@ void BTPlayer::_update_blackboard_source() {
blackboard_source = Ref<BlackboardSource>(memnew(BlackboardSource));
}
if (blackboard_source == behavior_tree->get_blackboard_source()) {
blackboard_source->sync_base();
blackboard_source->sync_with_base_source();
} else {
blackboard_source->set_base_source(behavior_tree->get_blackboard_source());
}

View File

@ -32,7 +32,7 @@ void BTState::_update_blackboard_source() {
set_blackboard_source(Ref<BlackboardSource>(memnew(BlackboardSource)));
}
if (get_blackboard_source() == behavior_tree->get_blackboard_source()) {
get_blackboard_source()->sync_base();
get_blackboard_source()->sync_with_base_source();
} else {
get_blackboard_source()->set_base_source(behavior_tree->get_blackboard_source());
}

View File

@ -36,5 +36,5 @@ void BTNewScope::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blackboard_source", "p_source"), &BTNewScope::set_blackboard_source);
ClassDB::bind_method(D_METHOD("get_blackboard_source"), &BTNewScope::get_blackboard_source);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_source", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardSource", PROPERTY_USAGE_DEFAULT), "set_blackboard_source", "get_blackboard_source");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_source", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardSource", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_blackboard_source", "get_blackboard_source");
}