2014-02-10 02:10:30 +01:00
/*************************************************************************/
2017-09-01 16:07:55 +02:00
/* scene_tree.h */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2020-09-10 16:04:30 +02:00
# ifndef SCENE_TREE_H
# define SCENE_TREE_H
2014-02-10 02:10:30 +01:00
2018-09-11 18:13:45 +02:00
# include "core/os/main_loop.h"
# include "core/os/thread_safe.h"
2020-11-07 23:33:38 +01:00
# include "core/templates/self_list.h"
2017-06-07 23:18:55 +02:00
# include "scene/resources/mesh.h"
2016-08-14 23:49:50 +02:00
2020-03-04 02:51:12 +01:00
# undef Window
2015-05-17 21:33:35 +02:00
class PackedScene ;
2014-02-10 02:10:30 +01:00
class Node ;
2020-03-04 02:51:12 +01:00
class Window ;
2015-09-20 18:03:46 +02:00
class Material ;
class Mesh ;
2021-10-08 14:13:06 +02:00
class MultiplayerAPI ;
2020-02-07 02:52:05 +01:00
class SceneDebugger ;
2020-09-05 03:05:30 +02:00
class Tween ;
2022-02-12 02:46:22 +01:00
class Viewport ;
2014-06-30 03:41:02 +02:00
2021-06-04 18:03:15 +02:00
class SceneTreeTimer : public RefCounted {
GDCLASS ( SceneTreeTimer , RefCounted ) ;
2016-08-07 02:39:50 +02:00
2021-05-21 07:23:35 +02:00
double time_left = 0.0 ;
2021-02-19 13:57:41 +01:00
bool process_always = true ;
2022-07-15 08:21:51 +02:00
bool process_in_physics = false ;
2021-02-27 00:37:20 +01:00
bool ignore_time_scale = false ;
2017-03-05 16:44:50 +01:00
2016-08-07 02:39:50 +02:00
protected :
static void _bind_methods ( ) ;
2017-03-05 16:44:50 +01:00
public :
2021-05-21 07:23:35 +02:00
void set_time_left ( double p_time ) ;
double get_time_left ( ) const ;
2016-08-07 02:39:50 +02:00
2021-02-19 13:57:41 +01:00
void set_process_always ( bool p_process_always ) ;
bool is_process_always ( ) ;
2017-02-14 00:34:33 +01:00
2022-07-15 08:21:51 +02:00
void set_process_in_physics ( bool p_process_in_physics ) ;
bool is_process_in_physics ( ) ;
2021-02-27 00:37:20 +01:00
void set_ignore_time_scale ( bool p_ignore ) ;
bool is_ignore_time_scale ( ) ;
2019-10-19 18:45:17 +02:00
void release_connections ( ) ;
2016-08-07 02:39:50 +02:00
SceneTreeTimer ( ) ;
} ;
2014-11-06 01:20:42 +01:00
class SceneTree : public MainLoop {
2014-02-10 02:10:30 +01:00
_THREAD_SAFE_CLASS_
2017-01-03 03:03:46 +01:00
GDCLASS ( SceneTree , MainLoop ) ;
2014-04-15 03:43:44 +02:00
2017-03-05 16:44:50 +01:00
public :
2016-10-27 16:50:26 +02:00
typedef void ( * IdleCallback ) ( ) ;
2017-03-05 16:44:50 +01:00
private :
2014-02-10 02:10:30 +01:00
struct Group {
Vector < Node * > nodes ;
2021-02-09 18:24:36 +01:00
bool changed = false ;
2014-02-10 02:10:30 +01:00
} ;
2020-12-11 15:54:03 +01:00
Window * root = nullptr ;
2014-02-10 02:10:30 +01:00
2020-12-11 15:54:03 +01:00
uint64_t tree_version = 1 ;
2022-07-16 17:07:03 +02:00
double physics_process_time = 0.0 ;
double process_time = 0.0 ;
2020-12-11 15:54:03 +01:00
bool accept_quit = true ;
bool quit_on_go_back = true ;
2014-02-10 02:10:30 +01:00
2017-04-07 16:17:16 +02:00
# ifdef DEBUG_ENABLED
2020-12-11 15:54:03 +01:00
bool debug_collisions_hint = false ;
2022-06-15 23:24:06 +02:00
bool debug_paths_hint = false ;
2020-12-11 15:54:03 +01:00
bool debug_navigation_hint = false ;
2017-04-07 16:17:16 +02:00
# endif
2021-02-19 13:57:41 +01:00
bool paused = false ;
2020-12-11 15:54:03 +01:00
int root_lock = 0 ;
2014-02-10 02:10:30 +01:00
2022-05-13 15:04:37 +02:00
HashMap < StringName , Group > group_map ;
2020-12-11 15:54:03 +01:00
bool _quit = false ;
bool initialized = false ;
2017-12-19 22:48:30 +01:00
2020-12-11 15:54:03 +01:00
StringName tree_changed_name = " tree_changed " ;
StringName node_added_name = " node_added " ;
StringName node_removed_name = " node_removed " ;
StringName node_renamed_name = " node_renamed " ;
2014-02-10 02:10:30 +01:00
2020-12-11 15:54:03 +01:00
int64_t current_frame = 0 ;
int node_count = 0 ;
2014-02-10 02:10:30 +01:00
2014-10-12 07:13:22 +02:00
# ifdef TOOLS_ENABLED
2022-04-04 15:06:57 +02:00
Node * edited_scene_root = nullptr ;
2014-10-12 07:13:22 +02:00
# endif
2014-02-10 02:10:30 +01:00
struct UGCall {
StringName group ;
StringName call ;
2022-05-13 15:04:37 +02:00
static uint32_t hash ( const UGCall & p_val ) {
return p_val . group . hash ( ) ^ p_val . call . hash ( ) ;
}
bool operator = = ( const UGCall & p_with ) const { return group = = p_with . group & & call = = p_with . call ; }
2014-02-10 02:10:30 +01:00
bool operator < ( const UGCall & p_with ) const { return group = = p_with . group ? call < p_with . call : group < p_with . group ; }
} ;
2020-12-11 15:54:03 +01:00
// Safety for when a node is deleted while a group is being called.
int call_lock = 0 ;
2022-10-24 15:35:46 +02:00
HashSet < ObjectID > call_skip ; // Skip erased nodes. Store ID instead of pointer to avoid false positives when node is freed and a new node is allocated at the pointed address.
2014-02-10 02:10:30 +01:00
List < ObjectID > delete_queue ;
2022-05-13 15:04:37 +02:00
HashMap < UGCall , Vector < Variant > , UGCall > unique_group_calls ;
2020-12-11 15:54:03 +01:00
bool ugc_locked = false ;
2014-02-10 02:10:30 +01:00
void _flush_ugc ( ) ;
2018-07-02 07:30:40 +02:00
_FORCE_INLINE_ void _update_group_order ( Group & g , bool p_use_priority = false ) ;
2014-02-10 02:10:30 +01:00
2022-08-05 20:35:08 +02:00
TypedArray < Node > _get_nodes_in_group ( const StringName & p_group ) ;
2014-02-10 02:10:30 +01:00
2022-04-04 15:06:57 +02:00
Node * current_scene = nullptr ;
2014-02-10 02:10:30 +01:00
2015-09-20 18:03:46 +02:00
Color debug_collisions_color ;
Color debug_collision_contact_color ;
2022-06-15 23:24:06 +02:00
Color debug_paths_color ;
float debug_paths_width = 1.0f ;
2015-09-20 18:03:46 +02:00
Color debug_navigation_color ;
Color debug_navigation_disabled_color ;
2017-06-07 23:18:55 +02:00
Ref < ArrayMesh > debug_contact_mesh ;
2022-06-15 23:24:06 +02:00
Ref < Material > debug_paths_material ;
2015-09-20 18:03:46 +02:00
Ref < Material > navigation_material ;
Ref < Material > navigation_disabled_material ;
Ref < Material > collision_material ;
int collision_debug_contacts ;
2015-05-17 21:33:35 +02:00
void _change_scene ( Node * p_to ) ;
2014-02-10 02:10:30 +01:00
2020-03-17 07:33:00 +01:00
List < Ref < SceneTreeTimer > > timers ;
2020-09-05 03:05:30 +02:00
List < Ref < Tween > > tweens ;
2016-08-07 02:39:50 +02:00
2016-08-14 23:49:50 +02:00
///network///
2018-05-08 10:51:04 +02:00
Ref < MultiplayerAPI > multiplayer ;
2022-02-05 01:43:47 +01:00
HashMap < NodePath , Ref < MultiplayerAPI > > custom_multiplayers ;
2020-12-11 15:54:03 +01:00
bool multiplayer_poll = true ;
2016-08-14 23:49:50 +02:00
2015-09-20 18:03:46 +02:00
static SceneTree * singleton ;
2014-02-10 02:10:30 +01:00
friend class Node ;
2016-08-14 23:49:50 +02:00
2014-02-10 02:10:30 +01:00
void tree_changed ( ) ;
2017-10-19 02:30:27 +02:00
void node_added ( Node * p_node ) ;
2014-02-10 02:10:30 +01:00
void node_removed ( Node * p_node ) ;
2019-05-24 15:27:22 +02:00
void node_renamed ( Node * p_node ) ;
2022-09-22 15:54:15 +02:00
void process_timers ( double p_delta , bool p_physics_frame ) ;
void process_tweens ( double p_delta , bool p_physics_frame ) ;
2014-02-10 02:10:30 +01:00
2016-06-08 03:08:12 +02:00
Group * add_to_group ( const StringName & p_group , Node * p_node ) ;
2014-02-10 02:10:30 +01:00
void remove_from_group ( const StringName & p_group , Node * p_node ) ;
2018-07-02 07:30:40 +02:00
void make_group_changed ( const StringName & p_group ) ;
2014-02-10 02:10:30 +01:00
void _notify_group_pause ( const StringName & p_group , int p_notification ) ;
2022-02-22 12:15:43 +01:00
void _call_group_flags ( const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
void _call_group ( const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2017-01-14 14:03:53 +01:00
2014-02-10 02:10:30 +01:00
void _flush_delete_queue ( ) ;
2020-12-11 15:54:03 +01:00
// Optimization.
2014-02-10 02:10:30 +01:00
friend class CanvasItem ;
2020-03-26 22:49:16 +01:00
friend class Node3D ;
2014-04-10 05:18:27 +02:00
friend class Viewport ;
2014-02-10 02:10:30 +01:00
SelfList < Node > : : List xform_change_list ;
2020-02-07 02:52:05 +01:00
# ifdef DEBUG_ENABLED // No live editor in release build.
friend class LiveEditor ;
2015-08-02 17:29:37 +02:00
# endif
2016-10-27 16:50:26 +02:00
enum {
MAX_IDLE_CALLBACKS = 256
} ;
static IdleCallback idle_callbacks [ MAX_IDLE_CALLBACKS ] ;
static int idle_callback_count ;
void _call_idle_callbacks ( ) ;
2020-03-04 17:36:09 +01:00
void _main_window_focus_in ( ) ;
void _main_window_close ( ) ;
void _main_window_go_back ( ) ;
2021-08-22 17:37:22 +02:00
enum CallInputType {
CALL_INPUT_TYPE_INPUT ,
2022-01-11 14:59:52 +01:00
CALL_INPUT_TYPE_SHORTCUT_INPUT ,
2021-08-22 17:37:22 +02:00
CALL_INPUT_TYPE_UNHANDLED_INPUT ,
CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT ,
} ;
2020-03-04 17:36:09 +01:00
//used by viewport
2021-08-22 17:37:22 +02:00
void _call_input_pause ( const StringName & p_group , CallInputType p_call_type , const Ref < InputEvent > & p_input , Viewport * p_viewport ) ;
2020-03-04 17:36:09 +01:00
2014-02-10 02:10:30 +01:00
protected :
void _notification ( int p_notification ) ;
static void _bind_methods ( ) ;
public :
enum {
2019-04-04 15:34:03 +02:00
NOTIFICATION_TRANSFORM_CHANGED = 2000
2014-02-10 02:10:30 +01:00
} ;
2017-12-24 03:17:48 +01:00
enum GroupCallFlags {
2014-02-10 02:10:30 +01:00
GROUP_CALL_DEFAULT = 0 ,
GROUP_CALL_REVERSE = 1 ,
2021-08-12 23:40:13 +02:00
GROUP_CALL_DEFERRED = 2 ,
2014-02-10 02:10:30 +01:00
GROUP_CALL_UNIQUE = 4 ,
} ;
2020-03-04 02:51:12 +01:00
_FORCE_INLINE_ Window * get_root ( ) const { return root ; }
2014-02-10 02:10:30 +01:00
2022-03-09 14:58:40 +01:00
void call_group_flagsp ( uint32_t p_call_flags , const StringName & p_group , const StringName & p_function , const Variant * * p_args , int p_argcount ) ;
2017-01-14 14:03:53 +01:00
void notify_group_flags ( uint32_t p_call_flags , const StringName & p_group , int p_notification ) ;
void set_group_flags ( uint32_t p_call_flags , const StringName & p_group , const String & p_name , const Variant & p_value ) ;
2014-02-10 02:10:30 +01:00
2021-08-12 23:40:13 +02:00
// `notify_group()` is immediate by default since Godot 4.0.
2017-01-14 14:03:53 +01:00
void notify_group ( const StringName & p_group , int p_notification ) ;
2021-08-12 23:40:13 +02:00
// `set_group()` is immediate by default since Godot 4.0.
2017-01-14 14:03:53 +01:00
void set_group ( const StringName & p_group , const String & p_name , const Variant & p_value ) ;
2014-02-10 02:10:30 +01:00
2022-03-09 14:58:40 +01:00
template < typename . . . VarArgs >
2021-08-12 23:40:13 +02:00
// `call_group()` is immediate by default since Godot 4.0.
2022-03-09 14:58:40 +01:00
void call_group ( const StringName & p_group , const StringName & p_function , VarArgs . . . p_args ) {
Variant args [ sizeof . . . ( p_args ) + 1 ] = { p_args . . . , Variant ( ) } ; // +1 makes sure zero sized arrays are also supported.
const Variant * argptrs [ sizeof . . . ( p_args ) + 1 ] ;
for ( uint32_t i = 0 ; i < sizeof . . . ( p_args ) ; i + + ) {
argptrs [ i ] = & args [ i ] ;
}
2021-08-12 23:40:13 +02:00
call_group_flagsp ( GROUP_CALL_DEFAULT , p_group , p_function , sizeof . . . ( p_args ) = = 0 ? nullptr : ( const Variant * * ) argptrs , sizeof . . . ( p_args ) ) ;
2022-03-09 14:58:40 +01:00
}
template < typename . . . VarArgs >
void call_group_flags ( uint32_t p_flags , const StringName & p_group , const StringName & p_function , VarArgs . . . p_args ) {
Variant args [ sizeof . . . ( p_args ) + 1 ] = { p_args . . . , Variant ( ) } ; // +1 makes sure zero sized arrays are also supported.
const Variant * argptrs [ sizeof . . . ( p_args ) + 1 ] ;
for ( uint32_t i = 0 ; i < sizeof . . . ( p_args ) ; i + + ) {
argptrs [ i ] = & args [ i ] ;
}
call_group_flagsp ( p_flags , p_group , p_function , sizeof . . . ( p_args ) = = 0 ? nullptr : ( const Variant * * ) argptrs , sizeof . . . ( p_args ) ) ;
}
2017-10-30 19:43:19 +01:00
void flush_transform_notifications ( ) ;
2020-12-22 10:50:29 +01:00
virtual void initialize ( ) override ;
2014-02-10 02:10:30 +01:00
2021-05-21 07:23:35 +02:00
virtual bool physics_process ( double p_time ) override ;
virtual bool process ( double p_time ) override ;
2014-02-10 02:10:30 +01:00
2020-12-22 10:50:29 +01:00
virtual void finalize ( ) override ;
2014-02-10 02:10:30 +01:00
2022-05-14 12:18:26 +02:00
bool is_auto_accept_quit ( ) const ;
2014-02-10 02:10:30 +01:00
void set_auto_accept_quit ( bool p_enable ) ;
2022-05-14 12:18:26 +02:00
bool is_quit_on_go_back ( ) const ;
2017-01-11 20:34:32 +01:00
void set_quit_on_go_back ( bool p_enable ) ;
2014-02-10 02:10:30 +01:00
2020-06-04 22:03:45 +02:00
void quit ( int p_exit_code = EXIT_SUCCESS ) ;
2014-02-10 02:10:30 +01:00
2021-05-21 07:23:35 +02:00
_FORCE_INLINE_ double get_physics_process_time ( ) const { return physics_process_time ; }
_FORCE_INLINE_ double get_process_time ( ) const { return process_time ; }
2014-02-10 02:10:30 +01:00
2017-04-07 16:17:16 +02:00
# ifdef TOOLS_ENABLED
2016-01-02 21:18:45 +01:00
bool is_node_being_edited ( const Node * p_node ) const ;
2017-04-07 16:17:16 +02:00
# else
bool is_node_being_edited ( const Node * p_node ) const { return false ; }
# endif
2016-01-02 21:18:45 +01:00
2014-02-10 02:10:30 +01:00
void set_pause ( bool p_enabled ) ;
bool is_paused ( ) const ;
2017-04-07 16:17:16 +02:00
# ifdef DEBUG_ENABLED
2015-09-19 04:10:58 +02:00
void set_debug_collisions_hint ( bool p_enabled ) ;
bool is_debugging_collisions_hint ( ) const ;
2022-06-15 23:24:06 +02:00
void set_debug_paths_hint ( bool p_enabled ) ;
bool is_debugging_paths_hint ( ) const ;
2015-09-20 18:03:46 +02:00
void set_debug_navigation_hint ( bool p_enabled ) ;
bool is_debugging_navigation_hint ( ) const ;
2017-04-07 16:17:16 +02:00
# else
void set_debug_collisions_hint ( bool p_enabled ) { }
bool is_debugging_collisions_hint ( ) const { return false ; }
2022-06-15 23:24:06 +02:00
void set_debug_paths_hint ( bool p_enabled ) { }
bool is_debugging_paths_hint ( ) const { return false ; }
2017-04-07 16:17:16 +02:00
void set_debug_navigation_hint ( bool p_enabled ) { }
bool is_debugging_navigation_hint ( ) const { return false ; }
# endif
2015-09-20 18:03:46 +02:00
void set_debug_collisions_color ( const Color & p_color ) ;
Color get_debug_collisions_color ( ) const ;
void set_debug_collision_contact_color ( const Color & p_color ) ;
Color get_debug_collision_contact_color ( ) const ;
2022-06-15 23:24:06 +02:00
void set_debug_paths_color ( const Color & p_color ) ;
Color get_debug_paths_color ( ) const ;
void set_debug_paths_width ( float p_width ) ;
float get_debug_paths_width ( ) const ;
Ref < Material > get_debug_paths_material ( ) ;
2015-09-20 18:03:46 +02:00
Ref < Material > get_debug_collision_material ( ) ;
2017-06-07 23:18:55 +02:00
Ref < ArrayMesh > get_debug_contact_mesh ( ) ;
2015-09-20 18:03:46 +02:00
int get_collision_debug_contact_count ( ) { return collision_debug_contacts ; }
2014-02-10 02:10:30 +01:00
int64_t get_frame ( ) const ;
int get_node_count ( ) const ;
void queue_delete ( Object * p_object ) ;
void get_nodes_in_group ( const StringName & p_group , List < Node * > * p_list ) ;
2021-02-22 14:54:12 +01:00
Node * get_first_node_in_group ( const StringName & p_group ) ;
2016-01-02 21:18:45 +01:00
bool has_group ( const StringName & p_identifier ) const ;
2014-02-10 02:10:30 +01:00
2017-12-06 21:36:34 +01:00
//void change_scene(const String& p_path);
//Node *get_loaded_scene();
2014-10-28 02:54:32 +01:00
2014-10-12 07:13:22 +02:00
void set_edited_scene_root ( Node * p_node ) ;
Node * get_edited_scene_root ( ) const ;
2014-04-15 03:43:44 +02:00
2015-05-17 21:33:35 +02:00
void set_current_scene ( Node * p_scene ) ;
Node * get_current_scene ( ) const ;
2022-07-28 23:25:57 +02:00
Error change_scene_to_file ( const String & p_path ) ;
Error change_scene_to_packed ( const Ref < PackedScene > & p_scene ) ;
2015-05-17 21:33:35 +02:00
Error reload_current_scene ( ) ;
2022-07-15 08:21:51 +02:00
Ref < SceneTreeTimer > create_timer ( double p_delay_sec , bool p_process_always = true , bool p_process_in_physics = false , bool p_ignore_time_scale = false ) ;
2020-09-05 03:05:30 +02:00
Ref < Tween > create_tween ( ) ;
2022-08-05 20:35:08 +02:00
TypedArray < Tween > get_processed_tweens ( ) ;
2016-08-07 02:39:50 +02:00
2015-05-17 21:33:35 +02:00
//used by Main::start, don't use otherwise
void add_current_scene ( Node * p_current ) ;
2015-09-20 18:03:46 +02:00
static SceneTree * get_singleton ( ) { return singleton ; }
2015-05-17 21:33:35 +02:00
2020-07-10 12:34:39 +02:00
void get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const override ;
2015-05-17 21:33:35 +02:00
2016-08-14 23:49:50 +02:00
//network API
2022-02-05 01:43:47 +01:00
Ref < MultiplayerAPI > get_multiplayer ( const NodePath & p_for_path = NodePath ( ) ) const ;
void set_multiplayer ( Ref < MultiplayerAPI > p_multiplayer , const NodePath & p_root_path = NodePath ( ) ) ;
2018-06-02 14:32:30 +02:00
void set_multiplayer_poll_enabled ( bool p_enabled ) ;
bool is_multiplayer_poll_enabled ( ) const ;
2016-08-14 23:49:50 +02:00
2016-10-27 16:50:26 +02:00
static void add_idle_callback ( IdleCallback p_callback ) ;
2019-06-25 03:24:07 +02:00
//default texture settings
2014-11-06 01:20:42 +01:00
SceneTree ( ) ;
~ SceneTree ( ) ;
2014-02-10 02:10:30 +01:00
} ;
2017-12-24 03:17:48 +01:00
VARIANT_ENUM_CAST ( SceneTree : : GroupCallFlags ) ;
2014-04-15 03:43:44 +02:00
2020-09-10 16:04:30 +02:00
# endif // SCENE_TREE_H