Merge pull request #183 from limbonaut/btplayer-allow-changing-instance
BTPlayer: Allow switching BT instance at runtime
This commit is contained in:
commit
8b2770116d
|
@ -81,6 +81,7 @@ Ref<BTInstance> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &
|
||||||
ERR_FAIL_COND_V_MSG(root_task == nullptr, nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
|
ERR_FAIL_COND_V_MSG(root_task == nullptr, nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
|
||||||
ERR_FAIL_NULL_V_MSG(p_agent, nullptr, "BehaviorTree: Instantiation failed - agent can't be null.");
|
ERR_FAIL_NULL_V_MSG(p_agent, nullptr, "BehaviorTree: Instantiation failed - agent can't be null.");
|
||||||
ERR_FAIL_NULL_V_MSG(p_instance_owner, nullptr, "BehaviorTree: Instantiation failed -- instance owner can't be null.");
|
ERR_FAIL_NULL_V_MSG(p_instance_owner, nullptr, "BehaviorTree: Instantiation failed -- instance owner can't be null.");
|
||||||
|
ERR_FAIL_NULL_V_MSG(p_blackboard, nullptr, "BehaviorTree: Instantiation failed - blackboard can't be null.");
|
||||||
Node *scene_root = p_instance_owner->get_owner();
|
Node *scene_root = p_instance_owner->get_owner();
|
||||||
ERR_FAIL_NULL_V_MSG(scene_root, nullptr, "BehaviorTree: Instantiation failed - can't get scene root, because instance_owner not owned by a scene node. Hint: Try my_player.set_owner(get_owner()).");
|
ERR_FAIL_NULL_V_MSG(scene_root, nullptr, "BehaviorTree: Instantiation failed - can't get scene root, because instance_owner not owned by a scene node. Hint: Try my_player.set_owner(get_owner()).");
|
||||||
Ref<BTTask> root_copy = root_task->clone();
|
Ref<BTTask> root_copy = root_task->clone();
|
||||||
|
|
|
@ -127,6 +127,10 @@ void BTInstance::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_owner_node"), &BTInstance::get_owner_node);
|
ClassDB::bind_method(D_METHOD("get_owner_node"), &BTInstance::get_owner_node);
|
||||||
ClassDB::bind_method(D_METHOD("get_last_status"), &BTInstance::get_last_status);
|
ClassDB::bind_method(D_METHOD("get_last_status"), &BTInstance::get_last_status);
|
||||||
ClassDB::bind_method(D_METHOD("get_source_bt_path"), &BTInstance::get_source_bt_path);
|
ClassDB::bind_method(D_METHOD("get_source_bt_path"), &BTInstance::get_source_bt_path);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_agent"), &BTInstance::get_agent);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTInstance::get_blackboard);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("is_instance_valid"), &BTInstance::is_instance_valid);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_monitor_performance", "monitor"), &BTInstance::set_monitor_performance);
|
ClassDB::bind_method(D_METHOD("set_monitor_performance", "monitor"), &BTInstance::set_monitor_performance);
|
||||||
ClassDB::bind_method(D_METHOD("get_monitor_performance"), &BTInstance::get_monitor_performance);
|
ClassDB::bind_method(D_METHOD("get_monitor_performance"), &BTInstance::get_monitor_performance);
|
||||||
|
|
|
@ -41,8 +41,11 @@ public:
|
||||||
_FORCE_INLINE_ Ref<BTTask> get_root_task() const { return root_task; }
|
_FORCE_INLINE_ Ref<BTTask> get_root_task() const { return root_task; }
|
||||||
_FORCE_INLINE_ Node *get_owner_node() const { return owner_node_id ? Object::cast_to<Node>(OBJECT_DB_GET_INSTANCE(owner_node_id)) : nullptr; }
|
_FORCE_INLINE_ Node *get_owner_node() const { return owner_node_id ? Object::cast_to<Node>(OBJECT_DB_GET_INSTANCE(owner_node_id)) : nullptr; }
|
||||||
_FORCE_INLINE_ BT::Status get_last_status() const { return last_status; }
|
_FORCE_INLINE_ BT::Status get_last_status() const { return last_status; }
|
||||||
_FORCE_INLINE_ bool is_instance_valid() const { return root_task.is_valid(); }
|
|
||||||
_FORCE_INLINE_ String get_source_bt_path() const { return source_bt_path; }
|
_FORCE_INLINE_ String get_source_bt_path() const { return source_bt_path; }
|
||||||
|
_FORCE_INLINE_ Node *get_agent() const { return root_task.is_valid() ? root_task->get_agent() : nullptr; }
|
||||||
|
_FORCE_INLINE_ Ref<Blackboard> get_blackboard() const { return root_task.is_valid() ? root_task->get_blackboard() : Ref<Blackboard>(); }
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool is_instance_valid() const { return root_task.is_valid(); }
|
||||||
|
|
||||||
BT::Status update(double p_delta);
|
BT::Status update(double p_delta);
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,18 @@ void BTPlayer::_update_blackboard_plan() {
|
||||||
blackboard_plan->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
|
blackboard_plan->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BTPlayer::set_bt_instance(const Ref<BTInstance> &p_bt_instance) {
|
||||||
|
ERR_FAIL_COND_MSG(p_bt_instance.is_null(), "BTPlayer: Failed to set behavior tree instance - instance is null.");
|
||||||
|
ERR_FAIL_COND_MSG(!p_bt_instance->is_instance_valid(), "BTPlayer: Failed to set behavior tree instance - instance is not valid.");
|
||||||
|
|
||||||
|
bt_instance = p_bt_instance;
|
||||||
|
blackboard = p_bt_instance->get_blackboard();
|
||||||
|
agent_node = p_bt_instance->get_agent()->get_path();
|
||||||
|
|
||||||
|
blackboard_plan.unref();
|
||||||
|
behavior_tree.unref();
|
||||||
|
}
|
||||||
|
|
||||||
void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(plan_changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) {
|
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(plan_changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) {
|
||||||
|
@ -217,6 +229,7 @@ void BTPlayer::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("restart"), &BTPlayer::restart);
|
ClassDB::bind_method(D_METHOD("restart"), &BTPlayer::restart);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_bt_instance"), &BTPlayer::get_bt_instance);
|
ClassDB::bind_method(D_METHOD("get_bt_instance"), &BTPlayer::get_bt_instance);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bt_instance", "bt_instance"), &BTPlayer::set_bt_instance);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "agent_node"), "set_agent_node", "get_agent_node");
|
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "agent_node"), "set_agent_node", "get_agent_node");
|
||||||
|
|
|
@ -77,6 +77,7 @@ public:
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
Ref<BTInstance> get_bt_instance() { return bt_instance; }
|
Ref<BTInstance> get_bt_instance() { return bt_instance; }
|
||||||
|
void set_bt_instance(const Ref<BTInstance> &p_bt_instance);
|
||||||
|
|
||||||
BTPlayer();
|
BTPlayer();
|
||||||
~BTPlayer();
|
~BTPlayer();
|
||||||
|
|
|
@ -174,7 +174,7 @@ Returns the root task of the BehaviorTree resource.
|
||||||
|
|
||||||
:ref:`BTInstance<class_BTInstance>` **instantiate**\ (\ agent\: ``Node``, blackboard\: :ref:`Blackboard<class_Blackboard>`, instance_owner\: ``Node``\ ) |const| :ref:`🔗<class_BehaviorTree_method_instantiate>`
|
:ref:`BTInstance<class_BTInstance>` **instantiate**\ (\ agent\: ``Node``, blackboard\: :ref:`Blackboard<class_Blackboard>`, instance_owner\: ``Node``\ ) |const| :ref:`🔗<class_BehaviorTree_method_instantiate>`
|
||||||
|
|
||||||
Instantiates the behavior tree and returns :ref:`BTInstance<class_BTInstance>`. ``instance_owner`` should be the scene node that will own the behavior tree instance. This is typically a :ref:`BTPlayer<class_BTPlayer>`, :ref:`BTState<class_BTState>`, or a custom player node that controls the behavior tree execution.
|
Instantiates the behavior tree and returns :ref:`BTInstance<class_BTInstance>`. ``instance_owner`` should be the scene node that will own the behavior tree instance. This is typically a :ref:`BTPlayer<class_BTPlayer>`, :ref:`BTState<class_BTState>`, or a custom player node that controls the behavior tree execution. Make sure to pass a :ref:`Blackboard<class_Blackboard>` with values populated from :ref:`blackboard_plan<class_BehaviorTree_property_blackboard_plan>`. See also ``BlackboardPlan.populate_blackboard`` & ``BlackboardPlan.create_blackboard``.
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
|
|
@ -41,21 +41,27 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
|
| ``Node`` | :ref:`get_agent<class_BTInstance_method_get_agent>`\ (\ ) |const| |
|
||||||
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
|
| :ref:`Blackboard<class_Blackboard>` | :ref:`get_blackboard<class_BTInstance_method_get_blackboard>`\ (\ ) |const| |
|
||||||
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| :ref:`Status<enum_BT_Status>` | :ref:`get_last_status<class_BTInstance_method_get_last_status>`\ (\ ) |const| |
|
| :ref:`Status<enum_BT_Status>` | :ref:`get_last_status<class_BTInstance_method_get_last_status>`\ (\ ) |const| |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| ``Node`` | :ref:`get_owner_node<class_BTInstance_method_get_owner_node>`\ (\ ) |const| |
|
| ``Node`` | :ref:`get_owner_node<class_BTInstance_method_get_owner_node>`\ (\ ) |const| |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BTInstance_method_get_root_task>`\ (\ ) |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BTInstance_method_get_root_task>`\ (\ ) |const| |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| ``String`` | :ref:`get_source_bt_path<class_BTInstance_method_get_source_bt_path>`\ (\ ) |const| |
|
| ``String`` | :ref:`get_source_bt_path<class_BTInstance_method_get_source_bt_path>`\ (\ ) |const| |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
|
| ``bool`` | :ref:`is_instance_valid<class_BTInstance_method_is_instance_valid>`\ (\ ) |const| |
|
||||||
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`register_with_debugger<class_BTInstance_method_register_with_debugger>`\ (\ ) |
|
| |void| | :ref:`register_with_debugger<class_BTInstance_method_register_with_debugger>`\ (\ ) |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`unregister_with_debugger<class_BTInstance_method_unregister_with_debugger>`\ (\ ) |
|
| |void| | :ref:`unregister_with_debugger<class_BTInstance_method_unregister_with_debugger>`\ (\ ) |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
| :ref:`Status<enum_BT_Status>` | :ref:`update<class_BTInstance_method_update>`\ (\ delta\: ``float``\ ) |
|
| :ref:`Status<enum_BT_Status>` | :ref:`update<class_BTInstance_method_update>`\ (\ delta\: ``float``\ ) |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------------------+
|
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -117,6 +123,30 @@ If ``true``, adds a performance monitor for this instance to "Debugger->Monitors
|
||||||
Method Descriptions
|
Method Descriptions
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
.. _class_BTInstance_method_get_agent:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
``Node`` **get_agent**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_agent>`
|
||||||
|
|
||||||
|
Returns the agent of the behavior tree instance.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
.. _class_BTInstance_method_get_blackboard:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
:ref:`Blackboard<class_Blackboard>` **get_blackboard**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_blackboard>`
|
||||||
|
|
||||||
|
Returns the blackboard of the behavior tree instance.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_last_status:
|
.. _class_BTInstance_method_get_last_status:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
@ -165,6 +195,18 @@ Returns the file path to the behavior tree resource that was used to create this
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
.. _class_BTInstance_method_is_instance_valid:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
``bool`` **is_instance_valid**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_is_instance_valid>`
|
||||||
|
|
||||||
|
Returns ``true`` if the behavior tree instance is properly initialized and can be used.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
.. _class_BTInstance_method_register_with_debugger:
|
.. _class_BTInstance_method_register_with_debugger:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
|
@ -55,13 +55,15 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-------------------------------------+----------------------------------------------------------------------+
|
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTInstance<class_BTInstance>` | :ref:`get_bt_instance<class_BTPlayer_method_get_bt_instance>`\ (\ ) |
|
| :ref:`BTInstance<class_BTInstance>` | :ref:`get_bt_instance<class_BTPlayer_method_get_bt_instance>`\ (\ ) |
|
||||||
+-------------------------------------+----------------------------------------------------------------------+
|
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`restart<class_BTPlayer_method_restart>`\ (\ ) |
|
| |void| | :ref:`restart<class_BTPlayer_method_restart>`\ (\ ) |
|
||||||
+-------------------------------------+----------------------------------------------------------------------+
|
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| |void| | :ref:`set_bt_instance<class_BTPlayer_method_set_bt_instance>`\ (\ bt_instance\: :ref:`BTInstance<class_BTInstance>`\ ) |
|
||||||
|
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`update<class_BTPlayer_method_update>`\ (\ delta\: ``float``\ ) |
|
| |void| | :ref:`update<class_BTPlayer_method_update>`\ (\ delta\: ``float``\ ) |
|
||||||
+-------------------------------------+----------------------------------------------------------------------+
|
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -289,6 +291,18 @@ Resets the behavior tree's execution. Each running task will be aborted and the
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
.. _class_BTPlayer_method_set_bt_instance:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
|void| **set_bt_instance**\ (\ bt_instance\: :ref:`BTInstance<class_BTInstance>`\ ) :ref:`🔗<class_BTPlayer_method_set_bt_instance>`
|
||||||
|
|
||||||
|
Sets the :ref:`BTInstance<class_BTInstance>` to play. This method is useful when you want to switch to a different behavior tree instance at runtime. See also :ref:`BehaviorTree.instantiate<class_BehaviorTree_property_instantiate>`.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
.. _class_BTPlayer_method_update:
|
.. _class_BTPlayer_method_update:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
|
@ -9,6 +9,18 @@
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
|
<method name="get_agent" qualifiers="const">
|
||||||
|
<return type="Node" />
|
||||||
|
<description>
|
||||||
|
Returns the agent of the behavior tree instance.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_blackboard" qualifiers="const">
|
||||||
|
<return type="Blackboard" />
|
||||||
|
<description>
|
||||||
|
Returns the blackboard of the behavior tree instance.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_last_status" qualifiers="const">
|
<method name="get_last_status" qualifiers="const">
|
||||||
<return type="int" enum="BT.Status" />
|
<return type="int" enum="BT.Status" />
|
||||||
<description>
|
<description>
|
||||||
|
@ -33,6 +45,12 @@
|
||||||
Returns the file path to the behavior tree resource that was used to create this instance.
|
Returns the file path to the behavior tree resource that was used to create this instance.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="is_instance_valid" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if the behavior tree instance is properly initialized and can be used.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="register_with_debugger">
|
<method name="register_with_debugger">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -22,6 +22,13 @@
|
||||||
Resets the behavior tree's execution. Each running task will be aborted and the next tree execution will start anew. This method does not reset [Blackboard].
|
Resets the behavior tree's execution. Each running task will be aborted and the next tree execution will start anew. This method does not reset [Blackboard].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="set_bt_instance">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="bt_instance" type="BTInstance" />
|
||||||
|
<description>
|
||||||
|
Sets the [BTInstance] to play. This method is useful when you want to switch to a different behavior tree instance at runtime. See also [member BehaviorTree.instantiate].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="update">
|
<method name="update">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="delta" type="float" />
|
<param index="0" name="delta" type="float" />
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<param index="1" name="blackboard" type="Blackboard" />
|
<param index="1" name="blackboard" type="Blackboard" />
|
||||||
<param index="2" name="instance_owner" type="Node" />
|
<param index="2" name="instance_owner" type="Node" />
|
||||||
<description>
|
<description>
|
||||||
Instantiates the behavior tree and returns [BTInstance]. [param instance_owner] should be the scene node that will own the behavior tree instance. This is typically a [BTPlayer], [BTState], or a custom player node that controls the behavior tree execution.
|
Instantiates the behavior tree and returns [BTInstance]. [param instance_owner] should be the scene node that will own the behavior tree instance. This is typically a [BTPlayer], [BTState], or a custom player node that controls the behavior tree execution. Make sure to pass a [Blackboard] with values populated from [member blackboard_plan]. See also [BlackboardPlan.populate_blackboard] & [BlackboardPlan.create_blackboard].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_root_task">
|
<method name="set_root_task">
|
||||||
|
|
Loading…
Reference in New Issue