Skip to content

Commit

Permalink
Merge pull request #71 from limbonaut/blackboard-fixes
Browse files Browse the repository at this point in the history
Blackboard-related improvements and fixes
  • Loading branch information
limbonaut authored Mar 12, 2024
2 parents 92010f1 + 06ebff7 commit 088ef00
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 104 deletions.
13 changes: 10 additions & 3 deletions blackboard/blackboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Variant Blackboard::get_var(const StringName &p_name, const Variant &p_default,
if (data.has(p_name)) {
return data.get(p_name).get_value();
} else if (parent.is_valid()) {
return parent->get_var(p_name, p_default);
return parent->get_var(p_name, p_default, p_complain);
} else {
if (p_complain) {
ERR_PRINT(vformat("Blackboard: Variable \"%s\" not found.", p_name));
Expand Down Expand Up @@ -74,11 +74,17 @@ void Blackboard::unbind_var(const StringName &p_name) {
data[p_name].unbind();
}

void Blackboard::add_var(const StringName &p_name, const BBVariable &p_var) {
ERR_FAIL_COND(data.has(p_name));
void Blackboard::assign_var(const StringName &p_name, const BBVariable &p_var) {
data.insert(p_name, p_var);
}

void Blackboard::link_var(const StringName &p_name, const Ref<Blackboard> &p_target_blackboard, const StringName &p_target_var) {
ERR_FAIL_COND_MSG(!data.has(p_name), "Blackboard: Can't link variable that doesn't exist (var: " + p_name + ").");
ERR_FAIL_COND_MSG(p_target_blackboard.is_null(), "Blackboard: Can't link variable to target blackboard that is null (var: " + p_name + ").");
ERR_FAIL_COND_MSG(!p_target_blackboard->data.has(p_target_var), "Blackboard: Can't link variable to non-existent target (var: " + p_name + ", target: " + p_target_var + ").");
data[p_name] = p_target_blackboard->data[p_target_var];
}

void Blackboard::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_var", "var_name", "default", "complain"), &Blackboard::get_var, Variant(), true);
ClassDB::bind_method(D_METHOD("set_var", "var_name", "value"), &Blackboard::set_var);
Expand All @@ -89,4 +95,5 @@ void Blackboard::_bind_methods() {
ClassDB::bind_method(D_METHOD("top"), &Blackboard::top);
ClassDB::bind_method(D_METHOD("bind_var_to_property", "var_name", "object", "property"), &Blackboard::bind_var_to_property);
ClassDB::bind_method(D_METHOD("unbind_var", "var_name"), &Blackboard::unbind_var);
ClassDB::bind_method(D_METHOD("link_var", "var_name", "target_blackboard", "target_var"), &Blackboard::link_var);
}
4 changes: 3 additions & 1 deletion blackboard/blackboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ class Blackboard : public RefCounted {
void bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property);
void unbind_var(const StringName &p_name);

void add_var(const StringName &p_name, const BBVariable &p_var);
void assign_var(const StringName &p_name, const BBVariable &p_var);

void link_var(const StringName &p_name, const Ref<Blackboard> &p_target_blackboard, const StringName &p_target_var);

// TODO: Add serialization API.
};
Expand Down
30 changes: 27 additions & 3 deletions blackboard/blackboard_plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
BBVariable var = p.second;

// * Editor
if (!is_derived() || !var_name.begins_with("_")) {
if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) {
p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR));
}

Expand Down Expand Up @@ -270,6 +270,25 @@ void BlackboardPlan::sync_with_base_plan() {
}
}

// Sync order of variables.
// Glossary: E - element of current plan, B - element of base plan, F - element of current plan (used for forward search).
ERR_FAIL_COND(base->var_list.size() != var_list.size());
List<Pair<StringName, BBVariable>>::Element *B = base->var_list.front();
for (List<Pair<StringName, BBVariable>>::Element *E = var_list.front(); E; E = E->next()) {
if (E->get().first != B->get().first) {
List<Pair<StringName, BBVariable>>::Element *F = E->next();
while (F) {
if (F->get().first == B->get().first) {
var_list.move_before(F, E);
E = F;
break;
}
F = F->next();
}
}
B = B->next();
}

if (changed) {
notify_property_list_changed();
emit_changed();
Expand All @@ -284,11 +303,16 @@ inline void bb_add_var_dup_with_prefetch(const Ref<Blackboard> &p_blackboard, co
if (n != nullptr) {
var.set_value(n);
} else {
if (p_blackboard->has_var(p_name)) {
// Not adding: Assuming variable was initialized by the user or in the parent scope.
return;
}
ERR_PRINT(vformat("BlackboardPlan: Prefetch failed for variable $%s with value: %s", p_name, p_var.get_value()));
var.set_value(Variant());
}
p_blackboard->add_var(p_name, var);
p_blackboard->assign_var(p_name, var);
} else {
p_blackboard->add_var(p_name, p_var.duplicate());
p_blackboard->assign_var(p_name, p_var.duplicate());
}
}

