2024-01-23 09:33:57 +00:00
/**
2024-01-23 19:02:23 +00:00
* blackboard_plan . cpp
2024-01-23 09:33:57 +00:00
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Copyright 2021 - 2024 Serhii Snitsaruk
*
* Use of this source code is governed by an MIT - style
* license that can be found in the LICENSE file or at
* https : //opensource.org/licenses/MIT.
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2024-01-23 19:02:23 +00:00
# include "blackboard_plan.h"
2024-01-23 09:33:57 +00:00
2024-05-15 10:50:33 +00:00
# include "../util/limbo_utility.h"
2024-01-23 19:02:23 +00:00
bool BlackboardPlan : : _set ( const StringName & p_name , const Variant & p_value ) {
2024-03-04 15:55:08 +00:00
String name_str = p_name ;
2024-01-23 14:31:56 +00:00
// * Editor
2024-03-04 15:55:08 +00:00
if ( var_map . has ( p_name ) ) {
2024-03-24 23:56:08 +00:00
BBVariable & var = var_map [ p_name ] ;
var . set_value ( p_value ) ;
2024-03-04 15:55:08 +00:00
if ( base . is_valid ( ) & & p_value = = base - > get_var ( p_name ) . get_value ( ) ) {
2024-02-09 12:58:54 +00:00
// When user pressed reset property button in inspector...
2024-03-24 23:56:08 +00:00
var . reset_value_changed ( ) ;
2024-02-09 12:58:54 +00:00
}
2024-01-23 14:31:56 +00:00
return true ;
}
2024-05-14 07:29:56 +00:00
// * Mapping
if ( name_str . begins_with ( " mapping/ " ) ) {
StringName mapped_var_name = name_str . get_slicec ( ' / ' , 1 ) ;
2024-05-14 18:25:18 +00:00
StringName value = p_value ;
2024-05-17 19:48:34 +00:00
bool properties_changed = false ;
2024-05-14 18:25:18 +00:00
if ( value = = StringName ( ) ) {
2024-05-17 19:48:34 +00:00
if ( parent_scope_mapping . has ( mapped_var_name ) ) {
properties_changed = true ;
parent_scope_mapping . erase ( mapped_var_name ) ;
}
2024-05-14 18:25:18 +00:00
} else {
2024-05-17 19:48:34 +00:00
if ( ! parent_scope_mapping . has ( mapped_var_name ) ) {
properties_changed = true ;
}
2024-05-14 18:25:18 +00:00
parent_scope_mapping [ mapped_var_name ] = value ;
}
2024-05-17 19:48:34 +00:00
if ( properties_changed ) {
notify_property_list_changed ( ) ;
}
2024-05-13 21:21:55 +00:00
return true ;
}
2024-01-23 14:31:56 +00:00
// * Storage
2024-03-04 15:55:08 +00:00
if ( name_str . begins_with ( " var/ " ) ) {
StringName var_name = name_str . get_slicec ( ' / ' , 1 ) ;
String what = name_str . get_slicec ( ' / ' , 2 ) ;
2024-01-25 16:59:38 +00:00
if ( ! var_map . has ( var_name ) & & what = = " name " ) {
add_var ( var_name , BBVariable ( ) ) ;
2024-01-23 14:31:56 +00:00
}
if ( what = = " name " ) {
// We don't store variable name with the variable.
} else if ( what = = " type " ) {
2024-01-25 16:59:38 +00:00
var_map [ var_name ] . set_type ( ( Variant : : Type ) ( int ) p_value ) ;
2024-01-23 14:31:56 +00:00
} else if ( what = = " value " ) {
2024-01-25 16:59:38 +00:00
var_map [ var_name ] . set_value ( p_value ) ;
2024-01-23 14:31:56 +00:00
} else if ( what = = " hint " ) {
2024-01-25 16:59:38 +00:00
var_map [ var_name ] . set_hint ( ( PropertyHint ) ( int ) p_value ) ;
2024-01-23 14:31:56 +00:00
} else if ( what = = " hint_string " ) {
2024-01-25 16:59:38 +00:00
var_map [ var_name ] . set_hint_string ( p_value ) ;
2024-01-23 14:31:56 +00:00
} else {
return false ;
}
return true ;
}
return false ;
}
2024-01-23 19:02:23 +00:00
bool BlackboardPlan : : _get ( const StringName & p_name , Variant & r_ret ) const {
2024-03-04 15:55:08 +00:00
String name_str = p_name ;
2024-01-23 14:31:56 +00:00
// * Editor
2024-03-04 15:55:08 +00:00
if ( var_map . has ( p_name ) ) {
2024-05-13 21:21:55 +00:00
if ( has_mapping ( p_name ) ) {
2024-05-15 10:50:33 +00:00
r_ret = " Mapped to " + LimboUtility : : get_singleton ( ) - > decorate_var ( parent_scope_mapping [ p_name ] ) ;
2024-05-13 21:21:55 +00:00
} else {
r_ret = var_map [ p_name ] . get_value ( ) ;
}
return true ;
}
2024-05-14 07:29:56 +00:00
// * Mapping
if ( name_str . begins_with ( " mapping/ " ) ) {
StringName mapped_var_name = name_str . get_slicec ( ' / ' , 1 ) ;
ERR_FAIL_COND_V ( mapped_var_name = = StringName ( ) , false ) ;
2024-05-13 21:21:55 +00:00
if ( parent_scope_mapping . has ( mapped_var_name ) ) {
r_ret = parent_scope_mapping [ mapped_var_name ] ;
} else {
r_ret = StringName ( ) ;
}
2024-01-23 14:31:56 +00:00
return true ;
}
// * Storage
2024-03-04 15:55:08 +00:00
if ( ! name_str . begins_with ( " var/ " ) ) {
2024-01-23 14:31:56 +00:00
return false ;
}
2024-03-04 15:55:08 +00:00
StringName var_name = name_str . get_slicec ( ' / ' , 1 ) ;
String what = name_str . get_slicec ( ' / ' , 2 ) ;
2024-01-25 16:59:38 +00:00
ERR_FAIL_COND_V ( ! var_map . has ( var_name ) , false ) ;
2024-01-25 13:27:14 +00:00
if ( what = = " name " ) {
r_ret = var_name ;
} else if ( what = = " type " ) {
2024-01-25 16:59:38 +00:00
r_ret = var_map [ var_name ] . get_type ( ) ;
2024-01-23 14:31:56 +00:00
} else if ( what = = " value " ) {
2024-01-25 16:59:38 +00:00
r_ret = var_map [ var_name ] . get_value ( ) ;
2024-01-23 14:31:56 +00:00
} else if ( what = = " hint " ) {
2024-01-25 16:59:38 +00:00
r_ret = var_map [ var_name ] . get_hint ( ) ;
2024-01-23 14:31:56 +00:00
} else if ( what = = " hint_string " ) {
2024-01-25 16:59:38 +00:00
r_ret = var_map [ var_name ] . get_hint_string ( ) ;
2024-01-23 14:31:56 +00:00
}
return true ;
}
2024-01-23 19:02:23 +00:00
void BlackboardPlan : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2024-03-04 15:55:08 +00:00
for ( const Pair < StringName , BBVariable > & p : var_list ) {
2024-01-25 16:59:38 +00:00
String var_name = p . first ;
BBVariable var = p . second ;
2024-01-23 14:31:56 +00:00
// * Editor
2024-03-11 17:58:40 +00:00
if ( var . get_type ( ) ! = Variant : : NIL & & ( ! is_derived ( ) | | ! var_name . begins_with ( " _ " ) ) ) {
2024-05-13 21:21:55 +00:00
if ( has_mapping ( var_name ) ) {
p_list - > push_back ( PropertyInfo ( Variant : : STRING , var_name , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY ) ) ;
} else {
p_list - > push_back ( PropertyInfo ( var . get_type ( ) , var_name , var . get_hint ( ) , var . get_hint_string ( ) , PROPERTY_USAGE_EDITOR ) ) ;
}
2024-01-25 10:51:35 +00:00
}
2024-01-23 14:31:56 +00:00
2024-05-13 21:21:55 +00:00
// * Storage
2024-03-24 23:56:08 +00:00
if ( is_derived ( ) & & ( ! var . is_value_changed ( ) | | var . get_value ( ) = = base - > var_map [ var_name ] . get_value ( ) ) ) {
// Don't store variable if it's not modified in a derived plan.
// Variable is considered modified when it's marked as changed and its value is different from the base plan.
continue ;
}
2024-01-23 14:31:56 +00:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING , " var/ " + var_name + " /name " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : INT , " var/ " + var_name + " /type " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
p_list - > push_back ( PropertyInfo ( var . get_type ( ) , " var/ " + var_name + " /value " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : INT , " var/ " + var_name + " /hint " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : STRING , " var/ " + var_name + " /hint_string " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
}
2024-05-13 21:21:55 +00:00
// * Mapping
2024-05-14 09:39:32 +00:00
if ( is_mapping_enabled ( ) ) {
2024-05-14 07:29:56 +00:00
p_list - > push_back ( PropertyInfo ( Variant : : NIL , " Mapping " , PROPERTY_HINT_NONE , " mapping/ " , PROPERTY_USAGE_GROUP ) ) ;
2024-05-13 21:21:55 +00:00
for ( const Pair < StringName , BBVariable > & p : var_list ) {
2024-05-14 18:25:18 +00:00
// Serialize only non-empty mappings.
PropertyUsageFlags usage = has_mapping ( p . first ) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR ;
p_list - > push_back ( PropertyInfo ( Variant : : STRING_NAME , " mapping/ " + p . first , PROPERTY_HINT_NONE , " " , usage ) ) ;
2024-05-13 21:21:55 +00:00
}
}
2024-01-23 14:31:56 +00:00
}
2024-01-23 19:02:23 +00:00
bool BlackboardPlan : : _property_can_revert ( const StringName & p_name ) const {
2024-05-14 18:25:18 +00:00
if ( String ( p_name ) . begins_with ( " mapping/ " ) ) {
return true ;
}
2024-01-25 16:59:38 +00:00
return base . is_valid ( ) & & base - > var_map . has ( p_name ) ;
2024-01-23 16:54:20 +00:00
}
2024-01-23 19:02:23 +00:00
bool BlackboardPlan : : _property_get_revert ( const StringName & p_name , Variant & r_property ) const {
2024-05-14 18:25:18 +00:00
if ( String ( p_name ) . begins_with ( " mapping/ " ) ) {
r_property = StringName ( ) ;
return true ;
}
2024-01-25 16:59:38 +00:00
if ( base - > var_map . has ( p_name ) ) {
r_property = base - > var_map [ p_name ] . get_value ( ) ;
2024-01-23 16:54:20 +00:00
return true ;
}
return false ;
}
2024-01-23 19:02:23 +00:00
void BlackboardPlan : : set_base_plan ( const Ref < BlackboardPlan > & p_base ) {
2024-03-31 23:45:40 +00:00
if ( p_base = = this ) {
2024-04-01 13:06:06 +00:00
WARN_PRINT_ED ( " BlackboardPlan: Using same resource for derived blackboard plan is not supported. " ) ;
2024-03-31 23:45:40 +00:00
base . unref ( ) ;
} else {
base = p_base ;
}
2024-01-23 19:02:23 +00:00
sync_with_base_plan ( ) ;
2024-02-29 14:45:59 +00:00
notify_property_list_changed ( ) ;
2024-01-23 14:31:56 +00:00
}
2024-05-15 09:38:53 +00:00
void BlackboardPlan : : set_parent_scope_plan_provider ( const Callable & p_parent_scope_plan_provider ) {
parent_scope_plan_provider = p_parent_scope_plan_provider ;
2024-05-14 09:39:32 +00:00
notify_property_list_changed ( ) ;
2024-05-13 21:21:55 +00:00
}
bool BlackboardPlan : : has_mapping ( const StringName & p_name ) const {
2024-05-14 09:39:32 +00:00
return is_mapping_enabled ( ) & & parent_scope_mapping . has ( p_name ) & & parent_scope_mapping [ p_name ] ! = StringName ( ) ;
2024-05-13 21:21:55 +00:00
}
2024-03-06 19:17:23 +00:00
void BlackboardPlan : : set_prefetch_nodepath_vars ( bool p_enable ) {
prefetch_nodepath_vars = p_enable ;
emit_changed ( ) ;
}
bool BlackboardPlan : : is_prefetching_nodepath_vars ( ) const {
if ( is_derived ( ) ) {
return base - > is_prefetching_nodepath_vars ( ) ;
} else {
return prefetch_nodepath_vars ;
}
}
2024-03-04 15:55:08 +00:00
void BlackboardPlan : : add_var ( const StringName & p_name , const BBVariable & p_var ) {
2024-03-25 00:04:07 +00:00
ERR_FAIL_COND ( p_name = = StringName ( ) ) ;
2024-01-25 16:59:38 +00:00
ERR_FAIL_COND ( var_map . has ( p_name ) ) ;
var_map . insert ( p_name , p_var ) ;
2024-03-04 15:55:08 +00:00
var_list . push_back ( Pair < StringName , BBVariable > ( p_name , p_var ) ) ;
2024-01-24 22:11:09 +00:00
notify_property_list_changed ( ) ;
emit_changed ( ) ;
2024-01-23 09:33:57 +00:00
}
2024-03-04 15:55:08 +00:00
void BlackboardPlan : : remove_var ( const StringName & p_name ) {
2024-01-25 16:59:38 +00:00
ERR_FAIL_COND ( ! var_map . has ( p_name ) ) ;
2024-03-04 15:55:08 +00:00
var_list . erase ( Pair < StringName , BBVariable > ( p_name , var_map [ p_name ] ) ) ;
2024-01-25 16:59:38 +00:00
var_map . erase ( p_name ) ;
2024-01-24 22:11:09 +00:00
notify_property_list_changed ( ) ;
emit_changed ( ) ;
2024-01-23 09:33:57 +00:00
}
2024-03-04 15:55:08 +00:00
BBVariable BlackboardPlan : : get_var ( const StringName & p_name ) {
2024-01-25 16:59:38 +00:00
ERR_FAIL_COND_V ( ! var_map . has ( p_name ) , BBVariable ( ) ) ;
return var_map . get ( p_name ) ;
2024-01-23 09:33:57 +00:00
}
2024-03-04 15:55:08 +00:00
Pair < StringName , BBVariable > BlackboardPlan : : get_var_by_index ( int p_index ) {
Pair < StringName , BBVariable > ret ;
2024-01-25 16:59:38 +00:00
ERR_FAIL_INDEX_V ( p_index , ( int ) var_map . size ( ) , ret ) ;
return var_list [ p_index ] ;
2024-01-24 22:11:09 +00:00
}
2024-05-31 09:57:27 +00:00
TypedArray < StringName > BlackboardPlan : : list_vars ( ) const {
TypedArray < StringName > ret ;
2024-03-04 15:55:08 +00:00
for ( const Pair < StringName , BBVariable > & p : var_list ) {
2024-01-25 16:59:38 +00:00
ret . append ( p . first ) ;
2024-01-23 09:33:57 +00:00
}
return ret ;
}
2024-03-04 15:55:08 +00:00
StringName BlackboardPlan : : get_var_name ( const BBVariable & p_var ) const {
for ( const Pair < StringName , BBVariable > & p : var_list ) {
2024-01-25 16:59:38 +00:00
if ( p . second = = p_var ) {
return p . first ;
2024-01-24 22:11:09 +00:00
}
}
2024-03-04 15:55:08 +00:00
return StringName ( ) ;
2024-01-24 22:11:09 +00:00
}
2024-03-04 15:55:08 +00:00
bool BlackboardPlan : : is_valid_var_name ( const StringName & p_name ) const {
String name_str = p_name ;
if ( name_str . begins_with ( " resource_ " ) ) {
2024-01-29 09:32:32 +00:00
return false ;
}
2024-03-04 15:55:08 +00:00
return name_str . is_valid_identifier ( ) & & ! var_map . has ( p_name ) ;
2024-01-28 19:14:52 +00:00
}
2024-03-04 15:55:08 +00:00
void BlackboardPlan : : rename_var ( const StringName & p_name , const StringName & p_new_name ) {
2024-01-28 19:14:52 +00:00
if ( p_name = = p_new_name ) {
return ;
}
ERR_FAIL_COND ( ! is_valid_var_name ( p_new_name ) ) ;
2024-01-25 16:59:38 +00:00
ERR_FAIL_COND ( ! var_map . has ( p_name ) ) ;
2024-03-25 00:04:07 +00:00
ERR_FAIL_COND ( var_map . has ( p_new_name ) ) ;
2024-01-25 16:59:38 +00:00
BBVariable var = var_map [ p_name ] ;
2024-03-04 15:55:08 +00:00
Pair < StringName , BBVariable > new_entry ( p_new_name , var ) ;
Pair < StringName , BBVariable > old_entry ( p_name , var ) ;
2024-01-25 16:59:38 +00:00
var_list . find ( old_entry ) - > set ( new_entry ) ;
var_map . erase ( p_name ) ;
var_map . insert ( p_new_name , var ) ;
2024-01-24 22:11:09 +00:00
2024-05-17 08:00:12 +00:00
if ( parent_scope_mapping . has ( p_name ) ) {
parent_scope_mapping [ p_new_name ] = parent_scope_mapping [ p_name ] ;
parent_scope_mapping . erase ( p_name ) ;
}
2024-01-24 22:11:09 +00:00
notify_property_list_changed ( ) ;
emit_changed ( ) ;
}
2024-01-25 21:01:14 +00:00
void BlackboardPlan : : move_var ( int p_index , int p_new_index ) {
ERR_FAIL_INDEX ( p_index , ( int ) var_map . size ( ) ) ;
ERR_FAIL_INDEX ( p_new_index , ( int ) var_map . size ( ) ) ;
2024-01-24 22:11:09 +00:00
2024-01-25 21:01:14 +00:00
if ( p_index = = p_new_index ) {
return ;
}
2024-03-04 15:55:08 +00:00
List < Pair < StringName , BBVariable > > : : Element * E = var_list . front ( ) ;
2024-01-25 21:01:14 +00:00
for ( int i = 0 ; i < p_index ; i + + ) {
E = E - > next ( ) ;
}
2024-03-04 15:55:08 +00:00
List < Pair < StringName , BBVariable > > : : Element * E2 = var_list . front ( ) ;
2024-01-25 21:01:14 +00:00
for ( int i = 0 ; i < p_new_index ; i + + ) {
E2 = E2 - > next ( ) ;
}
2024-01-24 22:11:09 +00:00
2024-01-25 21:01:14 +00:00
var_list . move_before ( E , E2 ) ;
if ( p_new_index > p_index ) {
var_list . move_before ( E2 , E ) ;
}
2024-01-24 22:11:09 +00:00
notify_property_list_changed ( ) ;
emit_changed ( ) ;
}
2024-01-23 19:02:23 +00:00
void BlackboardPlan : : sync_with_base_plan ( ) {
2024-01-23 16:54:20 +00:00
if ( base . is_null ( ) ) {
return ;
}
2024-01-23 19:02:23 +00:00
2024-01-24 22:11:09 +00:00
bool changed = false ;
2024-01-23 19:02:23 +00:00
// Sync variables with the base plan.
2024-03-04 15:55:08 +00:00
for ( const Pair < StringName , BBVariable > & p : base - > var_list ) {
const StringName & base_name = p . first ;
2024-01-25 16:59:38 +00:00
const BBVariable & base_var = p . second ;
if ( ! var_map . has ( base_name ) ) {
add_var ( base_name , base_var . duplicate ( ) ) ;
2024-01-24 22:11:09 +00:00
changed = true ;
2024-01-23 09:33:57 +00:00
continue ;
}
2024-01-25 16:59:38 +00:00
BBVariable var = var_map [ base_name ] ;
if ( ! var . is_same_prop_info ( base_var ) ) {
var . copy_prop_info ( base_var ) ;
2024-01-24 22:11:09 +00:00
changed = true ;
2024-01-23 09:33:57 +00:00
}
2024-02-09 12:58:54 +00:00
if ( ( ! var . is_value_changed ( ) & & var . get_value ( ) ! = base_var . get_value ( ) ) | |
( var . get_value ( ) . get_type ( ) ! = base_var . get_type ( ) ) ) {
// Reset value according to base plan.
2024-01-25 16:59:38 +00:00
var . set_value ( base_var . get_value ( ) ) ;
2024-02-09 12:58:54 +00:00
var . reset_value_changed ( ) ;
2024-01-24 22:11:09 +00:00
changed = true ;
2024-01-23 09:33:57 +00:00
}
}
2024-01-23 19:02:23 +00:00
// Erase variables that do not exist in the base plan.
2024-03-25 00:04:07 +00:00
List < StringName > erase_list ;
2024-03-04 15:55:08 +00:00
for ( const Pair < StringName , BBVariable > & p : var_list ) {
2024-01-25 16:59:38 +00:00
if ( ! base - > has_var ( p . first ) ) {
2024-03-25 00:04:07 +00:00
erase_list . push_back ( p . first ) ;
2024-01-24 22:11:09 +00:00
changed = true ;
2024-01-23 19:02:23 +00:00
}
}
2024-03-25 00:04:07 +00:00
while ( erase_list . size ( ) ) {
remove_var ( erase_list . front ( ) - > get ( ) ) ;
erase_list . pop_front ( ) ;
}
2024-01-24 22:11:09 +00:00
2024-03-12 16:11:01 +00:00
// 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 ) {
2024-03-12 20:09:28 +00:00
List < Pair < StringName , BBVariable > > : : Element * F = E - > next ( ) ;
while ( F ) {
2024-03-12 16:11:01 +00:00
if ( F - > get ( ) . first = = B - > get ( ) . first ) {
var_list . move_before ( F , E ) ;
E = F ;
break ;
}
2024-03-12 20:09:28 +00:00
F = F - > next ( ) ;
2024-03-12 16:11:01 +00:00
}
}
B = B - > next ( ) ;
}
2024-01-24 22:11:09 +00:00
if ( changed ) {
notify_property_list_changed ( ) ;
emit_changed ( ) ;
}
2024-01-23 09:33:57 +00:00
}
2024-03-06 19:17:23 +00:00
// Add a variable duplicate to the blackboard, optionally with NodePath prefetch.
inline void bb_add_var_dup_with_prefetch ( const Ref < Blackboard > & p_blackboard , const StringName & p_name , const BBVariable & p_var , bool p_prefetch , Node * p_node ) {
if ( unlikely ( p_prefetch & & p_var . get_type ( ) = = Variant : : NODE_PATH ) ) {
Node * n = p_node - > get_node_or_null ( p_var . get_value ( ) ) ;
2024-07-06 08:04:36 +00:00
BBVariable var = p_var . duplicate ( true ) ;
2024-03-06 19:17:23 +00:00
if ( n ! = nullptr ) {
var . set_value ( n ) ;
} else {
2024-03-11 23:30:38 +00:00
if ( p_blackboard - > has_var ( p_name ) ) {
// Not adding: Assuming variable was initialized by the user or in the parent scope.
return ;
2024-03-11 21:12:44 +00:00
}
2024-03-11 23:30:38 +00:00
ERR_PRINT ( vformat ( " BlackboardPlan: Prefetch failed for variable $%s with value: %s " , p_name , p_var . get_value ( ) ) ) ;
var . set_value ( Variant ( ) ) ;
2024-03-06 19:17:23 +00:00
}
2024-03-11 23:30:38 +00:00
p_blackboard - > assign_var ( p_name , var ) ;
2024-03-06 19:17:23 +00:00
} else {
2024-07-06 08:04:36 +00:00
p_blackboard - > assign_var ( p_name , p_var . duplicate ( true ) ) ;
2024-03-06 19:17:23 +00:00
}
}
2024-05-13 21:21:55 +00:00
Ref < Blackboard > BlackboardPlan : : create_blackboard ( Node * p_node , const Ref < Blackboard > & p_parent_scope ) {
2024-03-06 19:17:23 +00:00
ERR_FAIL_COND_V ( p_node = = nullptr & & prefetch_nodepath_vars , memnew ( Blackboard ) ) ;
2024-01-23 09:33:57 +00:00
Ref < Blackboard > bb = memnew ( Blackboard ) ;
2024-05-13 21:21:55 +00:00
bb - > set_parent ( p_parent_scope ) ;
2024-05-14 17:47:05 +00:00
populate_blackboard ( bb , true , p_node ) ;
2024-01-23 09:33:57 +00:00
return bb ;
}
2024-01-23 11:05:54 +00:00
2024-03-06 19:17:23 +00:00
void BlackboardPlan : : populate_blackboard ( const Ref < Blackboard > & p_blackboard , bool overwrite , Node * p_node ) {
ERR_FAIL_COND ( p_node = = nullptr & & prefetch_nodepath_vars ) ;
2024-03-04 15:55:08 +00:00
for ( const Pair < StringName , BBVariable > & p : var_list ) {
2024-03-13 21:00:50 +00:00
if ( p_blackboard - > has_var ( p . first ) & & ! overwrite ) {
continue ;
2024-01-23 11:05:54 +00:00
}
2024-03-06 19:17:23 +00:00
bb_add_var_dup_with_prefetch ( p_blackboard , p . first , p . second , prefetch_nodepath_vars , p_node ) ;
2024-05-13 21:21:55 +00:00
if ( parent_scope_mapping . has ( p . first ) ) {
StringName target_var = parent_scope_mapping [ p . first ] ;
if ( target_var ! = StringName ( ) ) {
ERR_CONTINUE_MSG ( p_blackboard - > get_parent ( ) = = nullptr , vformat ( " BlackboardPlan: Cannot link variable $%s to parent scope because the parent scope is not set. " , p . first ) ) ;
p_blackboard - > link_var ( p . first , p_blackboard - > get_parent ( ) , target_var ) ;
}
}
2024-01-23 11:05:54 +00:00
}
}
2024-01-23 14:31:56 +00:00
2024-03-02 15:06:32 +00:00
void BlackboardPlan : : _bind_methods ( ) {
2024-03-06 19:17:23 +00:00
ClassDB : : bind_method ( D_METHOD ( " set_prefetch_nodepath_vars " , " enable " ) , & BlackboardPlan : : set_prefetch_nodepath_vars ) ;
ClassDB : : bind_method ( D_METHOD ( " is_prefetching_nodepath_vars " ) , & BlackboardPlan : : is_prefetching_nodepath_vars ) ;
2024-03-08 14:33:28 +00:00
ClassDB : : bind_method ( D_METHOD ( " set_base_plan " , " blackboard_plan " ) , & BlackboardPlan : : set_base_plan ) ;
ClassDB : : bind_method ( D_METHOD ( " get_base_plan " ) , & BlackboardPlan : : get_base_plan ) ;
ClassDB : : bind_method ( D_METHOD ( " is_derived " ) , & BlackboardPlan : : is_derived ) ;
ClassDB : : bind_method ( D_METHOD ( " sync_with_base_plan " ) , & BlackboardPlan : : sync_with_base_plan ) ;
2024-05-15 18:43:24 +00:00
ClassDB : : bind_method ( D_METHOD ( " set_parent_scope_plan_provider " , " callable " ) , & BlackboardPlan : : set_parent_scope_plan_provider ) ;
ClassDB : : bind_method ( D_METHOD ( " get_parent_scope_plan_provider " ) , & BlackboardPlan : : get_parent_scope_plan_provider ) ;
2024-05-17 08:36:25 +00:00
ClassDB : : bind_method ( D_METHOD ( " create_blackboard " , " node " , " parent_scope " ) , & BlackboardPlan : : create_blackboard , DEFVAL ( Ref < Blackboard > ( ) ) ) ;
2024-03-06 19:17:23 +00:00
ClassDB : : bind_method ( D_METHOD ( " populate_blackboard " , " blackboard " , " overwrite " , " node " ) , & BlackboardPlan : : populate_blackboard ) ;
2024-03-08 14:33:28 +00:00
// To avoid cluttering the member namespace, we do not export unnecessary properties in this class.
2024-03-06 19:17:23 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " prefetch_nodepath_vars " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_STORAGE ) , " set_prefetch_nodepath_vars " , " is_prefetching_nodepath_vars " ) ;
2024-03-02 15:06:32 +00:00
}
2024-01-23 19:02:23 +00:00
BlackboardPlan : : BlackboardPlan ( ) {
2024-01-23 14:31:56 +00:00
}