Skip to content

Commit

Permalink
API: Add Blackboard methods to enable iteration, state inspection a…
Browse files Browse the repository at this point in the history
…nd serialization
  • Loading branch information
limbonaut committed May 31, 2024
1 parent 49f5e3b commit a4eb167
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
35 changes: 35 additions & 0 deletions blackboard/blackboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,37 @@ void Blackboard::erase_var(const StringName &p_name) {
data.erase(p_name);
}

TypedArray<StringName> Blackboard::list_vars() const {
Array var_names;
var_names.set_typed(Variant::STRING_NAME, StringName(), Variant());
var_names.resize(data.size());
int idx = 0;
for (const KeyValue<StringName, BBVariable> &kv : data) {
var_names.set(idx, kv.key);
idx += 1;
}
return var_names;
}

Dictionary Blackboard::get_vars_as_dict() const {
Dictionary dict;
for (const KeyValue<StringName, BBVariable> &kv : data) {
dict[kv.key] = kv.value.get_value();
}
return dict;
}

void Blackboard::populate_from_dict(const Dictionary &p_dictionary) {
Array keys = p_dictionary.keys();
for (int i = 0; i < keys.size(); i++) {
if (keys[i].get_type() == Variant::STRING_NAME || keys[i].get_type() == Variant::STRING) {
set_var(keys[i], p_dictionary[keys[i]]);
} else {
ERR_PRINT("Blackboard: Invalid key type in dictionary to populate blackboard. Must be StringName or String.");
}
}
}

void Blackboard::bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property, bool p_create) {
if (!data.has(p_name)) {
if (p_create) {
Expand Down Expand Up @@ -104,6 +135,10 @@ void Blackboard::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_parent", "blackboard"), &Blackboard::set_parent);
ClassDB::bind_method(D_METHOD("get_parent"), &Blackboard::get_parent);
ClassDB::bind_method(D_METHOD("erase_var", "var_name"), &Blackboard::erase_var);
ClassDB::bind_method(D_METHOD("clear"), &Blackboard::clear);
ClassDB::bind_method(D_METHOD("list_vars"), &Blackboard::list_vars);
ClassDB::bind_method(D_METHOD("get_vars_as_dict"), &Blackboard::get_vars_as_dict);
ClassDB::bind_method(D_METHOD("populate_from_dict", "dictionary"), &Blackboard::populate_from_dict);
ClassDB::bind_method(D_METHOD("top"), &Blackboard::top);
ClassDB::bind_method(D_METHOD("bind_var_to_property", "var_name", "object", "property", "create"), &Blackboard::bind_var_to_property, DEFVAL(false));
ClassDB::bind_method(D_METHOD("unbind_var", "var_name"), &Blackboard::unbind_var);
Expand Down
7 changes: 5 additions & 2 deletions blackboard/blackboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,18 @@ class Blackboard : public RefCounted {
void set_var(const StringName &p_name, const Variant &p_value);
bool has_var(const StringName &p_name) const;
void erase_var(const StringName &p_name);
void clear() { data.clear(); }
TypedArray<StringName> list_vars() const;

Dictionary get_vars_as_dict() const;
void populate_from_dict(const Dictionary &p_dictionary);

void bind_var_to_property(const StringName &p_name, Object *p_object, const StringName &p_property, bool p_create = false);
void unbind_var(const StringName &p_name);

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, bool p_create = false);

// TODO: Add serialization API.
};

#endif // BLACKBOARD_H
56 changes: 56 additions & 0 deletions doc/source/classes/class_blackboard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,24 @@ Methods
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`bind_var_to_property<class_Blackboard_method_bind_var_to_property>` **(** StringName var_name, Object object, StringName property, bool create=false **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`clear<class_Blackboard_method_clear>` **(** **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Dictionary | :ref:`get_vars_as_dict<class_Blackboard_method_get_vars_as_dict>` **(** **)** |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, bool create=false **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| StringName[] | :ref:`list_vars<class_Blackboard_method_list_vars>` **(** **)** |const| |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| void | :ref:`populate_from_dict<class_Blackboard_method_populate_from_dict>` **(** Dictionary dictionary **)** |
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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 **)** |
Expand Down Expand Up @@ -76,6 +84,18 @@ Establish a binding between a variable and the object's property specified by ``

----

.. _class_Blackboard_method_clear:

.. rst-class:: classref-method

void **clear** **(** **)**

Removes all variables from the Blackboard. Parent scopes are not affected.

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

----

.. _class_Blackboard_method_erase_var:

.. rst-class:: classref-method
Expand Down Expand Up @@ -112,6 +132,18 @@ Returns variable value or ``default`` if variable doesn't exist. If ``complain``

----

.. _class_Blackboard_method_get_vars_as_dict:

.. rst-class:: classref-method

Dictionary **get_vars_as_dict** **(** **)** |const|

Returns all variables in the Blackboard as a dictionary. Keys are the variable names, values are the variable values. Parent scopes are not included.

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

----

.. _class_Blackboard_method_has_var:

.. rst-class:: classref-method
Expand All @@ -138,6 +170,30 @@ You can use this method to link a variable in the current scope to a variable in

----

.. _class_Blackboard_method_list_vars:

.. rst-class:: classref-method

StringName[] **list_vars** **(** **)** |const|

Returns all variable names in the Blackboard. Parent scopes are not included.

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

----

.. _class_Blackboard_method_populate_from_dict:

.. rst-class:: classref-method

void **populate_from_dict** **(** Dictionary dictionary **)**

Fills the Blackboard with multiple variables from a dictionary. The dictionary keys must be variable names and the dictionary values must be variable values. Keys must be StringName or String.

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

----

.. _class_Blackboard_method_set_parent:

.. rst-class:: classref-method
Expand Down
25 changes: 25 additions & 0 deletions doc_classes/Blackboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
Establish a binding between a variable and the object's property specified by [param property] and [param object]. Changes to the variable update the property, and vice versa. If [param create] is [code]true[/code], the variable will be created if it doesn't exist.
</description>
</method>
<method name="clear">
<return type="void" />
<description>
Removes all variables from the Blackboard. Parent scopes are not affected.
</description>
</method>
<method name="erase_var">
<return type="void" />
<param index="0" name="var_name" type="StringName" />
Expand All @@ -43,6 +49,12 @@
Returns variable value or [param default] if variable doesn't exist. If [param complain] is [code]true[/code], an error will be printed if variable doesn't exist.
</description>
</method>
<method name="get_vars_as_dict" qualifiers="const">
<return type="Dictionary" />
<description>
Returns all variables in the Blackboard as a dictionary. Keys are the variable names, values are the variable values. Parent scopes are not included.
</description>
</method>
<method name="has_var" qualifiers="const">
<return type="bool" />
<param index="0" name="var_name" type="StringName" />
Expand All @@ -61,6 +73,19 @@
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="list_vars" qualifiers="const">
<return type="StringName[]" />
<description>
Returns all variable names in the Blackboard. Parent scopes are not included.
</description>
</method>
<method name="populate_from_dict">
<return type="void" />
<param index="0" name="dictionary" type="Dictionary" />
<description>
Fills the Blackboard with multiple variables from a dictionary. The dictionary keys must be variable names and the dictionary values must be variable values. Keys must be StringName or String.
</description>
</method>
<method name="set_parent">
<return type="void" />
<param index="0" name="blackboard" type="Blackboard" />
Expand Down

0 comments on commit a4eb167

Please sign in to comment.