Expand Down
2 changes: 2 additions & 0 deletions bt/bt_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ void BTPlayer::_notification(int p_notification) {
#ifdef DEBUG_ENABLED
_set_monitor_performance(monitor_performance);
#endif
} else {
_update_blackboard_plan();
}
} break;
case NOTIFICATION_ENTER_TREE: {
Expand Down
3 changes: 0 additions & 3 deletions bt/bt_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

#ifdef LIMBOAI_MODULE
#include "core/debugger/engine_debugger.h"
#include "core/error/error_macros.h"
#include "core/object/class_db.h"
#include "core/variant/variant.h"
#endif // LIMBOAI_MODULE

#ifdef LIMBOAI_GDEXTENSION
Expand Down
3 changes: 1 addition & 2 deletions bt/bt_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ class BTState : public LimboState {
StringName success_event;
StringName failure_event;

void _update_blackboard_plan();

protected:
static void _bind_methods();

void _notification(int p_notification);

virtual bool _should_use_new_scope() const override { return true; }
virtual void _update_blackboard_plan() override;

virtual void _setup() override;
virtual void _exit() override;
Expand Down
56 changes: 37 additions & 19 deletions doc/source/classes/class_blackboard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,27 @@ Methods
.. table::
:widths: auto

+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`bind_var_to_property<class_Blackboard_method_bind_var_to_property>` **(** StringName var_name, Object object, StringName property **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`erase_var<class_Blackboard_method_erase_var>` **(** StringName var_name **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`get_parent<class_Blackboard_method_get_parent>` **(** **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Variant | :ref:`get_var<class_Blackboard_method_get_var>` **(** StringName var_name, Variant default=null, bool complain=true **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`has_var<class_Blackboard_method_has_var>` **(** StringName var_name **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_parent<class_Blackboard_method_set_parent>` **(** :ref:`Blackboard<class_Blackboard>` blackboard **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_var<class_Blackboard_method_set_var>` **(** StringName var_name, Variant value **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`top<class_Blackboard_method_top>` **(** **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`unbind_var<class_Blackboard_method_unbind_var>` **(** StringName var_name **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`bind_var_to_property<class_Blackboard_method_bind_var_to_property>` **(** StringName var_name, Object object, StringName property **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`erase_var<class_Blackboard_method_erase_var>` **(** StringName var_name **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`get_parent<class_Blackboard_method_get_parent>` **(** **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Variant | :ref:`get_var<class_Blackboard_method_get_var>` **(** StringName var_name, Variant default=null, bool complain=true **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bool | :ref:`has_var<class_Blackboard_method_has_var>` **(** StringName var_name **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`link_var<class_Blackboard_method_link_var>` **(** StringName var_name, :ref:`Blackboard<class_Blackboard>` target_blackboard, StringName target_var **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_parent<class_Blackboard_method_set_parent>` **(** :ref:`Blackboard<class_Blackboard>` blackboard **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`set_var<class_Blackboard_method_set_var>` **(** StringName var_name, Variant value **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Blackboard<class_Blackboard>` | :ref:`top<class_Blackboard_method_top>` **(** **)** |const| |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`unbind_var<class_Blackboard_method_unbind_var>` **(** StringName var_name **)** |
+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+

.. rst-class:: classref-section-separator

Expand Down Expand Up @@ -122,6 +124,22 @@ Returns ``true`` if the Blackboard contains the ``var_name`` variable, including

----

.. _class_Blackboard_method_link_var:

.. rst-class:: classref-method

void **link_var** **(** StringName var_name, :ref:`Blackboard<class_Blackboard>` target_blackboard, StringName target_var **)**

Links a variable to another Blackboard variable. If a variable is linked to another variable, their state will always be identical, and any change to one will be reflected in the other. You can use this method to link a variable in the current scope to a variable in another scope, or in another Blackboard instance.



A variable can only be linked to one other variable. Calling this method again will overwrite the previous link. However, it is possible to link to the same variable from multiple different variables.

.. rst-class:: classref-item-separator

----

.. _class_Blackboard_method_set_parent:

.. rst-class:: classref-method
Expand Down
11 changes: 11 additions & 0 deletions doc_classes/Blackboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@
Returns [code]true[/code] if the Blackboard contains the [param var_name] variable, including the parent scopes.
</description>
</method>
<method name="link_var">
<return type="void" />
<param index="0" name="var_name" type="StringName" />
<param index="1" name="target_blackboard" type="Blackboard" />
<param index="2" name="target_var" type="StringName" />
<description>
Links a variable to another Blackboard variable. If a variable is linked to another variable, their state will always be identical, and any change to one will be reflected in the other. You can use this method to link a variable in the current scope to a variable in another scope, or in another Blackboard instance.

A variable can only be linked to one other variable. Calling this method again will overwrite the previous link. However, it is possible to link to the same variable from multiple different variables.
</description>
</method>
<method name="set_parent">
<return type="void" />
<param index="0" name="blackboard" type="Blackboard" />
Expand Down
Loading

0 comments on commit 088ef00

Please sign in to comment.