2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* core_bind.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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
2014-02-10 02:10:30 +01:00
# include "core_bind.h"
2024-08-27 05:12:10 +02:00
# include "core_bind.compat.inc"
2017-04-28 18:29:15 +02:00
2020-11-07 23:33:38 +01:00
# include "core/config/project_settings.h"
2019-07-11 15:21:47 +02:00
# include "core/crypto/crypto_core.h"
2020-05-18 16:55:49 +02:00
# include "core/debugger/engine_debugger.h"
2024-01-02 20:07:10 +01:00
# include "core/debugger/script_debugger.h"
2018-09-11 18:13:45 +02:00
# include "core/io/file_access_compressed.h"
# include "core/io/file_access_encrypted.h"
# include "core/io/marshalls.h"
2020-05-25 19:20:45 +02:00
# include "core/math/geometry_2d.h"
# include "core/math/geometry_3d.h"
2018-09-11 18:13:45 +02:00
# include "core/os/keyboard.h"
2023-06-08 11:33:35 +02:00
# include "core/os/thread_safe.h"
2022-08-05 03:41:48 +02:00
# include "core/variant/typed_array.h"
2016-03-04 07:31:27 +01:00
2021-08-13 16:46:14 +02:00
namespace core_bind {
2020-05-12 17:01:17 +02:00
2021-08-13 16:46:14 +02:00
////// ResourceLoader //////
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ResourceLoader * ResourceLoader : : singleton = nullptr ;
2021-11-07 18:47:53 +01:00
Error ResourceLoader : : load_threaded_request ( const String & p_path , const String & p_type_hint , bool p_use_sub_threads , CacheMode p_cache_mode ) {
return : : ResourceLoader : : load_threaded_request ( p_path , p_type_hint , p_use_sub_threads , ResourceFormatLoader : : CacheMode ( p_cache_mode ) ) ;
2020-02-28 12:27:04 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
ResourceLoader : : ThreadLoadStatus ResourceLoader : : load_threaded_get_status ( const String & p_path , Array r_progress ) {
2020-02-28 12:27:04 +01:00
float progress = 0 ;
2021-08-13 16:46:14 +02:00
: : ResourceLoader : : ThreadLoadStatus tls = : : ResourceLoader : : load_threaded_get_status ( p_path , & progress ) ;
2020-02-28 12:27:04 +01:00
r_progress . resize ( 1 ) ;
r_progress [ 0 ] = progress ;
return ( ThreadLoadStatus ) tls ;
}
2020-05-14 14:29:06 +02:00
2022-05-03 01:43:50 +02:00
Ref < Resource > ResourceLoader : : load_threaded_get ( const String & p_path ) {
2020-02-28 12:27:04 +01:00
Error error ;
2022-05-03 01:43:50 +02:00
Ref < Resource > res = : : ResourceLoader : : load_threaded_get ( p_path , & error ) ;
2020-02-28 12:27:04 +01:00
return res ;
2014-02-10 02:10:30 +01:00
}
2022-05-03 01:43:50 +02:00
Ref < Resource > ResourceLoader : : load ( const String & p_path , const String & p_type_hint , CacheMode p_cache_mode ) {
2018-01-05 21:35:48 +01:00
Error err = OK ;
2022-05-03 01:43:50 +02:00
Ref < Resource > ret = : : ResourceLoader : : load ( p_path , p_type_hint , ResourceFormatLoader : : CacheMode ( p_cache_mode ) , & err ) ;
2018-01-05 21:35:48 +01:00
2019-08-15 04:57:49 +02:00
ERR_FAIL_COND_V_MSG ( err ! = OK , ret , " Error loading resource: ' " + p_path + " '. " ) ;
2014-02-10 02:10:30 +01:00
return ret ;
}
2021-08-13 16:46:14 +02:00
Vector < String > ResourceLoader : : get_recognized_extensions_for_type ( const String & p_type ) {
2014-02-10 02:10:30 +01:00
List < String > exts ;
2021-08-13 16:46:14 +02:00
: : ResourceLoader : : get_recognized_extensions_for_type ( p_type , & exts ) ;
2020-02-17 22:06:54 +01:00
Vector < String > ret ;
2021-07-24 15:46:25 +02:00
for ( const String & E : exts ) {
2021-07-16 05:45:57 +02:00
ret . push_back ( E ) ;
2014-02-10 02:10:30 +01:00
}
return ret ;
}
2022-05-15 15:42:27 +02:00
void ResourceLoader : : add_resource_format_loader ( Ref < ResourceFormatLoader > p_format_loader , bool p_at_front ) {
: : ResourceLoader : : add_resource_format_loader ( p_format_loader , p_at_front ) ;
}
void ResourceLoader : : remove_resource_format_loader ( Ref < ResourceFormatLoader > p_format_loader ) {
: : ResourceLoader : : remove_resource_format_loader ( p_format_loader ) ;
}
2021-08-13 16:46:14 +02:00
void ResourceLoader : : set_abort_on_missing_resources ( bool p_abort ) {
: : ResourceLoader : : set_abort_on_missing_resources ( p_abort ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
PackedStringArray ResourceLoader : : get_dependencies ( const String & p_path ) {
2014-02-10 02:10:30 +01:00
List < String > deps ;
2021-08-13 16:46:14 +02:00
: : ResourceLoader : : get_dependencies ( p_path , & deps ) ;
2014-02-10 02:10:30 +01:00
2020-02-17 22:06:54 +01:00
PackedStringArray ret ;
2021-07-24 15:46:25 +02:00
for ( const String & E : deps ) {
2021-07-16 05:45:57 +02:00
ret . push_back ( E ) ;
2014-02-10 02:10:30 +01:00
}
return ret ;
2020-05-19 15:46:49 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
bool ResourceLoader : : has_cached ( const String & p_path ) {
2017-07-19 22:00:46 +02:00
String local_path = ProjectSettings : : get_singleton ( ) - > localize_path ( p_path ) ;
2014-02-10 02:10:30 +01:00
return ResourceCache : : has ( local_path ) ;
2018-08-10 20:57:43 +02:00
}
2021-08-13 16:46:14 +02:00
bool ResourceLoader : : exists ( const String & p_path , const String & p_type_hint ) {
return : : ResourceLoader : : exists ( p_path , p_type_hint ) ;
2018-08-10 20:57:43 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ResourceUID : : ID ResourceLoader : : get_resource_uid ( const String & p_path ) {
return : : ResourceLoader : : get_resource_uid ( p_path ) ;
2021-07-30 18:35:19 +02:00
}
2021-08-13 16:46:14 +02:00
void ResourceLoader : : _bind_methods ( ) {
2021-11-07 18:47:53 +01:00
ClassDB : : bind_method ( D_METHOD ( " load_threaded_request " , " path " , " type_hint " , " use_sub_threads " , " cache_mode " ) , & ResourceLoader : : load_threaded_request , DEFVAL ( " " ) , DEFVAL ( false ) , DEFVAL ( CACHE_MODE_REUSE ) ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " load_threaded_get_status " , " path " , " progress " ) , & ResourceLoader : : load_threaded_get_status , DEFVAL ( Array ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " load_threaded_get " , " path " ) , & ResourceLoader : : load_threaded_get ) ;
2020-02-28 12:27:04 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " load " , " path " , " type_hint " , " cache_mode " ) , & ResourceLoader : : load , DEFVAL ( " " ) , DEFVAL ( CACHE_MODE_REUSE ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_recognized_extensions_for_type " , " type " ) , & ResourceLoader : : get_recognized_extensions_for_type ) ;
2022-05-15 15:42:27 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_resource_format_loader " , " format_loader " , " at_front " ) , & ResourceLoader : : add_resource_format_loader , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_resource_format_loader " , " format_loader " ) , & ResourceLoader : : remove_resource_format_loader ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_abort_on_missing_resources " , " abort " ) , & ResourceLoader : : set_abort_on_missing_resources ) ;
ClassDB : : bind_method ( D_METHOD ( " get_dependencies " , " path " ) , & ResourceLoader : : get_dependencies ) ;
ClassDB : : bind_method ( D_METHOD ( " has_cached " , " path " ) , & ResourceLoader : : has_cached ) ;
ClassDB : : bind_method ( D_METHOD ( " exists " , " path " , " type_hint " ) , & ResourceLoader : : exists , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_resource_uid " , " path " ) , & ResourceLoader : : get_resource_uid ) ;
2020-02-28 12:27:04 +01:00
BIND_ENUM_CONSTANT ( THREAD_LOAD_INVALID_RESOURCE ) ;
BIND_ENUM_CONSTANT ( THREAD_LOAD_IN_PROGRESS ) ;
BIND_ENUM_CONSTANT ( THREAD_LOAD_FAILED ) ;
BIND_ENUM_CONSTANT ( THREAD_LOAD_LOADED ) ;
2021-02-11 18:18:45 +01:00
BIND_ENUM_CONSTANT ( CACHE_MODE_IGNORE ) ;
BIND_ENUM_CONSTANT ( CACHE_MODE_REUSE ) ;
BIND_ENUM_CONSTANT ( CACHE_MODE_REPLACE ) ;
2024-02-22 12:53:19 +01:00
BIND_ENUM_CONSTANT ( CACHE_MODE_IGNORE_DEEP ) ;
BIND_ENUM_CONSTANT ( CACHE_MODE_REPLACE_DEEP ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
////// ResourceSaver //////
2014-02-10 02:10:30 +01:00
2022-06-03 01:33:42 +02:00
Error ResourceSaver : : save ( const Ref < Resource > & p_resource , const String & p_path , BitField < SaverFlags > p_flags ) {
return : : ResourceSaver : : save ( p_resource , p_path , p_flags ) ;
2014-02-10 02:10:30 +01:00
}
2022-05-03 01:43:50 +02:00
Vector < String > ResourceSaver : : get_recognized_extensions ( const Ref < Resource > & p_resource ) {
2014-02-10 02:10:30 +01:00
List < String > exts ;
2021-08-13 16:46:14 +02:00
: : ResourceSaver : : get_recognized_extensions ( p_resource , & exts ) ;
2020-02-17 22:06:54 +01:00
Vector < String > ret ;
2021-07-24 15:46:25 +02:00
for ( const String & E : exts ) {
2021-07-16 05:45:57 +02:00
ret . push_back ( E ) ;
2014-02-10 02:10:30 +01:00
}
return ret ;
}
2022-05-15 15:42:27 +02:00
void ResourceSaver : : add_resource_format_saver ( Ref < ResourceFormatSaver > p_format_saver , bool p_at_front ) {
: : ResourceSaver : : add_resource_format_saver ( p_format_saver , p_at_front ) ;
}
void ResourceSaver : : remove_resource_format_saver ( Ref < ResourceFormatSaver > p_format_saver ) {
: : ResourceSaver : : remove_resource_format_saver ( p_format_saver ) ;
}
2021-08-13 16:46:14 +02:00
ResourceSaver * ResourceSaver : : singleton = nullptr ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
void ResourceSaver : : _bind_methods ( ) {
2022-06-03 01:33:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " save " , " resource " , " path " , " flags " ) , & ResourceSaver : : save , DEFVAL ( " " ) , DEFVAL ( ( uint32_t ) FLAG_NONE ) ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_recognized_extensions " , " type " ) , & ResourceSaver : : get_recognized_extensions ) ;
2022-05-15 15:42:27 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_resource_format_saver " , " format_saver " , " at_front " ) , & ResourceSaver : : add_resource_format_saver , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_resource_format_saver " , " format_saver " ) , & ResourceSaver : : remove_resource_format_saver ) ;
2014-05-24 06:35:47 +02:00
2022-06-24 11:16:37 +02:00
BIND_BITFIELD_FLAG ( FLAG_NONE ) ;
BIND_BITFIELD_FLAG ( FLAG_RELATIVE_PATHS ) ;
BIND_BITFIELD_FLAG ( FLAG_BUNDLE_RESOURCES ) ;
BIND_BITFIELD_FLAG ( FLAG_CHANGE_PATH ) ;
BIND_BITFIELD_FLAG ( FLAG_OMIT_EDITOR_PROPERTIES ) ;
BIND_BITFIELD_FLAG ( FLAG_SAVE_BIG_ENDIAN ) ;
BIND_BITFIELD_FLAG ( FLAG_COMPRESS ) ;
BIND_BITFIELD_FLAG ( FLAG_REPLACE_SUBRESOURCE_PATHS ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
////// OS //////
2014-02-10 02:10:30 +01:00
2024-06-14 02:30:32 +02:00
PackedByteArray OS : : get_entropy ( int p_bytes ) {
PackedByteArray pba ;
pba . resize ( p_bytes ) ;
Error err = : : OS : : get_singleton ( ) - > get_entropy ( pba . ptrw ( ) , p_bytes ) ;
ERR_FAIL_COND_V ( err ! = OK , PackedByteArray ( ) ) ;
return pba ;
}
2024-06-10 15:35:50 +02:00
String OS : : get_system_ca_certificates ( ) {
return : : OS : : get_singleton ( ) - > get_system_ca_certificates ( ) ;
}
2021-08-13 16:46:14 +02:00
PackedStringArray OS : : get_connected_midi_inputs ( ) {
return : : OS : : get_singleton ( ) - > get_connected_midi_inputs ( ) ;
2018-07-14 14:11:28 +02:00
}
2021-08-13 16:46:14 +02:00
void OS : : open_midi_inputs ( ) {
: : OS : : get_singleton ( ) - > open_midi_inputs ( ) ;
2018-08-04 02:17:33 +02:00
}
2021-08-13 16:46:14 +02:00
void OS : : close_midi_inputs ( ) {
: : OS : : get_singleton ( ) - > close_midi_inputs ( ) ;
2018-08-04 02:17:33 +02:00
}
2021-08-13 16:46:14 +02:00
void OS : : set_use_file_access_save_and_swap ( bool p_enable ) {
2014-08-02 03:10:38 +02:00
FileAccess : : set_backup_save ( p_enable ) ;
}
2021-08-13 16:46:14 +02:00
void OS : : set_low_processor_usage_mode ( bool p_enabled ) {
: : OS : : get_singleton ( ) - > set_low_processor_usage_mode ( p_enabled ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool OS : : is_in_low_processor_usage_mode ( ) const {
return : : OS : : get_singleton ( ) - > is_in_low_processor_usage_mode ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
void OS : : set_low_processor_usage_mode_sleep_usec ( int p_usec ) {
: : OS : : get_singleton ( ) - > set_low_processor_usage_mode_sleep_usec ( p_usec ) ;
2019-11-08 18:36:06 +01:00
}
2021-08-13 16:46:14 +02:00
int OS : : get_low_processor_usage_mode_sleep_usec ( ) const {
return : : OS : : get_singleton ( ) - > get_low_processor_usage_mode_sleep_usec ( ) ;
2019-11-08 18:36:06 +01:00
}
2021-09-01 16:47:12 +02:00
void OS : : set_delta_smoothing ( bool p_enabled ) {
: : OS : : get_singleton ( ) - > set_delta_smoothing ( p_enabled ) ;
}
bool OS : : is_delta_smoothing_enabled ( ) const {
return : : OS : : get_singleton ( ) - > is_delta_smoothing_enabled ( ) ;
}
2021-08-13 16:46:14 +02:00
void OS : : alert ( const String & p_alert , const String & p_title ) {
: : OS : : get_singleton ( ) - > alert ( p_alert , p_title ) ;
2021-07-22 18:23:48 +02:00
}
2021-12-03 20:36:47 +01:00
void OS : : crash ( const String & p_message ) {
CRASH_NOW_MSG ( p_message ) ;
}
2022-07-08 14:38:30 +02:00
Vector < String > OS : : get_system_fonts ( ) const {
return : : OS : : get_singleton ( ) - > get_system_fonts ( ) ;
}
2022-11-21 14:04:01 +01:00
String OS : : get_system_font_path ( const String & p_font_name , int p_weight , int p_stretch , bool p_italic ) const {
return : : OS : : get_singleton ( ) - > get_system_font_path ( p_font_name , p_weight , p_stretch , p_italic ) ;
}
Vector < String > OS : : get_system_font_path_for_text ( const String & p_font_name , const String & p_text , const String & p_locale , const String & p_script , int p_weight , int p_stretch , bool p_italic ) const {
return : : OS : : get_singleton ( ) - > get_system_font_path_for_text ( p_font_name , p_text , p_locale , p_script , p_weight , p_stretch , p_italic ) ;
2022-07-08 14:38:30 +02:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_executable_path ( ) const {
return : : OS : : get_singleton ( ) - > get_executable_path ( ) ;
2014-02-10 02:10:30 +01:00
}
2024-01-09 02:36:19 +01:00
Error OS : : shell_open ( const String & p_uri ) {
2020-04-28 19:25:02 +02:00
if ( p_uri . begins_with ( " res:// " ) ) {
WARN_PRINT ( " Attempting to open an URL with the \" res:// \" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_open()`. " ) ;
} else if ( p_uri . begins_with ( " user:// " ) ) {
WARN_PRINT ( " Attempting to open an URL with the \" user:// \" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_open()`. " ) ;
}
2021-08-13 16:46:14 +02:00
return : : OS : : get_singleton ( ) - > shell_open ( p_uri ) ;
2020-05-19 15:46:49 +02:00
}
2014-02-10 02:10:30 +01:00
2024-01-09 02:36:19 +01:00
Error OS : : shell_show_in_file_manager ( const String & p_path , bool p_open_folder ) {
2022-12-07 04:33:35 +01:00
if ( p_path . begins_with ( " res:// " ) ) {
WARN_PRINT ( " Attempting to explore file path with the \" res:// \" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_show_in_file_manager()`. " ) ;
} else if ( p_path . begins_with ( " user:// " ) ) {
WARN_PRINT ( " Attempting to explore file path with the \" user:// \" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_show_in_file_manager()`. " ) ;
}
return : : OS : : get_singleton ( ) - > shell_show_in_file_manager ( p_path , p_open_folder ) ;
}
2022-12-29 21:06:11 +01:00
String OS : : read_string_from_stdin ( ) {
return : : OS : : get_singleton ( ) - > get_stdin_string ( ) ;
2022-09-13 18:37:11 +02:00
}
2021-12-16 14:00:55 +01:00
int OS : : execute ( const String & p_path , const Vector < String > & p_arguments , Array r_output , bool p_read_stderr , bool p_open_console ) {
2014-02-10 02:10:30 +01:00
List < String > args ;
2023-10-19 13:35:10 +02:00
for ( const String & arg : p_arguments ) {
args . push_back ( arg ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
String pipe ;
2020-12-18 19:49:13 +01:00
int exitcode = 0 ;
2021-12-16 14:00:55 +01:00
Error err = : : OS : : get_singleton ( ) - > execute ( p_path , args , & pipe , & exitcode , p_read_stderr , nullptr , p_open_console ) ;
2020-12-18 19:49:13 +01:00
r_output . push_back ( pipe ) ;
if ( err ! = OK ) {
return - 1 ;
}
return exitcode ;
}
2023-10-19 13:35:10 +02:00
Dictionary OS : : execute_with_pipe ( const String & p_path , const Vector < String > & p_arguments ) {
List < String > args ;
for ( const String & arg : p_arguments ) {
args . push_back ( arg ) ;
}
return : : OS : : get_singleton ( ) - > execute_with_pipe ( p_path , args ) ;
}
2021-11-01 10:12:52 +01:00
int OS : : create_instance ( const Vector < String > & p_arguments ) {
List < String > args ;
2023-10-19 13:35:10 +02:00
for ( const String & arg : p_arguments ) {
args . push_back ( arg ) ;
2021-11-01 10:12:52 +01:00
}
: : OS : : ProcessID pid = 0 ;
Error err = : : OS : : get_singleton ( ) - > create_instance ( args , & pid ) ;
if ( err ! = OK ) {
return - 1 ;
}
return pid ;
}
2021-12-16 14:00:55 +01:00
int OS : : create_process ( const String & p_path , const Vector < String > & p_arguments , bool p_open_console ) {
2020-12-18 19:49:13 +01:00
List < String > args ;
2023-10-19 13:35:10 +02:00
for ( const String & arg : p_arguments ) {
args . push_back ( arg ) ;
2020-12-18 19:49:13 +01:00
}
2021-08-13 16:46:14 +02:00
: : OS : : ProcessID pid = 0 ;
2021-12-16 14:00:55 +01:00
Error err = : : OS : : get_singleton ( ) - > create_process ( p_path , args , & pid , p_open_console ) ;
2020-05-14 16:41:43 +02:00
if ( err ! = OK ) {
2014-02-10 02:10:30 +01:00
return - 1 ;
2020-05-14 16:41:43 +02:00
}
2020-12-18 19:49:13 +01:00
return pid ;
2014-02-10 02:10:30 +01:00
}
2018-05-30 12:18:01 +02:00
2021-08-13 16:46:14 +02:00
Error OS : : kill ( int p_pid ) {
return : : OS : : get_singleton ( ) - > kill ( p_pid ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 05:36:23 +02:00
bool OS : : is_process_running ( int p_pid ) const {
return : : OS : : get_singleton ( ) - > is_process_running ( p_pid ) ;
}
2024-04-07 20:19:46 +02:00
int OS : : get_process_exit_code ( int p_pid ) const {
return : : OS : : get_singleton ( ) - > get_process_exit_code ( p_pid ) ;
}
2021-08-13 16:46:14 +02:00
int OS : : get_process_id ( ) const {
return : : OS : : get_singleton ( ) - > get_process_id ( ) ;
2020-05-19 15:46:49 +02:00
}
2014-04-05 17:39:30 +02:00
2021-08-13 16:46:14 +02:00
bool OS : : has_environment ( const String & p_var ) const {
return : : OS : : get_singleton ( ) - > has_environment ( p_var ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
String OS : : get_environment ( const String & p_var ) const {
return : : OS : : get_singleton ( ) - > get_environment ( p_var ) ;
2014-02-10 02:10:30 +01:00
}
2023-01-16 14:26:14 +01:00
void OS : : set_environment ( const String & p_var , const String & p_value ) const {
: : OS : : get_singleton ( ) - > set_environment ( p_var , p_value ) ;
}
void OS : : unset_environment ( const String & p_var ) const {
: : OS : : get_singleton ( ) - > unset_environment ( p_var ) ;
2021-02-25 12:20:13 +01:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_name ( ) const {
return : : OS : : get_singleton ( ) - > get_name ( ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2022-09-16 11:14:14 +02:00
String OS : : get_distribution_name ( ) const {
return : : OS : : get_singleton ( ) - > get_distribution_name ( ) ;
}
String OS : : get_version ( ) const {
return : : OS : : get_singleton ( ) - > get_version ( ) ;
}
2022-10-11 12:39:41 +02:00
Vector < String > OS : : get_video_adapter_driver_info ( ) const {
return : : OS : : get_singleton ( ) - > get_video_adapter_driver_info ( ) ;
}
2021-08-13 16:46:14 +02:00
Vector < String > OS : : get_cmdline_args ( ) {
List < String > cmdline = : : OS : : get_singleton ( ) - > get_cmdline_args ( ) ;
2014-02-10 02:10:30 +01:00
Vector < String > cmdlinev ;
2021-07-24 15:46:25 +02:00
for ( const String & E : cmdline ) {
2021-07-16 05:45:57 +02:00
cmdlinev . push_back ( E ) ;
2014-02-10 02:10:30 +01:00
}
return cmdlinev ;
}
2022-07-29 15:30:52 +02:00
Vector < String > OS : : get_cmdline_user_args ( ) {
List < String > cmdline = : : OS : : get_singleton ( ) - > get_cmdline_user_args ( ) ;
Vector < String > cmdlinev ;
for ( const String & E : cmdline ) {
cmdlinev . push_back ( E ) ;
}
return cmdlinev ;
}
2021-05-12 03:12:59 +02:00
void OS : : set_restart_on_exit ( bool p_restart , const Vector < String > & p_restart_arguments ) {
List < String > args_list ;
for ( const String & restart_argument : p_restart_arguments ) {
args_list . push_back ( restart_argument ) ;
}
: : OS : : get_singleton ( ) - > set_restart_on_exit ( p_restart , args_list ) ;
}
bool OS : : is_restart_on_exit_set ( ) const {
return : : OS : : get_singleton ( ) - > is_restart_on_exit_set ( ) ;
}
Vector < String > OS : : get_restart_on_exit_arguments ( ) const {
List < String > args = : : OS : : get_singleton ( ) - > get_restart_on_exit_arguments ( ) ;
Vector < String > args_vector ;
for ( List < String > : : Element * E = args . front ( ) ; E ; E = E - > next ( ) ) {
args_vector . push_back ( E - > get ( ) ) ;
}
return args_vector ;
}
2021-08-13 16:46:14 +02:00
String OS : : get_locale ( ) const {
return : : OS : : get_singleton ( ) - > get_locale ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-09-16 09:27:56 +02:00
String OS : : get_locale_language ( ) const {
return : : OS : : get_singleton ( ) - > get_locale_language ( ) ;
}
2021-08-13 16:46:14 +02:00
String OS : : get_model_name ( ) const {
return : : OS : : get_singleton ( ) - > get_model_name ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
Error OS : : set_thread_name ( const String & p_name ) {
return : : Thread : : set_name ( p_name ) ;
2020-05-19 15:46:49 +02:00
}
2016-02-01 00:22:38 +01:00
2021-08-13 16:46:14 +02:00
: : Thread : : ID OS : : get_thread_caller_id ( ) const {
return : : Thread : : get_caller_id ( ) ;
2020-12-27 16:49:46 +01:00
} ;
2021-11-13 01:10:33 +01:00
: : Thread : : ID OS : : get_main_thread_id ( ) const {
return : : Thread : : get_main_id ( ) ;
} ;
2021-08-13 16:46:14 +02:00
bool OS : : has_feature ( const String & p_feature ) const {
2023-05-05 15:23:25 +02:00
const bool * value_ptr = feature_cache . getptr ( p_feature ) ;
if ( value_ptr ) {
return * value_ptr ;
} else {
const bool has = : : OS : : get_singleton ( ) - > has_feature ( p_feature ) ;
feature_cache [ p_feature ] = has ;
return has ;
}
2017-10-02 21:38:39 +02:00
}
2021-03-30 14:42:50 +02:00
bool OS : : is_sandboxed ( ) const {
return : : OS : : get_singleton ( ) - > is_sandboxed ( ) ;
}
2021-08-13 16:46:14 +02:00
uint64_t OS : : get_static_memory_usage ( ) const {
return : : OS : : get_singleton ( ) - > get_static_memory_usage ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
uint64_t OS : : get_static_memory_peak_usage ( ) const {
return : : OS : : get_singleton ( ) - > get_static_memory_peak_usage ( ) ;
2014-02-10 02:10:30 +01:00
}
2023-04-03 10:46:29 +02:00
Dictionary OS : : get_memory_info ( ) const {
return : : OS : : get_singleton ( ) - > get_memory_info ( ) ;
}
2021-02-18 21:59:09 +01:00
/** This method uses a signed argument for better error reporting as it's used from the scripting API. */
2021-08-13 16:46:14 +02:00
void OS : : delay_usec ( int p_usec ) const {
2021-02-18 21:59:09 +01:00
ERR_FAIL_COND_MSG (
p_usec < 0 ,
vformat ( " Can't sleep for %d microseconds. The delay provided must be greater than or equal to 0 microseconds. " , p_usec ) ) ;
2021-08-13 16:46:14 +02:00
: : OS : : get_singleton ( ) - > delay_usec ( p_usec ) ;
2014-02-10 02:10:30 +01:00
}
2021-02-18 21:59:09 +01:00
/** This method uses a signed argument for better error reporting as it's used from the scripting API. */
2021-08-13 16:46:14 +02:00
void OS : : delay_msec ( int p_msec ) const {
2021-02-18 21:59:09 +01:00
ERR_FAIL_COND_MSG (
p_msec < 0 ,
vformat ( " Can't sleep for %d milliseconds. The delay provided must be greater than or equal to 0 milliseconds. " , p_msec ) ) ;
2021-08-13 16:46:14 +02:00
: : OS : : get_singleton ( ) - > delay_usec ( int64_t ( p_msec ) * 1000 ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
bool OS : : is_userfs_persistent ( ) const {
return : : OS : : get_singleton ( ) - > is_userfs_persistent ( ) ;
2017-10-02 16:09:24 +02:00
}
2021-08-13 16:46:14 +02:00
int OS : : get_processor_count ( ) const {
return : : OS : : get_singleton ( ) - > get_processor_count ( ) ;
2014-02-10 02:10:30 +01:00
}
2020-12-27 01:50:21 +01:00
String OS : : get_processor_name ( ) const {
return : : OS : : get_singleton ( ) - > get_processor_name ( ) ;
}
2021-08-13 16:46:14 +02:00
bool OS : : is_stdout_verbose ( ) const {
return : : OS : : get_singleton ( ) - > is_stdout_verbose ( ) ;
2014-02-10 02:10:30 +01:00
}
2022-04-26 23:52:20 +02:00
Error OS : : move_to_trash ( const String & p_path ) const {
return : : OS : : get_singleton ( ) - > move_to_trash ( p_path ) ;
}
2021-08-13 16:46:14 +02:00
String OS : : get_user_data_dir ( ) const {
return : : OS : : get_singleton ( ) - > get_user_data_dir ( ) ;
2020-05-19 15:46:49 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
String OS : : get_config_dir ( ) const {
2021-05-07 19:36:32 +02:00
// Exposed as `get_config_dir()` instead of `get_config_path()` for consistency with other exposed OS methods.
2021-08-13 16:46:14 +02:00
return : : OS : : get_singleton ( ) - > get_config_path ( ) ;
2021-05-07 19:36:32 +02:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_data_dir ( ) const {
2021-05-07 19:36:32 +02:00
// Exposed as `get_data_dir()` instead of `get_data_path()` for consistency with other exposed OS methods.
2021-08-13 16:46:14 +02:00
return : : OS : : get_singleton ( ) - > get_data_path ( ) ;
2021-05-07 19:36:32 +02:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_cache_dir ( ) const {
2021-05-07 19:36:32 +02:00
// Exposed as `get_cache_dir()` instead of `get_cache_path()` for consistency with other exposed OS methods.
2021-08-13 16:46:14 +02:00
return : : OS : : get_singleton ( ) - > get_cache_path ( ) ;
2021-05-07 19:36:32 +02:00
}
2021-08-13 16:46:14 +02:00
bool OS : : is_debug_build ( ) const {
2014-11-02 15:31:01 +01:00
# ifdef DEBUG_ENABLED
return true ;
# else
return false ;
# endif
}
2014-12-02 18:02:41 +01:00
2021-08-13 16:46:14 +02:00
String OS : : get_system_dir ( SystemDir p_dir , bool p_shared_storage ) const {
return : : OS : : get_singleton ( ) - > get_system_dir ( : : OS : : SystemDir ( p_dir ) , p_shared_storage ) ;
2014-12-02 18:02:41 +01:00
}
2021-08-13 23:31:57 +02:00
String OS : : get_keycode_string ( Key p_code ) const {
2021-08-13 16:46:14 +02:00
return : : keycode_get_string ( p_code ) ;
2015-05-17 18:11:55 +02:00
}
2018-04-05 19:59:35 +02:00
2021-08-13 23:31:57 +02:00
bool OS : : is_keycode_unicode ( char32_t p_unicode ) const {
return : : keycode_has_unicode ( ( Key ) p_unicode ) ;
2015-05-17 18:11:55 +02:00
}
2018-04-05 19:59:35 +02:00
2021-08-13 23:31:57 +02:00
Key OS : : find_keycode_from_string ( const String & p_code ) const {
2015-05-17 18:11:55 +02:00
return find_keycode ( p_code ) ;
}
2021-08-13 16:46:14 +02:00
bool OS : : request_permission ( const String & p_name ) {
return : : OS : : get_singleton ( ) - > request_permission ( p_name ) ;
2019-03-05 03:06:37 +01:00
}
2021-08-13 16:46:14 +02:00
bool OS : : request_permissions ( ) {
return : : OS : : get_singleton ( ) - > request_permissions ( ) ;
2019-10-06 20:17:44 +02:00
}
2021-08-13 16:46:14 +02:00
Vector < String > OS : : get_granted_permissions ( ) const {
return : : OS : : get_singleton ( ) - > get_granted_permissions ( ) ;
2019-10-06 20:17:44 +02:00
}
2021-03-30 14:42:50 +02:00
void OS : : revoke_granted_permissions ( ) {
: : OS : : get_singleton ( ) - > revoke_granted_permissions ( ) ;
}
2021-08-13 16:46:14 +02:00
String OS : : get_unique_id ( ) const {
return : : OS : : get_singleton ( ) - > get_unique_id ( ) ;
2020-03-03 14:36:29 +01:00
}
2020-05-12 17:01:17 +02:00
2021-08-13 16:46:14 +02:00
OS * OS : : singleton = nullptr ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
void OS : : _bind_methods ( ) {
2024-06-14 02:30:32 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_entropy " , " size " ) , & OS : : get_entropy ) ;
2024-06-10 15:35:50 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_system_ca_certificates " ) , & OS : : get_system_ca_certificates ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_connected_midi_inputs " ) , & OS : : get_connected_midi_inputs ) ;
ClassDB : : bind_method ( D_METHOD ( " open_midi_inputs " ) , & OS : : open_midi_inputs ) ;
ClassDB : : bind_method ( D_METHOD ( " close_midi_inputs " ) , & OS : : close_midi_inputs ) ;
2018-03-04 18:18:05 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " alert " , " text " , " title " ) , & OS : : alert , DEFVAL ( " Alert! " ) ) ;
2021-12-03 20:36:47 +01:00
ClassDB : : bind_method ( D_METHOD ( " crash " , " message " ) , & OS : : crash ) ;
2021-07-22 18:23:48 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_low_processor_usage_mode " , " enable " ) , & OS : : set_low_processor_usage_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " is_in_low_processor_usage_mode " ) , & OS : : is_in_low_processor_usage_mode ) ;
2017-02-13 12:47:24 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_low_processor_usage_mode_sleep_usec " , " usec " ) , & OS : : set_low_processor_usage_mode_sleep_usec ) ;
ClassDB : : bind_method ( D_METHOD ( " get_low_processor_usage_mode_sleep_usec " ) , & OS : : get_low_processor_usage_mode_sleep_usec ) ;
2019-11-08 18:36:06 +01:00
2021-09-01 16:47:12 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_delta_smoothing " , " delta_smoothing_enabled " ) , & OS : : set_delta_smoothing ) ;
ClassDB : : bind_method ( D_METHOD ( " is_delta_smoothing_enabled " ) , & OS : : is_delta_smoothing_enabled ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_processor_count " ) , & OS : : get_processor_count ) ;
2020-12-27 01:50:21 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_processor_name " ) , & OS : : get_processor_name ) ;
2017-02-13 12:47:24 +01:00
2022-07-08 14:38:30 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_system_fonts " ) , & OS : : get_system_fonts ) ;
2022-11-21 14:04:01 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_system_font_path " , " font_name " , " weight " , " stretch " , " italic " ) , & OS : : get_system_font_path , DEFVAL ( 400 ) , DEFVAL ( 100 ) , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_system_font_path_for_text " , " font_name " , " text " , " locale " , " script " , " weight " , " stretch " , " italic " ) , & OS : : get_system_font_path_for_text , DEFVAL ( String ( ) ) , DEFVAL ( String ( ) ) , DEFVAL ( 400 ) , DEFVAL ( 100 ) , DEFVAL ( false ) ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_executable_path " ) , & OS : : get_executable_path ) ;
2022-12-29 21:06:11 +01:00
ClassDB : : bind_method ( D_METHOD ( " read_string_from_stdin " ) , & OS : : read_string_from_stdin ) ;
2021-12-16 14:00:55 +01:00
ClassDB : : bind_method ( D_METHOD ( " execute " , " path " , " arguments " , " output " , " read_stderr " , " open_console " ) , & OS : : execute , DEFVAL ( Array ( ) ) , DEFVAL ( false ) , DEFVAL ( false ) ) ;
2023-10-19 13:35:10 +02:00
ClassDB : : bind_method ( D_METHOD ( " execute_with_pipe " , " path " , " arguments " ) , & OS : : execute_with_pipe ) ;
2021-12-16 14:00:55 +01:00
ClassDB : : bind_method ( D_METHOD ( " create_process " , " path " , " arguments " , " open_console " ) , & OS : : create_process , DEFVAL ( false ) ) ;
2021-11-01 10:12:52 +01:00
ClassDB : : bind_method ( D_METHOD ( " create_instance " , " arguments " ) , & OS : : create_instance ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " kill " , " pid " ) , & OS : : kill ) ;
ClassDB : : bind_method ( D_METHOD ( " shell_open " , " uri " ) , & OS : : shell_open ) ;
2022-12-07 04:33:35 +01:00
ClassDB : : bind_method ( D_METHOD ( " shell_show_in_file_manager " , " file_or_dir_path " , " open_folder " ) , & OS : : shell_show_in_file_manager , DEFVAL ( true ) ) ;
2021-08-13 05:36:23 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_process_running " , " pid " ) , & OS : : is_process_running ) ;
2024-04-07 20:19:46 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_process_exit_code " , " pid " ) , & OS : : get_process_exit_code ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_process_id " ) , & OS : : get_process_id ) ;
2017-02-13 12:47:24 +01:00
2023-01-16 14:26:14 +01:00
ClassDB : : bind_method ( D_METHOD ( " has_environment " , " variable " ) , & OS : : has_environment ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_environment " , " variable " ) , & OS : : get_environment ) ;
ClassDB : : bind_method ( D_METHOD ( " set_environment " , " variable " , " value " ) , & OS : : set_environment ) ;
2023-01-16 14:26:14 +01:00
ClassDB : : bind_method ( D_METHOD ( " unset_environment " , " variable " ) , & OS : : unset_environment ) ;
2017-02-13 12:47:24 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_name " ) , & OS : : get_name ) ;
2022-09-16 11:14:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_distribution_name " ) , & OS : : get_distribution_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_version " ) , & OS : : get_version ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_cmdline_args " ) , & OS : : get_cmdline_args ) ;
2022-07-29 15:30:52 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_cmdline_user_args " ) , & OS : : get_cmdline_user_args ) ;
2017-02-13 12:47:24 +01:00
2022-10-11 12:39:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_video_adapter_driver_info " ) , & OS : : get_video_adapter_driver_info ) ;
2021-05-12 03:12:59 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_restart_on_exit " , " restart " , " arguments " ) , & OS : : set_restart_on_exit , DEFVAL ( Vector < String > ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " is_restart_on_exit_set " ) , & OS : : is_restart_on_exit_set ) ;
ClassDB : : bind_method ( D_METHOD ( " get_restart_on_exit_arguments " ) , & OS : : get_restart_on_exit_arguments ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " delay_usec " , " usec " ) , & OS : : delay_usec ) ;
ClassDB : : bind_method ( D_METHOD ( " delay_msec " , " msec " ) , & OS : : delay_msec ) ;
ClassDB : : bind_method ( D_METHOD ( " get_locale " ) , & OS : : get_locale ) ;
2021-09-16 09:27:56 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_locale_language " ) , & OS : : get_locale_language ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_model_name " ) , & OS : : get_model_name ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_userfs_persistent " ) , & OS : : is_userfs_persistent ) ;
ClassDB : : bind_method ( D_METHOD ( " is_stdout_verbose " ) , & OS : : is_stdout_verbose ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_debug_build " ) , & OS : : is_debug_build ) ;
2014-11-02 15:31:01 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_static_memory_usage " ) , & OS : : get_static_memory_usage ) ;
ClassDB : : bind_method ( D_METHOD ( " get_static_memory_peak_usage " ) , & OS : : get_static_memory_peak_usage ) ;
2023-04-03 10:46:29 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_memory_info " ) , & OS : : get_memory_info ) ;
2017-03-05 16:44:50 +01:00
2022-04-26 23:52:20 +02:00
ClassDB : : bind_method ( D_METHOD ( " move_to_trash " , " path " ) , & OS : : move_to_trash ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_user_data_dir " ) , & OS : : get_user_data_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " get_system_dir " , " dir " , " shared_storage " ) , & OS : : get_system_dir , DEFVAL ( true ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_config_dir " ) , & OS : : get_config_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " get_data_dir " ) , & OS : : get_data_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " get_cache_dir " ) , & OS : : get_cache_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " get_unique_id " ) , & OS : : get_unique_id ) ;
2017-03-05 16:44:50 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_keycode_string " , " code " ) , & OS : : get_keycode_string ) ;
ClassDB : : bind_method ( D_METHOD ( " is_keycode_unicode " , " code " ) , & OS : : is_keycode_unicode ) ;
ClassDB : : bind_method ( D_METHOD ( " find_keycode_from_string " , " string " ) , & OS : : find_keycode_from_string ) ;
2017-03-05 16:44:50 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_use_file_access_save_and_swap " , " enabled " ) , & OS : : set_use_file_access_save_and_swap ) ;
2017-03-05 16:44:50 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_thread_name " , " name " ) , & OS : : set_thread_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_thread_caller_id " ) , & OS : : get_thread_caller_id ) ;
2021-11-13 01:10:33 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_main_thread_id " ) , & OS : : get_main_thread_id ) ;
2017-03-05 16:44:50 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " has_feature " , " tag_name " ) , & OS : : has_feature ) ;
2021-03-30 14:42:50 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_sandboxed " ) , & OS : : is_sandboxed ) ;
2017-10-02 21:38:39 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " request_permission " , " name " ) , & OS : : request_permission ) ;
ClassDB : : bind_method ( D_METHOD ( " request_permissions " ) , & OS : : request_permissions ) ;
ClassDB : : bind_method ( D_METHOD ( " get_granted_permissions " ) , & OS : : get_granted_permissions ) ;
2021-03-30 14:42:50 +02:00
ClassDB : : bind_method ( D_METHOD ( " revoke_granted_permissions " ) , & OS : : revoke_granted_permissions ) ;
2019-03-05 03:06:37 +01:00
2018-01-11 23:35:12 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " low_processor_usage_mode " ) , " set_low_processor_usage_mode " , " is_in_low_processor_usage_mode " ) ;
2019-11-08 18:36:06 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " low_processor_usage_mode_sleep_usec " ) , " set_low_processor_usage_mode_sleep_usec " , " get_low_processor_usage_mode_sleep_usec " ) ;
2021-09-01 16:47:12 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " delta_smoothing " ) , " set_delta_smoothing " , " is_delta_smoothing_enabled " ) ;
2018-01-11 23:35:12 +01:00
2019-06-30 13:19:00 +02:00
// Those default values need to be specified for the docs generator,
// to avoid using values from the documentation writer's own OS instance.
ADD_PROPERTY_DEFAULT ( " low_processor_usage_mode " , false ) ;
2019-11-08 18:36:06 +01:00
ADD_PROPERTY_DEFAULT ( " low_processor_usage_mode_sleep_usec " , 6900 ) ;
2019-06-30 13:19:00 +02:00
2022-10-11 10:32:13 +02:00
BIND_ENUM_CONSTANT ( RENDERING_DRIVER_VULKAN ) ;
BIND_ENUM_CONSTANT ( RENDERING_DRIVER_OPENGL3 ) ;
2023-01-09 16:56:16 +01:00
BIND_ENUM_CONSTANT ( RENDERING_DRIVER_D3D12 ) ;
2024-02-19 19:52:00 +01:00
BIND_ENUM_CONSTANT ( RENDERING_DRIVER_METAL ) ;
2019-02-16 14:40:52 +01:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( SYSTEM_DIR_DESKTOP ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_DCIM ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_DOCUMENTS ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_DOWNLOADS ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_MOVIES ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_MUSIC ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_PICTURES ) ;
BIND_ENUM_CONSTANT ( SYSTEM_DIR_RINGTONES ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
////// Geometry2D //////
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
Geometry2D * Geometry2D : : singleton = nullptr ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
Geometry2D * Geometry2D : : get_singleton ( ) {
2014-02-10 02:10:30 +01:00
return singleton ;
}
2021-08-13 16:46:14 +02:00
bool Geometry2D : : is_point_in_circle ( const Vector2 & p_point , const Vector2 & p_circle_pos , real_t p_circle_radius ) {
return : : Geometry2D : : is_point_in_circle ( p_point , p_circle_pos , p_circle_radius ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
real_t Geometry2D : : segment_intersects_circle ( const Vector2 & p_from , const Vector2 & p_to , const Vector2 & p_circle_pos , real_t p_circle_radius ) {
return : : Geometry2D : : segment_intersects_circle ( p_from , p_to , p_circle_pos , p_circle_radius ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Variant Geometry2D : : segment_intersects_segment ( const Vector2 & p_from_a , const Vector2 & p_to_a , const Vector2 & p_from_b , const Vector2 & p_to_b ) {
2014-02-10 02:10:30 +01:00
Vector2 result ;
2021-08-13 16:46:14 +02:00
if ( : : Geometry2D : : segment_intersects_segment ( p_from_a , p_to_a , p_from_b , p_to_b , & result ) ) {
2014-02-10 02:10:30 +01:00
return result ;
} else {
return Variant ( ) ;
2020-05-19 15:46:49 +02:00
}
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
Variant Geometry2D : : line_intersects_line ( const Vector2 & p_from_a , const Vector2 & p_dir_a , const Vector2 & p_from_b , const Vector2 & p_dir_b ) {
2018-01-21 09:21:02 +01:00
Vector2 result ;
2021-08-13 16:46:14 +02:00
if ( : : Geometry2D : : line_intersects_line ( p_from_a , p_dir_a , p_from_b , p_dir_b , result ) ) {
2018-01-21 09:21:02 +01:00
return result ;
} else {
return Variant ( ) ;
}
}
2021-08-13 16:46:14 +02:00
Vector < Vector2 > Geometry2D : : get_closest_points_between_segments ( const Vector2 & p1 , const Vector2 & q1 , const Vector2 & p2 , const Vector2 & q2 ) {
2014-02-10 02:10:30 +01:00
Vector2 r1 , r2 ;
2021-08-13 16:46:14 +02:00
: : Geometry2D : : get_closest_points_between_segments ( p1 , q1 , p2 , q2 , r1 , r2 ) ;
2022-01-11 16:27:39 +01:00
Vector < Vector2 > r = { r1 , r2 } ;
2014-02-10 02:10:30 +01:00
return r ;
}
2021-08-13 16:46:14 +02:00
Vector2 Geometry2D : : get_closest_point_to_segment ( const Vector2 & p_point , const Vector2 & p_a , const Vector2 & p_b ) {
2017-03-05 16:44:50 +01:00
Vector2 s [ 2 ] = { p_a , p_b } ;
2021-08-13 16:46:14 +02:00
return : : Geometry2D : : get_closest_point_to_segment ( p_point , s ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Vector2 Geometry2D : : get_closest_point_to_segment_uncapped ( const Vector2 & p_point , const Vector2 & p_a , const Vector2 & p_b ) {
2017-03-05 16:44:50 +01:00
Vector2 s [ 2 ] = { p_a , p_b } ;
2021-08-13 16:46:14 +02:00
return : : Geometry2D : : get_closest_point_to_segment_uncapped ( p_point , s ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool Geometry2D : : point_is_inside_triangle ( const Vector2 & s , const Vector2 & a , const Vector2 & b , const Vector2 & c ) const {
return : : Geometry2D : : is_point_in_triangle ( s , a , b , c ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool Geometry2D : : is_polygon_clockwise ( const Vector < Vector2 > & p_polygon ) {
return : : Geometry2D : : is_polygon_clockwise ( p_polygon ) ;
2019-06-26 23:20:22 +02:00
}
2021-08-13 16:46:14 +02:00
bool Geometry2D : : is_point_in_polygon ( const Point2 & p_point , const Vector < Vector2 > & p_polygon ) {
return : : Geometry2D : : is_point_in_polygon ( p_point , p_polygon ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
Vector < int > Geometry2D : : triangulate_polygon ( const Vector < Vector2 > & p_polygon ) {
return : : Geometry2D : : triangulate_polygon ( p_polygon ) ;
2019-05-23 15:53:53 +02:00
}
2021-08-13 16:46:14 +02:00
Vector < int > Geometry2D : : triangulate_delaunay ( const Vector < Vector2 > & p_points ) {
return : : Geometry2D : : triangulate_delaunay ( p_points ) ;
2017-11-05 00:46:32 +01:00
}
2021-08-13 16:46:14 +02:00
Vector < Point2 > Geometry2D : : convex_hull ( const Vector < Point2 > & p_points ) {
return : : Geometry2D : : convex_hull ( p_points ) ;
2017-11-05 00:46:32 +01:00
}
2022-09-19 12:09:56 +02:00
TypedArray < PackedVector2Array > Geometry2D : : decompose_polygon_in_convex ( const Vector < Vector2 > & p_polygon ) {
Vector < Vector < Point2 > > decomp = : : Geometry2D : : decompose_polygon_in_convex ( p_polygon ) ;
TypedArray < PackedVector2Array > ret ;
for ( int i = 0 ; i < decomp . size ( ) ; + + i ) {
ret . push_back ( decomp [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : merge_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : merge_polygons ( p_polygon_a , p_polygon_b ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : clip_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : clip_polygons ( p_polygon_a , p_polygon_b ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : intersect_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : intersect_polygons ( p_polygon_a , p_polygon_b ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : exclude_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : exclude_polygons ( p_polygon_a , p_polygon_b ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : clip_polyline_with_polygon ( const Vector < Vector2 > & p_polyline , const Vector < Vector2 > & p_polygon ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : clip_polyline_with_polygon ( p_polyline , p_polygon ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : intersect_polyline_with_polygon ( const Vector < Vector2 > & p_polyline , const Vector < Vector2 > & p_polygon ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : intersect_polyline_with_polygon ( p_polyline , p_polygon ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : offset_polygon ( const Vector < Vector2 > & p_polygon , real_t p_delta , PolyJoinType p_join_type ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : offset_polygon ( p_polygon , p_delta , : : Geometry2D : : PolyJoinType ( p_join_type ) ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < PackedVector2Array > Geometry2D : : offset_polyline ( const Vector < Vector2 > & p_polygon , real_t p_delta , PolyJoinType p_join_type , PolyEndType p_end_type ) {
2021-08-13 16:46:14 +02:00
Vector < Vector < Point2 > > polys = : : Geometry2D : : offset_polyline ( p_polygon , p_delta , : : Geometry2D : : PolyJoinType ( p_join_type ) , : : Geometry2D : : PolyEndType ( p_end_type ) ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2022-11-27 08:56:53 +01:00
TypedArray < PackedVector2Array > ret ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Dictionary Geometry2D : : make_atlas ( const Vector < Size2 > & p_rects ) {
2014-10-03 05:10:51 +02:00
Dictionary ret ;
Vector < Size2i > rects ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < p_rects . size ( ) ; i + + ) {
2014-10-03 05:10:51 +02:00
rects . push_back ( p_rects [ i ] ) ;
2020-05-19 15:46:49 +02:00
}
2014-10-03 05:10:51 +02:00
Vector < Point2i > result ;
Size2i size ;
2021-08-13 16:46:14 +02:00
: : Geometry2D : : make_atlas ( rects , result , size ) ;
2014-10-03 05:10:51 +02:00
Vector < Point2 > r_result ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < result . size ( ) ; i + + ) {
2014-10-03 05:10:51 +02:00
r_result . push_back ( result [ i ] ) ;
2020-05-19 15:46:49 +02:00
}
2014-10-03 05:10:51 +02:00
ret [ " points " ] = r_result ;
2022-09-19 12:37:02 +02:00
ret [ " size " ] = size ;
2014-10-03 05:10:51 +02:00
return ret ;
2020-05-19 15:46:49 +02:00
}
2014-10-03 05:10:51 +02:00
2021-08-13 16:46:14 +02:00
void Geometry2D : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " is_point_in_circle " , " point " , " circle_position " , " circle_radius " ) , & Geometry2D : : is_point_in_circle ) ;
2022-08-03 15:36:54 +02:00
ClassDB : : bind_method ( D_METHOD ( " segment_intersects_circle " , " segment_from " , " segment_to " , " circle_position " , " circle_radius " ) , & Geometry2D : : segment_intersects_circle ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " segment_intersects_segment " , " from_a " , " to_a " , " from_b " , " to_b " ) , & Geometry2D : : segment_intersects_segment ) ;
ClassDB : : bind_method ( D_METHOD ( " line_intersects_line " , " from_a " , " dir_a " , " from_b " , " dir_b " ) , & Geometry2D : : line_intersects_line ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_closest_points_between_segments " , " p1 " , " q1 " , " p2 " , " q2 " ) , & Geometry2D : : get_closest_points_between_segments ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_closest_point_to_segment " , " point " , " s1 " , " s2 " ) , & Geometry2D : : get_closest_point_to_segment ) ;
2017-03-04 23:02:27 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_closest_point_to_segment_uncapped " , " point " , " s1 " , " s2 " ) , & Geometry2D : : get_closest_point_to_segment_uncapped ) ;
2014-10-07 06:31:49 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " point_is_inside_triangle " , " point " , " a " , " b " , " c " ) , & Geometry2D : : point_is_inside_triangle ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_polygon_clockwise " , " polygon " ) , & Geometry2D : : is_polygon_clockwise ) ;
ClassDB : : bind_method ( D_METHOD ( " is_point_in_polygon " , " point " , " polygon " ) , & Geometry2D : : is_point_in_polygon ) ;
ClassDB : : bind_method ( D_METHOD ( " triangulate_polygon " , " polygon " ) , & Geometry2D : : triangulate_polygon ) ;
ClassDB : : bind_method ( D_METHOD ( " triangulate_delaunay " , " points " ) , & Geometry2D : : triangulate_delaunay ) ;
ClassDB : : bind_method ( D_METHOD ( " convex_hull " , " points " ) , & Geometry2D : : convex_hull ) ;
2022-09-19 12:09:56 +02:00
ClassDB : : bind_method ( D_METHOD ( " decompose_polygon_in_convex " , " polygon " ) , & Geometry2D : : decompose_polygon_in_convex ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " merge_polygons " , " polygon_a " , " polygon_b " ) , & Geometry2D : : merge_polygons ) ;
ClassDB : : bind_method ( D_METHOD ( " clip_polygons " , " polygon_a " , " polygon_b " ) , & Geometry2D : : clip_polygons ) ;
ClassDB : : bind_method ( D_METHOD ( " intersect_polygons " , " polygon_a " , " polygon_b " ) , & Geometry2D : : intersect_polygons ) ;
ClassDB : : bind_method ( D_METHOD ( " exclude_polygons " , " polygon_a " , " polygon_b " ) , & Geometry2D : : exclude_polygons ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " clip_polyline_with_polygon " , " polyline " , " polygon " ) , & Geometry2D : : clip_polyline_with_polygon ) ;
ClassDB : : bind_method ( D_METHOD ( " intersect_polyline_with_polygon " , " polyline " , " polygon " ) , & Geometry2D : : intersect_polyline_with_polygon ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " offset_polygon " , " polygon " , " delta " , " join_type " ) , & Geometry2D : : offset_polygon , DEFVAL ( JOIN_SQUARE ) ) ;
ClassDB : : bind_method ( D_METHOD ( " offset_polyline " , " polyline " , " delta " , " join_type " , " end_type " ) , & Geometry2D : : offset_polyline , DEFVAL ( JOIN_SQUARE ) , DEFVAL ( END_SQUARE ) ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " make_atlas " , " sizes " ) , & Geometry2D : : make_atlas ) ;
Expose 2D polygon boolean operations in Geometry singleton
Clipper 6.4.2 is used internally to perform polypaths clipping, as well
as inflating/deflating polypaths. The following methods were added:
```
Geometry.merge_polygons_2d(poly_a, poly_b) # union
Geometry.clip_polygons_2d(poly_a, poly_b) # difference
Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection
Geometry.exclude_polygons_2d(poly_a, poly_b) # xor
Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b)
Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate
Geometry.offset_polyline_2d(polyline, delta) # returns polygons
// This one helps to implement CSG-like behaviour:
Geometry.transform_points_2d(points, transform)
```
All the methods return an array of polygons/polylines. The resulting
polygons could possibly be holes which could be checked with
`Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
2019-05-18 19:01:42 +02:00
BIND_ENUM_CONSTANT ( OPERATION_UNION ) ;
BIND_ENUM_CONSTANT ( OPERATION_DIFFERENCE ) ;
BIND_ENUM_CONSTANT ( OPERATION_INTERSECTION ) ;
BIND_ENUM_CONSTANT ( OPERATION_XOR ) ;
BIND_ENUM_CONSTANT ( JOIN_SQUARE ) ;
BIND_ENUM_CONSTANT ( JOIN_ROUND ) ;
BIND_ENUM_CONSTANT ( JOIN_MITER ) ;
BIND_ENUM_CONSTANT ( END_POLYGON ) ;
BIND_ENUM_CONSTANT ( END_JOINED ) ;
BIND_ENUM_CONSTANT ( END_BUTT ) ;
BIND_ENUM_CONSTANT ( END_SQUARE ) ;
BIND_ENUM_CONSTANT ( END_ROUND ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
////// Geometry3D //////
2020-05-25 19:20:45 +02:00
2021-08-13 16:46:14 +02:00
Geometry3D * Geometry3D : : singleton = nullptr ;
2020-05-25 19:20:45 +02:00
2021-08-13 16:46:14 +02:00
Geometry3D * Geometry3D : : get_singleton ( ) {
2020-05-25 19:20:45 +02:00
return singleton ;
}
2023-06-30 13:25:03 +02:00
Vector < Vector3 > Geometry3D : : compute_convex_mesh_points ( const TypedArray < Plane > & p_planes ) {
Vector < Plane > planes_vec ;
int size = p_planes . size ( ) ;
planes_vec . resize ( size ) ;
for ( int i = 0 ; i < size ; + + i ) {
planes_vec . set ( i , p_planes [ i ] ) ;
}
Variant ret = : : Geometry3D : : compute_convex_mesh_points ( planes_vec . ptr ( ) , size ) ;
return ret ;
}
2022-08-05 20:35:08 +02:00
TypedArray < Plane > Geometry3D : : build_box_planes ( const Vector3 & p_extents ) {
Variant ret = : : Geometry3D : : build_box_planes ( p_extents ) ;
return ret ;
2020-05-25 19:20:45 +02:00
}
2022-08-05 20:35:08 +02:00
TypedArray < Plane > Geometry3D : : build_cylinder_planes ( float p_radius , float p_height , int p_sides , Vector3 : : Axis p_axis ) {
Variant ret = : : Geometry3D : : build_cylinder_planes ( p_radius , p_height , p_sides , p_axis ) ;
return ret ;
2020-05-25 19:20:45 +02:00
}
2022-08-05 20:35:08 +02:00
TypedArray < Plane > Geometry3D : : build_capsule_planes ( float p_radius , float p_height , int p_sides , int p_lats , Vector3 : : Axis p_axis ) {
Variant ret = : : Geometry3D : : build_capsule_planes ( p_radius , p_height , p_sides , p_lats , p_axis ) ;
return ret ;
2020-05-25 19:20:45 +02:00
}
2021-08-13 16:46:14 +02:00
Vector < Vector3 > Geometry3D : : get_closest_points_between_segments ( const Vector3 & p1 , const Vector3 & p2 , const Vector3 & q1 , const Vector3 & q2 ) {
2020-05-25 19:20:45 +02:00
Vector3 r1 , r2 ;
2021-08-13 16:46:14 +02:00
: : Geometry3D : : get_closest_points_between_segments ( p1 , p2 , q1 , q2 , r1 , r2 ) ;
2022-01-11 16:27:39 +01:00
Vector < Vector3 > r = { r1 , r2 } ;
2020-05-25 19:20:45 +02:00
return r ;
}
2021-08-13 16:46:14 +02:00
Vector3 Geometry3D : : get_closest_point_to_segment ( const Vector3 & p_point , const Vector3 & p_a , const Vector3 & p_b ) {
2020-05-25 19:20:45 +02:00
Vector3 s [ 2 ] = { p_a , p_b } ;
2021-08-13 16:46:14 +02:00
return : : Geometry3D : : get_closest_point_to_segment ( p_point , s ) ;
2020-05-25 19:20:45 +02:00
}
2021-08-13 16:46:14 +02:00
Vector3 Geometry3D : : get_closest_point_to_segment_uncapped ( const Vector3 & p_point , const Vector3 & p_a , const Vector3 & p_b ) {
2020-05-25 19:20:45 +02:00
Vector3 s [ 2 ] = { p_a , p_b } ;
2021-08-13 16:46:14 +02:00
return : : Geometry3D : : get_closest_point_to_segment_uncapped ( p_point , s ) ;
2020-05-25 19:20:45 +02:00
}
2023-03-05 22:59:22 +01:00
Vector3 Geometry3D : : get_triangle_barycentric_coords ( const Vector3 & p_point , const Vector3 & p_v0 , const Vector3 & p_v1 , const Vector3 & p_v2 ) {
Vector3 res = : : Geometry3D : : triangle_get_barycentric_coords ( p_v0 , p_v1 , p_v2 , p_point ) ;
return res ;
}
2021-08-13 16:46:14 +02:00
Variant Geometry3D : : ray_intersects_triangle ( const Vector3 & p_from , const Vector3 & p_dir , const Vector3 & p_v0 , const Vector3 & p_v1 , const Vector3 & p_v2 ) {
2020-05-25 19:20:45 +02:00
Vector3 res ;
2021-08-13 16:46:14 +02:00
if ( : : Geometry3D : : ray_intersects_triangle ( p_from , p_dir , p_v0 , p_v1 , p_v2 , & res ) ) {
2020-05-25 19:20:45 +02:00
return res ;
} else {
return Variant ( ) ;
}
}
2021-08-13 16:46:14 +02:00
Variant Geometry3D : : segment_intersects_triangle ( const Vector3 & p_from , const Vector3 & p_to , const Vector3 & p_v0 , const Vector3 & p_v1 , const Vector3 & p_v2 ) {
2020-05-25 19:20:45 +02:00
Vector3 res ;
2021-08-13 16:46:14 +02:00
if ( : : Geometry3D : : segment_intersects_triangle ( p_from , p_to , p_v0 , p_v1 , p_v2 , & res ) ) {
2020-05-25 19:20:45 +02:00
return res ;
} else {
return Variant ( ) ;
}
}
2021-08-13 16:46:14 +02:00
Vector < Vector3 > Geometry3D : : segment_intersects_sphere ( const Vector3 & p_from , const Vector3 & p_to , const Vector3 & p_sphere_pos , real_t p_sphere_radius ) {
2020-05-25 19:20:45 +02:00
Vector < Vector3 > r ;
Vector3 res , norm ;
2021-08-13 16:46:14 +02:00
if ( ! : : Geometry3D : : segment_intersects_sphere ( p_from , p_to , p_sphere_pos , p_sphere_radius , & res , & norm ) ) {
2020-05-25 19:20:45 +02:00
return r ;
}
r . resize ( 2 ) ;
r . set ( 0 , res ) ;
r . set ( 1 , norm ) ;
return r ;
}
2021-08-13 16:46:14 +02:00
Vector < Vector3 > Geometry3D : : segment_intersects_cylinder ( const Vector3 & p_from , const Vector3 & p_to , float p_height , float p_radius ) {
2020-05-25 19:20:45 +02:00
Vector < Vector3 > r ;
Vector3 res , norm ;
2021-08-13 16:46:14 +02:00
if ( ! : : Geometry3D : : segment_intersects_cylinder ( p_from , p_to , p_height , p_radius , & res , & norm ) ) {
2020-05-25 19:20:45 +02:00
return r ;
}
r . resize ( 2 ) ;
r . set ( 0 , res ) ;
r . set ( 1 , norm ) ;
return r ;
}
2023-04-25 00:21:32 +02:00
Vector < Vector3 > Geometry3D : : segment_intersects_convex ( const Vector3 & p_from , const Vector3 & p_to , const TypedArray < Plane > & p_planes ) {
2020-05-25 19:20:45 +02:00
Vector < Vector3 > r ;
Vector3 res , norm ;
2023-04-25 00:21:32 +02:00
Vector < Plane > planes = Variant ( p_planes ) ;
if ( ! : : Geometry3D : : segment_intersects_convex ( p_from , p_to , planes . ptr ( ) , planes . size ( ) , & res , & norm ) ) {
2020-05-25 19:20:45 +02:00
return r ;
}
r . resize ( 2 ) ;
r . set ( 0 , res ) ;
r . set ( 1 , norm ) ;
return r ;
}
2021-08-13 16:46:14 +02:00
Vector < Vector3 > Geometry3D : : clip_polygon ( const Vector < Vector3 > & p_points , const Plane & p_plane ) {
return : : Geometry3D : : clip_polygon ( p_points , p_plane ) ;
2020-05-25 19:20:45 +02:00
}
2023-10-14 15:18:14 +02:00
Vector < int32_t > Geometry3D : : tetrahedralize_delaunay ( const Vector < Vector3 > & p_points ) {
return : : Geometry3D : : tetrahedralize_delaunay ( p_points ) ;
}
2021-08-13 16:46:14 +02:00
void Geometry3D : : _bind_methods ( ) {
2023-06-30 13:25:03 +02:00
ClassDB : : bind_method ( D_METHOD ( " compute_convex_mesh_points " , " planes " ) , & Geometry3D : : compute_convex_mesh_points ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " build_box_planes " , " extents " ) , & Geometry3D : : build_box_planes ) ;
ClassDB : : bind_method ( D_METHOD ( " build_cylinder_planes " , " radius " , " height " , " sides " , " axis " ) , & Geometry3D : : build_cylinder_planes , DEFVAL ( Vector3 : : AXIS_Z ) ) ;
ClassDB : : bind_method ( D_METHOD ( " build_capsule_planes " , " radius " , " height " , " sides " , " lats " , " axis " ) , & Geometry3D : : build_capsule_planes , DEFVAL ( Vector3 : : AXIS_Z ) ) ;
2020-05-25 19:20:45 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_closest_points_between_segments " , " p1 " , " p2 " , " q1 " , " q2 " ) , & Geometry3D : : get_closest_points_between_segments ) ;
2020-05-25 19:20:45 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_closest_point_to_segment " , " point " , " s1 " , " s2 " ) , & Geometry3D : : get_closest_point_to_segment ) ;
2020-05-25 19:20:45 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_closest_point_to_segment_uncapped " , " point " , " s1 " , " s2 " ) , & Geometry3D : : get_closest_point_to_segment_uncapped ) ;
2020-05-25 19:20:45 +02:00
2023-03-05 22:59:22 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_triangle_barycentric_coords " , " point " , " a " , " b " , " c " ) , & Geometry3D : : get_triangle_barycentric_coords ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " ray_intersects_triangle " , " from " , " dir " , " a " , " b " , " c " ) , & Geometry3D : : ray_intersects_triangle ) ;
ClassDB : : bind_method ( D_METHOD ( " segment_intersects_triangle " , " from " , " to " , " a " , " b " , " c " ) , & Geometry3D : : segment_intersects_triangle ) ;
ClassDB : : bind_method ( D_METHOD ( " segment_intersects_sphere " , " from " , " to " , " sphere_position " , " sphere_radius " ) , & Geometry3D : : segment_intersects_sphere ) ;
ClassDB : : bind_method ( D_METHOD ( " segment_intersects_cylinder " , " from " , " to " , " height " , " radius " ) , & Geometry3D : : segment_intersects_cylinder ) ;
ClassDB : : bind_method ( D_METHOD ( " segment_intersects_convex " , " from " , " to " , " planes " ) , & Geometry3D : : segment_intersects_convex ) ;
2020-05-25 19:20:45 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " clip_polygon " , " points " , " plane " ) , & Geometry3D : : clip_polygon ) ;
2023-10-14 15:18:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " tetrahedralize_delaunay " , " points " ) , & Geometry3D : : tetrahedralize_delaunay ) ;
2020-05-25 19:20:45 +02:00
}
2021-08-13 16:46:14 +02:00
////// Marshalls //////
2020-05-12 17:01:17 +02:00
2021-08-13 16:46:14 +02:00
Marshalls * Marshalls : : singleton = nullptr ;
2016-11-05 17:13:04 +01:00
2021-08-13 16:46:14 +02:00
Marshalls * Marshalls : : get_singleton ( ) {
2016-11-05 17:13:04 +01:00
return singleton ;
}
2021-08-13 16:46:14 +02:00
String Marshalls : : variant_to_base64 ( const Variant & p_var , bool p_full_objects ) {
2014-02-10 02:10:30 +01:00
int len ;
2020-04-02 01:20:12 +02:00
Error err = encode_variant ( p_var , nullptr , len , p_full_objects ) ;
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( err ! = OK , " " , " Error when trying to encode Variant. " ) ;
2014-02-10 02:10:30 +01:00
2020-02-17 22:06:54 +01:00
Vector < uint8_t > buff ;
2014-02-10 02:10:30 +01:00
buff . resize ( len ) ;
2020-02-17 22:06:54 +01:00
uint8_t * w = buff . ptrw ( ) ;
2014-02-10 02:10:30 +01:00
2019-03-26 16:52:42 +01:00
err = encode_variant ( p_var , & w [ 0 ] , len , p_full_objects ) ;
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( err ! = OK , " " , " Error when trying to encode Variant. " ) ;
2014-02-10 02:10:30 +01:00
2019-07-02 17:47:34 +02:00
String ret = CryptoCore : : b64_encode_str ( & w [ 0 ] , len ) ;
2021-12-09 10:42:46 +01:00
ERR_FAIL_COND_V ( ret . is_empty ( ) , ret ) ;
2014-02-10 02:10:30 +01:00
return ret ;
2020-05-19 15:46:49 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
Variant Marshalls : : base64_to_variant ( const String & p_str , bool p_allow_objects ) {
2014-02-10 02:10:30 +01:00
int strlen = p_str . length ( ) ;
CharString cstr = p_str . ascii ( ) ;
2020-02-17 22:06:54 +01:00
Vector < uint8_t > buf ;
2014-06-11 15:41:03 +02:00
buf . resize ( strlen / 4 * 3 + 1 ) ;
2020-02-17 22:06:54 +01:00
uint8_t * w = buf . ptrw ( ) ;
2014-02-10 02:10:30 +01:00
2019-07-02 03:06:52 +02:00
size_t len = 0 ;
ERR_FAIL_COND_V ( CryptoCore : : b64_decode ( & w [ 0 ] , buf . size ( ) , & len , ( unsigned char * ) cstr . get_data ( ) , strlen ) ! = OK , Variant ( ) ) ;
2014-02-10 02:10:30 +01:00
Variant v ;
2020-04-02 01:20:12 +02:00
Error err = decode_variant ( v , & w [ 0 ] , len , nullptr , p_allow_objects ) ;
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( err ! = OK , Variant ( ) , " Error when trying to decode Variant. " ) ;
2014-02-10 02:10:30 +01:00
return v ;
2020-05-19 15:46:49 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
String Marshalls : : raw_to_base64 ( const Vector < uint8_t > & p_arr ) {
2020-02-17 22:06:54 +01:00
String ret = CryptoCore : : b64_encode_str ( p_arr . ptr ( ) , p_arr . size ( ) ) ;
2021-12-09 10:42:46 +01:00
ERR_FAIL_COND_V ( ret . is_empty ( ) , ret ) ;
2015-07-28 12:50:52 +02:00
return ret ;
2020-05-19 15:46:49 +02:00
}
2015-07-28 12:50:52 +02:00
2021-08-13 16:46:14 +02:00
Vector < uint8_t > Marshalls : : base64_to_raw ( const String & p_str ) {
2015-07-28 12:50:52 +02:00
int strlen = p_str . length ( ) ;
CharString cstr = p_str . ascii ( ) ;
2019-07-02 03:06:52 +02:00
size_t arr_len = 0 ;
2020-02-17 22:06:54 +01:00
Vector < uint8_t > buf ;
2015-07-28 12:50:52 +02:00
{
buf . resize ( strlen / 4 * 3 + 1 ) ;
2020-02-17 22:06:54 +01:00
uint8_t * w = buf . ptrw ( ) ;
2015-07-28 12:50:52 +02:00
2020-02-17 22:06:54 +01:00
ERR_FAIL_COND_V ( CryptoCore : : b64_decode ( & w [ 0 ] , buf . size ( ) , & arr_len , ( unsigned char * ) cstr . get_data ( ) , strlen ) ! = OK , Vector < uint8_t > ( ) ) ;
2019-07-02 03:06:52 +02:00
}
2015-07-28 12:50:52 +02:00
buf . resize ( arr_len ) ;
return buf ;
2020-05-19 15:46:49 +02:00
}
2015-07-28 12:50:52 +02:00
2021-08-13 16:46:14 +02:00
String Marshalls : : utf8_to_base64 ( const String & p_str ) {
2015-07-28 12:50:52 +02:00
CharString cstr = p_str . utf8 ( ) ;
2019-07-02 17:47:34 +02:00
String ret = CryptoCore : : b64_encode_str ( ( unsigned char * ) cstr . get_data ( ) , cstr . length ( ) ) ;
2021-12-09 10:42:46 +01:00
ERR_FAIL_COND_V ( ret . is_empty ( ) , ret ) ;
2015-07-28 12:50:52 +02:00
return ret ;
2020-05-19 15:46:49 +02:00
}
2015-07-28 12:50:52 +02:00
2021-08-13 16:46:14 +02:00
String Marshalls : : base64_to_utf8 ( const String & p_str ) {
2015-07-28 12:50:52 +02:00
int strlen = p_str . length ( ) ;
CharString cstr = p_str . ascii ( ) ;
2020-02-17 22:06:54 +01:00
Vector < uint8_t > buf ;
2015-07-28 12:50:52 +02:00
buf . resize ( strlen / 4 * 3 + 1 + 1 ) ;
2020-02-17 22:06:54 +01:00
uint8_t * w = buf . ptrw ( ) ;
2015-07-28 12:50:52 +02:00
2019-07-02 03:06:52 +02:00
size_t len = 0 ;
ERR_FAIL_COND_V ( CryptoCore : : b64_decode ( & w [ 0 ] , buf . size ( ) , & len , ( unsigned char * ) cstr . get_data ( ) , strlen ) ! = OK , String ( ) ) ;
2015-07-28 12:50:52 +02:00
w [ len ] = 0 ;
2017-03-05 16:44:50 +01:00
String ret = String : : utf8 ( ( char * ) & w [ 0 ] ) ;
2015-07-28 12:50:52 +02:00
return ret ;
2020-05-19 15:46:49 +02:00
}
2015-07-28 12:50:52 +02:00
2021-08-13 16:46:14 +02:00
void Marshalls : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " variant_to_base64 " , " variant " , " full_objects " ) , & Marshalls : : variant_to_base64 , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " base64_to_variant " , " base64_str " , " allow_objects " ) , & Marshalls : : base64_to_variant , DEFVAL ( false ) ) ;
2015-07-28 12:50:52 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " raw_to_base64 " , " array " ) , & Marshalls : : raw_to_base64 ) ;
ClassDB : : bind_method ( D_METHOD ( " base64_to_raw " , " base64_str " ) , & Marshalls : : base64_to_raw ) ;
2015-07-28 12:50:52 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " utf8_to_base64 " , " utf8_str " ) , & Marshalls : : utf8_to_base64 ) ;
ClassDB : : bind_method ( D_METHOD ( " base64_to_utf8 " , " base64_str " ) , & Marshalls : : base64_to_utf8 ) ;
2020-05-19 15:46:49 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
////// Semaphore //////
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
void Semaphore : : wait ( ) {
2020-03-03 09:26:42 +01:00
semaphore . wait ( ) ;
2014-02-10 02:10:30 +01:00
}
2023-01-27 11:04:41 +01:00
bool Semaphore : : try_wait ( ) {
return semaphore . try_wait ( ) ;
2014-02-10 02:10:30 +01:00
}
2024-08-27 05:12:10 +02:00
void Semaphore : : post ( int p_count ) {
ERR_FAIL_COND ( p_count < = 0 ) ;
semaphore . post ( p_count ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
void Semaphore : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " wait " ) , & Semaphore : : wait ) ;
ClassDB : : bind_method ( D_METHOD ( " try_wait " ) , & Semaphore : : try_wait ) ;
2024-08-27 05:12:10 +02:00
ClassDB : : bind_method ( D_METHOD ( " post " , " count " ) , & Semaphore : : post , DEFVAL ( 1 ) ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
////// Mutex //////
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
void Mutex : : lock ( ) {
2020-02-26 11:28:13 +01:00
mutex . lock ( ) ;
2014-02-10 02:10:30 +01:00
}
2023-01-27 11:04:41 +01:00
bool Mutex : : try_lock ( ) {
2020-02-26 11:28:13 +01:00
return mutex . try_lock ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
void Mutex : : unlock ( ) {
2020-02-26 11:28:13 +01:00
mutex . unlock ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
void Mutex : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " lock " ) , & Mutex : : lock ) ;
ClassDB : : bind_method ( D_METHOD ( " try_lock " ) , & Mutex : : try_lock ) ;
ClassDB : : bind_method ( D_METHOD ( " unlock " ) , & Mutex : : unlock ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
////// Thread //////
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
void Thread : : _start_func ( void * ud ) {
Ref < Thread > * tud = ( Ref < Thread > * ) ud ;
Ref < Thread > t = * tud ;
2015-05-18 17:45:53 +02:00
memdelete ( tud ) ;
2021-09-25 18:02:51 +02:00
2023-09-26 21:58:57 +02:00
if ( ! t - > target_callable . is_valid ( ) ) {
2021-10-06 06:28:24 +02:00
t - > running . clear ( ) ;
2021-09-25 18:02:51 +02:00
ERR_FAIL_MSG ( vformat ( " Could not call function '%s' on previously freed instance to start thread %s. " , t - > target_callable . get_method ( ) , t - > get_id ( ) ) ) ;
}
2023-06-07 19:40:30 +02:00
// Finding out a suitable name for the thread can involve querying a node, if the target is one.
// We know this is safe (unless the user is causing life cycle race conditions, which would be a bug on their part).
set_current_thread_safe_for_nodes ( true ) ;
2022-07-01 12:48:58 +02:00
String func_name = t - > target_callable . is_custom ( ) ? t - > target_callable . get_custom ( ) - > get_as_text ( ) : String ( t - > target_callable . get_method ( ) ) ;
2023-06-07 19:40:30 +02:00
set_current_thread_safe_for_nodes ( false ) ;
2022-07-01 12:48:58 +02:00
: : Thread : : set_name ( func_name ) ;
2015-12-18 07:06:51 +01:00
2023-01-28 13:34:06 +01:00
// To avoid a circular reference between the thread and the script which can possibly contain a reference
// to the thread, we will do the call (keeping a reference up to that point) and then break chains with it.
// When the call returns, we will reference the thread again if possible.
ObjectID th_instance_id = t - > get_instance_id ( ) ;
Callable target_callable = t - > target_callable ;
t = Ref < Thread > ( ) ;
2022-06-23 02:15:38 +02:00
Callable : : CallError ce ;
2023-01-28 13:34:06 +01:00
Variant ret ;
target_callable . callp ( nullptr , 0 , ret , ce ) ;
// If script properly kept a reference to the thread, we should be able to re-reference it now
// (well, or if the call failed, since we had to break chains anyway because the outcome isn't known upfront).
t = Ref < Thread > ( ObjectDB : : get_instance ( th_instance_id ) ) ;
if ( t . is_valid ( ) ) {
t - > ret = ret ;
2021-10-06 06:28:24 +02:00
t - > running . clear ( ) ;
2023-01-28 13:34:06 +01:00
} else {
// We could print a warning here, but the Thread object will be eventually destroyed
// noticing wait_to_finish() hasn't been called on it, and it will print a warning itself.
2014-02-10 02:10:30 +01:00
}
2021-10-06 06:28:24 +02:00
2023-01-28 13:34:06 +01:00
if ( ce . error ! = Callable : : CallError : : CALL_OK ) {
ERR_FAIL_MSG ( " Could not call function ' " + func_name + " ' to start thread " + t - > get_id ( ) + " : " + Variant : : get_callable_error_text ( t - > target_callable , nullptr , 0 , ce ) + " . " ) ;
}
2014-02-10 02:10:30 +01:00
}
2022-06-23 02:15:38 +02:00
Error Thread : : start ( const Callable & p_callable , Priority p_priority ) {
2021-10-06 06:28:24 +02:00
ERR_FAIL_COND_V_MSG ( is_started ( ) , ERR_ALREADY_IN_USE , " Thread already started. " ) ;
2022-01-04 14:44:47 +01:00
ERR_FAIL_COND_V ( ! p_callable . is_valid ( ) , ERR_INVALID_PARAMETER ) ;
2019-04-07 18:52:39 +02:00
ERR_FAIL_INDEX_V ( p_priority , PRIORITY_MAX , ERR_INVALID_PARAMETER ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ret = Variant ( ) ;
2021-09-25 15:07:13 +02:00
target_callable = p_callable ;
2021-10-06 06:28:24 +02:00
running . set ( ) ;
2014-02-10 02:10:30 +01:00
2021-08-13 16:46:14 +02:00
Ref < Thread > * ud = memnew ( Ref < Thread > ( this ) ) ;
2015-05-18 17:45:53 +02:00
2021-08-13 16:46:14 +02:00
: : Thread : : Settings s ;
s . priority = ( : : Thread : : Priority ) p_priority ;
2021-01-19 13:29:41 +01:00
thread . start ( _start_func , ud , s ) ;
2014-02-10 02:10:30 +01:00
return OK ;
}
2021-08-13 16:46:14 +02:00
String Thread : : get_id ( ) const {
2021-01-19 13:29:41 +01:00
return itos ( thread . get_id ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2021-10-06 06:28:24 +02:00
bool Thread : : is_started ( ) const {
return thread . is_started ( ) ;
}
bool Thread : : is_alive ( ) const {
return running . is_set ( ) ;
2014-02-10 02:10:30 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Variant Thread : : wait_to_finish ( ) {
2021-10-06 06:28:24 +02:00
ERR_FAIL_COND_V_MSG ( ! is_started ( ) , Variant ( ) , " Thread must have been started to wait for its completion. " ) ;
2021-01-19 13:29:41 +01:00
thread . wait_to_finish ( ) ;
2014-02-10 02:10:30 +01:00
Variant r = ret ;
2021-09-25 15:07:13 +02:00
target_callable = Callable ( ) ;
2014-02-10 02:10:30 +01:00
return r ;
}
2023-06-08 11:33:35 +02:00
void Thread : : set_thread_safety_checks_enabled ( bool p_enabled ) {
ERR_FAIL_COND_MSG ( : : Thread : : is_main_thread ( ) , " This call is forbidden on the main thread. " ) ;
set_current_thread_safe_for_nodes ( ! p_enabled ) ;
}
2021-08-13 16:46:14 +02:00
void Thread : : _bind_methods ( ) {
2022-06-23 02:15:38 +02:00
ClassDB : : bind_method ( D_METHOD ( " start " , " callable " , " priority " ) , & Thread : : start , DEFVAL ( PRIORITY_NORMAL ) ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_id " ) , & Thread : : get_id ) ;
2021-10-06 06:28:24 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_started " ) , & Thread : : is_started ) ;
ClassDB : : bind_method ( D_METHOD ( " is_alive " ) , & Thread : : is_alive ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " wait_to_finish " ) , & Thread : : wait_to_finish ) ;
2014-02-10 02:10:30 +01:00
2023-06-08 11:33:35 +02:00
ClassDB : : bind_static_method ( " Thread " , D_METHOD ( " set_thread_safety_checks_enabled " , " enabled " ) , & Thread : : set_thread_safety_checks_enabled ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( PRIORITY_LOW ) ;
BIND_ENUM_CONSTANT ( PRIORITY_NORMAL ) ;
BIND_ENUM_CONSTANT ( PRIORITY_HIGH ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-13 16:46:14 +02:00
namespace special {
////// ClassDB //////
2017-01-03 03:03:46 +01:00
2021-08-13 16:46:14 +02:00
PackedStringArray ClassDB : : get_class_list ( ) const {
2017-01-03 03:03:46 +01:00
List < StringName > classes ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_class_list ( & classes ) ;
2017-01-03 03:03:46 +01:00
2020-02-17 22:06:54 +01:00
PackedStringArray ret ;
2017-01-03 03:03:46 +01:00
ret . resize ( classes . size ( ) ) ;
2017-03-05 16:44:50 +01:00
int idx = 0 ;
2021-07-24 15:46:25 +02:00
for ( const StringName & E : classes ) {
2021-07-16 05:45:57 +02:00
ret . set ( idx + + , E ) ;
2017-01-03 03:03:46 +01:00
}
return ret ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
PackedStringArray ClassDB : : get_inheriters_from_class ( const StringName & p_class ) const {
2017-01-03 03:03:46 +01:00
List < StringName > classes ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_inheriters_from_class ( p_class , & classes ) ;
2017-01-03 03:03:46 +01:00
2020-02-17 22:06:54 +01:00
PackedStringArray ret ;
2017-01-03 03:03:46 +01:00
ret . resize ( classes . size ( ) ) ;
2017-03-05 16:44:50 +01:00
int idx = 0 ;
2021-07-24 15:46:25 +02:00
for ( const StringName & E : classes ) {
2021-07-16 05:45:57 +02:00
ret . set ( idx + + , E ) ;
2017-01-03 03:03:46 +01:00
}
return ret ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
StringName ClassDB : : get_parent_class ( const StringName & p_class ) const {
return : : ClassDB : : get_parent_class ( p_class ) ;
2017-01-03 03:03:46 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool ClassDB : : class_exists ( const StringName & p_class ) const {
return : : ClassDB : : class_exists ( p_class ) ;
2017-01-03 03:03:46 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool ClassDB : : is_parent_class ( const StringName & p_class , const StringName & p_inherits ) const {
return : : ClassDB : : is_parent_class ( p_class , p_inherits ) ;
2017-01-03 03:03:46 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool ClassDB : : can_instantiate ( const StringName & p_class ) const {
return : : ClassDB : : can_instantiate ( p_class ) ;
2017-01-03 03:03:46 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Variant ClassDB : : instantiate ( const StringName & p_class ) const {
Object * obj = : : ClassDB : : instantiate ( p_class ) ;
2020-05-14 16:41:43 +02:00
if ( ! obj ) {
2017-01-03 03:03:46 +01:00
return Variant ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-01-03 03:03:46 +01:00
2021-06-04 18:03:15 +02:00
RefCounted * r = Object : : cast_to < RefCounted > ( obj ) ;
2017-01-03 03:03:46 +01:00
if ( r ) {
2022-05-03 01:43:50 +02:00
return Ref < RefCounted > ( r ) ;
2017-01-03 03:03:46 +01:00
} else {
return obj ;
}
}
2021-08-01 21:47:20 +02:00
bool ClassDB : : class_has_signal ( const StringName & p_class , const StringName & p_signal ) const {
2021-08-13 16:46:14 +02:00
return : : ClassDB : : has_signal ( p_class , p_signal ) ;
2017-01-03 03:03:46 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-01 21:47:20 +02:00
Dictionary ClassDB : : class_get_signal ( const StringName & p_class , const StringName & p_signal ) const {
2017-01-03 03:03:46 +01:00
MethodInfo signal ;
2021-08-13 16:46:14 +02:00
if ( : : ClassDB : : get_signal ( p_class , p_signal , & signal ) ) {
2017-01-03 03:03:46 +01:00
return signal . operator Dictionary ( ) ;
} else {
return Dictionary ( ) ;
}
}
2020-05-14 14:29:06 +02:00
2021-08-01 21:47:20 +02:00
TypedArray < Dictionary > ClassDB : : class_get_signal_list ( const StringName & p_class , bool p_no_inheritance ) const {
2017-01-03 03:03:46 +01:00
List < MethodInfo > signals ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_signal_list ( p_class , & signals , p_no_inheritance ) ;
2022-08-05 03:41:48 +02:00
TypedArray < Dictionary > ret ;
2017-01-03 03:03:46 +01:00
2021-07-24 15:46:25 +02:00
for ( const MethodInfo & E : signals ) {
2021-07-16 05:45:57 +02:00
ret . push_back ( E . operator Dictionary ( ) ) ;
2017-01-03 03:03:46 +01:00
}
return ret ;
}
2021-08-01 21:47:20 +02:00
TypedArray < Dictionary > ClassDB : : class_get_property_list ( const StringName & p_class , bool p_no_inheritance ) const {
2017-01-03 03:03:46 +01:00
List < PropertyInfo > plist ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_property_list ( p_class , & plist , p_no_inheritance ) ;
2022-08-05 03:41:48 +02:00
TypedArray < Dictionary > ret ;
2021-07-24 15:46:25 +02:00
for ( const PropertyInfo & E : plist ) {
2021-07-16 05:45:57 +02:00
ret . push_back ( E . operator Dictionary ( ) ) ;
2017-01-03 03:03:46 +01:00
}
return ret ;
}
2024-07-27 05:53:13 +02:00
StringName ClassDB : : class_get_property_getter ( const StringName & p_class , const StringName & p_property ) {
return : : ClassDB : : get_property_getter ( p_class , p_property ) ;
}
StringName ClassDB : : class_get_property_setter ( const StringName & p_class , const StringName & p_property ) {
return : : ClassDB : : get_property_setter ( p_class , p_property ) ;
}
2023-05-12 13:53:15 +02:00
Variant ClassDB : : class_get_property ( Object * p_object , const StringName & p_property ) const {
2017-04-09 13:26:48 +02:00
Variant ret ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_property ( p_object , p_property , ret ) ;
2017-04-09 13:26:48 +02:00
return ret ;
}
2023-05-12 13:53:15 +02:00
Error ClassDB : : class_set_property ( Object * p_object , const StringName & p_property , const Variant & p_value ) const {
2017-04-09 13:26:48 +02:00
Variant ret ;
bool valid ;
2021-08-13 16:46:14 +02:00
if ( ! : : ClassDB : : set_property ( p_object , p_property , p_value , & valid ) ) {
2017-04-09 13:26:48 +02:00
return ERR_UNAVAILABLE ;
} else if ( ! valid ) {
return ERR_INVALID_DATA ;
}
return OK ;
}
2024-04-19 19:51:28 +02:00
Variant ClassDB : : class_get_property_default_value ( const StringName & p_class , const StringName & p_property ) const {
bool valid ;
Variant ret = : : ClassDB : : class_get_default_property_value ( p_class , p_property , & valid ) ;
if ( valid ) {
return ret ;
}
return Variant ( ) ;
}
2021-08-01 21:47:20 +02:00
bool ClassDB : : class_has_method ( const StringName & p_class , const StringName & p_method , bool p_no_inheritance ) const {
2021-08-13 16:46:14 +02:00
return : : ClassDB : : has_method ( p_class , p_method , p_no_inheritance ) ;
2017-01-03 03:03:46 +01:00
}
2024-01-28 15:16:09 +01:00
int ClassDB : : class_get_method_argument_count ( const StringName & p_class , const StringName & p_method , bool p_no_inheritance ) const {
return : : ClassDB : : get_method_argument_count ( p_class , p_method , nullptr , p_no_inheritance ) ;
}
2021-08-01 21:47:20 +02:00
TypedArray < Dictionary > ClassDB : : class_get_method_list ( const StringName & p_class , bool p_no_inheritance ) const {
2017-01-03 03:03:46 +01:00
List < MethodInfo > methods ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_method_list ( p_class , & methods , p_no_inheritance ) ;
2022-08-05 03:41:48 +02:00
TypedArray < Dictionary > ret ;
2017-01-03 03:03:46 +01:00
2021-07-24 15:46:25 +02:00
for ( const MethodInfo & E : methods ) {
2018-01-04 19:04:05 +01:00
# ifdef DEBUG_METHODS_ENABLED
2021-07-16 05:45:57 +02:00
ret . push_back ( E . operator Dictionary ( ) ) ;
2018-01-04 19:04:05 +01:00
# else
Dictionary dict ;
2021-07-16 05:45:57 +02:00
dict [ " name " ] = E . name ;
2018-01-04 19:04:05 +01:00
ret . push_back ( dict ) ;
# endif
2017-01-03 03:03:46 +01:00
}
return ret ;
}
2024-08-23 01:56:29 +02:00
Variant ClassDB : : class_call_static_method ( const Variant * * p_arguments , int p_argcount , Callable : : CallError & r_call_error ) {
if ( p_argcount < 2 ) {
r_call_error . error = Callable : : CallError : : CALL_ERROR_TOO_FEW_ARGUMENTS ;
return Variant : : NIL ;
}
if ( ! p_arguments [ 0 ] - > is_string ( ) | | ! p_arguments [ 1 ] - > is_string ( ) ) {
r_call_error . error = Callable : : CallError : : CALL_ERROR_INVALID_ARGUMENT ;
return Variant : : NIL ;
}
StringName class_ = * p_arguments [ 0 ] ;
StringName method = * p_arguments [ 1 ] ;
const MethodBind * bind = : : ClassDB : : get_method ( class_ , method ) ;
ERR_FAIL_NULL_V_MSG ( bind , Variant : : NIL , " Cannot find static method. " ) ;
ERR_FAIL_COND_V_MSG ( ! bind - > is_static ( ) , Variant : : NIL , " Method is not static. " ) ;
return bind - > call ( nullptr , p_arguments + 2 , p_argcount - 2 , r_call_error ) ;
}
2023-05-12 13:53:15 +02:00
PackedStringArray ClassDB : : class_get_integer_constant_list ( const StringName & p_class , bool p_no_inheritance ) const {
2017-01-03 03:03:46 +01:00
List < String > constants ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_integer_constant_list ( p_class , & constants , p_no_inheritance ) ;
2017-01-03 03:03:46 +01:00
2020-02-17 22:06:54 +01:00
PackedStringArray ret ;
2017-01-03 03:03:46 +01:00
ret . resize ( constants . size ( ) ) ;
2017-03-05 16:44:50 +01:00
int idx = 0 ;
2021-07-24 15:46:25 +02:00
for ( const String & E : constants ) {
2021-07-16 05:45:57 +02:00
ret . set ( idx + + , E ) ;
2017-01-03 03:03:46 +01:00
}
return ret ;
}
2023-05-12 13:53:15 +02:00
bool ClassDB : : class_has_integer_constant ( const StringName & p_class , const StringName & p_name ) const {
2017-01-03 03:03:46 +01:00
bool success ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_integer_constant ( p_class , p_name , & success ) ;
2017-01-03 03:03:46 +01:00
return success ;
}
2023-05-12 13:53:15 +02:00
int64_t ClassDB : : class_get_integer_constant ( const StringName & p_class , const StringName & p_name ) const {
2017-01-03 03:03:46 +01:00
bool found ;
2022-05-09 11:47:10 +02:00
int64_t c = : : ClassDB : : get_integer_constant ( p_class , p_name , & found ) ;
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( ! found , 0 ) ;
2017-01-03 03:03:46 +01:00
return c ;
}
2020-05-14 14:29:06 +02:00
2023-05-12 13:53:15 +02:00
bool ClassDB : : class_has_enum ( const StringName & p_class , const StringName & p_name , bool p_no_inheritance ) const {
2021-09-11 14:31:11 +02:00
return : : ClassDB : : has_enum ( p_class , p_name , p_no_inheritance ) ;
}
2023-05-12 13:53:15 +02:00
PackedStringArray ClassDB : : class_get_enum_list ( const StringName & p_class , bool p_no_inheritance ) const {
2021-09-11 14:31:11 +02:00
List < StringName > enums ;
: : ClassDB : : get_enum_list ( p_class , & enums , p_no_inheritance ) ;
PackedStringArray ret ;
ret . resize ( enums . size ( ) ) ;
int idx = 0 ;
for ( const StringName & E : enums ) {
ret . set ( idx + + , E ) ;
}
return ret ;
}
2023-05-12 13:53:15 +02:00
PackedStringArray ClassDB : : class_get_enum_constants ( const StringName & p_class , const StringName & p_enum , bool p_no_inheritance ) const {
2021-09-11 14:31:11 +02:00
List < StringName > constants ;
: : ClassDB : : get_enum_constants ( p_class , p_enum , & constants , p_no_inheritance ) ;
PackedStringArray ret ;
ret . resize ( constants . size ( ) ) ;
int idx = 0 ;
for ( const StringName & E : constants ) {
ret . set ( idx + + , E ) ;
}
return ret ;
}
2023-05-12 13:53:15 +02:00
StringName ClassDB : : class_get_integer_constant_enum ( const StringName & p_class , const StringName & p_name , bool p_no_inheritance ) const {
2021-09-11 14:31:11 +02:00
return : : ClassDB : : get_integer_constant_enum ( p_class , p_name , p_no_inheritance ) ;
}
2024-04-08 01:21:19 +02:00
bool ClassDB : : is_class_enum_bitfield ( const StringName & p_class , const StringName & p_enum , bool p_no_inheritance ) const {
return : : ClassDB : : is_enum_bitfield ( p_class , p_enum , p_no_inheritance ) ;
}
2021-08-01 21:47:20 +02:00
bool ClassDB : : is_class_enabled ( const StringName & p_class ) const {
2021-08-13 16:46:14 +02:00
return : : ClassDB : : is_class_enabled ( p_class ) ;
2017-01-03 03:03:46 +01:00
}
2024-01-04 00:20:55 +01:00
# ifdef TOOLS_ENABLED
void ClassDB : : get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const {
const String pf = p_function ;
bool first_argument_is_class = false ;
if ( p_idx = = 0 ) {
first_argument_is_class = ( pf = = " get_inheriters_from_class " | | pf = = " get_parent_class " | |
pf = = " class_exists " | | pf = = " can_instantiate " | | pf = = " instantiate " | |
pf = = " class_has_signal " | | pf = = " class_get_signal " | | pf = = " class_get_signal_list " | |
pf = = " class_get_property_list " | | pf = = " class_get_property " | | pf = = " class_set_property " | |
pf = = " class_has_method " | | pf = = " class_get_method_list " | |
pf = = " class_get_integer_constant_list " | | pf = = " class_has_integer_constant " | | pf = = " class_get_integer_constant " | |
pf = = " class_has_enum " | | pf = = " class_get_enum_list " | | pf = = " class_get_enum_constants " | | pf = = " class_get_integer_constant_enum " | |
2024-04-08 01:21:19 +02:00
pf = = " is_class_enabled " | | pf = = " is_class_enum_bitfield " ) ;
2024-01-04 00:20:55 +01:00
}
if ( first_argument_is_class | | pf = = " is_parent_class " ) {
for ( const String & E : get_class_list ( ) ) {
r_options - > push_back ( E . quote ( ) ) ;
}
}
Object : : get_argument_options ( p_function , p_idx , r_options ) ;
}
# endif
2021-08-13 16:46:14 +02:00
void ClassDB : : _bind_methods ( ) {
: : ClassDB : : bind_method ( D_METHOD ( " get_class_list " ) , & ClassDB : : get_class_list ) ;
: : ClassDB : : bind_method ( D_METHOD ( " get_inheriters_from_class " , " class " ) , & ClassDB : : get_inheriters_from_class ) ;
: : ClassDB : : bind_method ( D_METHOD ( " get_parent_class " , " class " ) , & ClassDB : : get_parent_class ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_exists " , " class " ) , & ClassDB : : class_exists ) ;
: : ClassDB : : bind_method ( D_METHOD ( " is_parent_class " , " class " , " inherits " ) , & ClassDB : : is_parent_class ) ;
: : ClassDB : : bind_method ( D_METHOD ( " can_instantiate " , " class " ) , & ClassDB : : can_instantiate ) ;
: : ClassDB : : bind_method ( D_METHOD ( " instantiate " , " class " ) , & ClassDB : : instantiate ) ;
2017-01-03 03:03:46 +01:00
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_signal " , " class " , " signal " ) , & ClassDB : : class_has_signal ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_signal " , " class " , " signal " ) , & ClassDB : : class_get_signal ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_signal_list " , " class " , " no_inheritance " ) , & ClassDB : : class_get_signal_list , DEFVAL ( false ) ) ;
2017-01-03 03:03:46 +01:00
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property_list " , " class " , " no_inheritance " ) , & ClassDB : : class_get_property_list , DEFVAL ( false ) ) ;
2024-07-27 05:53:13 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property_getter " , " class " , " property " ) , & ClassDB : : class_get_property_getter ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property_setter " , " class " , " property " ) , & ClassDB : : class_get_property_setter ) ;
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property " , " object " , " property " ) , & ClassDB : : class_get_property ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_set_property " , " object " , " property " , " value " ) , & ClassDB : : class_set_property ) ;
2017-01-03 03:03:46 +01:00
2024-04-19 19:51:28 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property_default_value " , " class " , " property " ) , & ClassDB : : class_get_property_default_value ) ;
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_method " , " class " , " method " , " no_inheritance " ) , & ClassDB : : class_has_method , DEFVAL ( false ) ) ;
2017-01-03 03:03:46 +01:00
2024-01-28 15:16:09 +01:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_method_argument_count " , " class " , " method " , " no_inheritance " ) , & ClassDB : : class_get_method_argument_count , DEFVAL ( false ) ) ;
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_method_list " , " class " , " no_inheritance " ) , & ClassDB : : class_get_method_list , DEFVAL ( false ) ) ;
2017-01-03 03:03:46 +01:00
2024-08-23 01:56:29 +02:00
: : ClassDB : : bind_vararg_method ( METHOD_FLAGS_DEFAULT , " class_call_static_method " , & ClassDB : : class_call_static_method , MethodInfo ( " class_call_static_method " , PropertyInfo ( Variant : : STRING_NAME , " class " ) , PropertyInfo ( Variant : : STRING_NAME , " method " ) ) ) ;
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_integer_constant_list " , " class " , " no_inheritance " ) , & ClassDB : : class_get_integer_constant_list , DEFVAL ( false ) ) ;
2017-01-03 03:03:46 +01:00
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_integer_constant " , " class " , " name " ) , & ClassDB : : class_has_integer_constant ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_integer_constant " , " class " , " name " ) , & ClassDB : : class_get_integer_constant ) ;
2017-01-03 03:03:46 +01:00
2023-05-12 13:53:15 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_enum " , " class " , " name " , " no_inheritance " ) , & ClassDB : : class_has_enum , DEFVAL ( false ) ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_enum_list " , " class " , " no_inheritance " ) , & ClassDB : : class_get_enum_list , DEFVAL ( false ) ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_enum_constants " , " class " , " enum " , " no_inheritance " ) , & ClassDB : : class_get_enum_constants , DEFVAL ( false ) ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_integer_constant_enum " , " class " , " name " , " no_inheritance " ) , & ClassDB : : class_get_integer_constant_enum , DEFVAL ( false ) ) ;
2021-09-11 14:31:11 +02:00
2024-04-08 01:21:19 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " is_class_enum_bitfield " , " class " , " enum " , " no_inheritance " ) , & ClassDB : : is_class_enum_bitfield , DEFVAL ( false ) ) ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " is_class_enabled " , " class " ) , & ClassDB : : is_class_enabled ) ;
2017-01-03 03:03:46 +01:00
}
2021-08-13 16:46:14 +02:00
} // namespace special
2017-01-13 16:51:14 +01:00
2021-08-13 16:46:14 +02:00
////// Engine //////
void Engine : : set_physics_ticks_per_second ( int p_ips ) {
: : Engine : : get_singleton ( ) - > set_physics_ticks_per_second ( p_ips ) ;
2017-01-13 16:51:14 +01:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
int Engine : : get_physics_ticks_per_second ( ) const {
return : : Engine : : get_singleton ( ) - > get_physics_ticks_per_second ( ) ;
2017-01-13 16:51:14 +01:00
}
2022-09-15 18:57:34 +02:00
void Engine : : set_max_physics_steps_per_frame ( int p_max_physics_steps ) {
: : Engine : : get_singleton ( ) - > set_max_physics_steps_per_frame ( p_max_physics_steps ) ;
}
int Engine : : get_max_physics_steps_per_frame ( ) const {
return : : Engine : : get_singleton ( ) - > get_max_physics_steps_per_frame ( ) ;
}
2021-08-13 16:46:14 +02:00
void Engine : : set_physics_jitter_fix ( double p_threshold ) {
: : Engine : : get_singleton ( ) - > set_physics_jitter_fix ( p_threshold ) ;
Add hysteresis to physics timestep count per frame
Add new class _TimerSync to manage timestep calculations.
The new class handles the decisions about simulation progression
previously handled by main::iteration(). It is fed the current timer
ticks and determines how many physics updates are to be run and what
the delta argument to the _process() functions should be.
The new class tries to keep the number of physics updates per frame as
constant as possible from frame to frame. Ideally, it would be N steps
every render frame, but even with perfectly regular rendering, the
general case is that N or N+1 steps are required per frame, for some
fixed N. The best guess for N is stored in typical_physics_steps.
When determining the number of steps to take, no restrictions are
imposed between the choice of typical_physics_steps and
typical_physics_steps+1 steps. Should more or less steps than that be
required, the accumulated remaining time (as before, stored in
time_accum) needs to surpass its boundaries by some minimal threshold.
Once surpassed, typical_physics_steps is updated to allow the new step
count for future updates.
Care is taken that the modified calculation of the number of physics
steps is not observable from game code that only checks the delta
parameters to the _process and _physics_process functions; in addition
to modifying the number of steps, the _process argument is modified as
well to stay in expected bounds. Extra care is taken that the accumulated
steps still sum up to roughly the real elapsed time, up to a maximum
tolerated difference.
To allow the hysteresis code to work correctly on higher refresh
monitors, the number of typical physics steps is not only recorded and
kept consistent for single render frames, but for groups of them.
Currently, up to 12 frames are grouped that way.
The engine parameter physics_jitter_fix controls both the maximum
tolerated difference between wall clock time and summed up _process
arguments and the threshold for changing typical_physics_steps. It is
given in units of the real physics frame slice 1/physics_fps. Set
physics_jitter_fix to 0 to disable the effects of the new code here.
It starts to be effective against the random physics jitter at around
0.02 to 0.05. at values greater than 1 it starts having ill effects on
the engine's ability to react sensibly to dropped frames and framerate
changes.
2018-02-11 00:03:31 +01:00
}
2021-08-13 16:46:14 +02:00
double Engine : : get_physics_jitter_fix ( ) const {
return : : Engine : : get_singleton ( ) - > get_physics_jitter_fix ( ) ;
Add hysteresis to physics timestep count per frame
Add new class _TimerSync to manage timestep calculations.
The new class handles the decisions about simulation progression
previously handled by main::iteration(). It is fed the current timer
ticks and determines how many physics updates are to be run and what
the delta argument to the _process() functions should be.
The new class tries to keep the number of physics updates per frame as
constant as possible from frame to frame. Ideally, it would be N steps
every render frame, but even with perfectly regular rendering, the
general case is that N or N+1 steps are required per frame, for some
fixed N. The best guess for N is stored in typical_physics_steps.
When determining the number of steps to take, no restrictions are
imposed between the choice of typical_physics_steps and
typical_physics_steps+1 steps. Should more or less steps than that be
required, the accumulated remaining time (as before, stored in
time_accum) needs to surpass its boundaries by some minimal threshold.
Once surpassed, typical_physics_steps is updated to allow the new step
count for future updates.
Care is taken that the modified calculation of the number of physics
steps is not observable from game code that only checks the delta
parameters to the _process and _physics_process functions; in addition
to modifying the number of steps, the _process argument is modified as
well to stay in expected bounds. Extra care is taken that the accumulated
steps still sum up to roughly the real elapsed time, up to a maximum
tolerated difference.
To allow the hysteresis code to work correctly on higher refresh
monitors, the number of typical physics steps is not only recorded and
kept consistent for single render frames, but for groups of them.
Currently, up to 12 frames are grouped that way.
The engine parameter physics_jitter_fix controls both the maximum
tolerated difference between wall clock time and summed up _process
arguments and the threshold for changing typical_physics_steps. It is
given in units of the real physics frame slice 1/physics_fps. Set
physics_jitter_fix to 0 to disable the effects of the new code here.
It starts to be effective against the random physics jitter at around
0.02 to 0.05. at values greater than 1 it starts having ill effects on
the engine's ability to react sensibly to dropped frames and framerate
changes.
2018-02-11 00:03:31 +01:00
}
2021-08-13 16:46:14 +02:00
double Engine : : get_physics_interpolation_fraction ( ) const {
return : : Engine : : get_singleton ( ) - > get_physics_interpolation_fraction ( ) ;
2019-07-01 18:42:02 +02:00
}
2022-09-22 22:15:07 +02:00
void Engine : : set_max_fps ( int p_fps ) {
: : Engine : : get_singleton ( ) - > set_max_fps ( p_fps ) ;
2017-01-13 16:51:14 +01:00
}
2022-09-22 22:15:07 +02:00
int Engine : : get_max_fps ( ) const {
return : : Engine : : get_singleton ( ) - > get_max_fps ( ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
double Engine : : get_frames_per_second ( ) const {
return : : Engine : : get_singleton ( ) - > get_frames_per_second ( ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
uint64_t Engine : : get_physics_frames ( ) const {
return : : Engine : : get_singleton ( ) - > get_physics_frames ( ) ;
2020-01-13 17:53:10 +01:00
}
2021-08-13 16:46:14 +02:00
uint64_t Engine : : get_process_frames ( ) const {
return : : Engine : : get_singleton ( ) - > get_process_frames ( ) ;
2020-01-13 17:53:10 +01:00
}
2021-08-13 16:46:14 +02:00
void Engine : : set_time_scale ( double p_scale ) {
: : Engine : : get_singleton ( ) - > set_time_scale ( p_scale ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
double Engine : : get_time_scale ( ) {
return : : Engine : : get_singleton ( ) - > get_time_scale ( ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
int Engine : : get_frames_drawn ( ) {
return : : Engine : : get_singleton ( ) - > get_frames_drawn ( ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
MainLoop * Engine : : get_main_loop ( ) const {
// Needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here
return : : OS : : get_singleton ( ) - > get_main_loop ( ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
Dictionary Engine : : get_version_info ( ) const {
return : : Engine : : get_singleton ( ) - > get_version_info ( ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
Dictionary Engine : : get_author_info ( ) const {
return : : Engine : : get_singleton ( ) - > get_author_info ( ) ;
2018-05-16 06:54:22 +02:00
}
2022-08-05 03:41:48 +02:00
TypedArray < Dictionary > Engine : : get_copyright_info ( ) const {
2021-08-13 16:46:14 +02:00
return : : Engine : : get_singleton ( ) - > get_copyright_info ( ) ;
2018-05-16 06:54:22 +02:00
}
2021-08-13 16:46:14 +02:00
Dictionary Engine : : get_donor_info ( ) const {
return : : Engine : : get_singleton ( ) - > get_donor_info ( ) ;
2018-05-16 06:54:22 +02:00
}
2021-08-13 16:46:14 +02:00
Dictionary Engine : : get_license_info ( ) const {
return : : Engine : : get_singleton ( ) - > get_license_info ( ) ;
2018-05-16 06:54:22 +02:00
}
2021-08-13 16:46:14 +02:00
String Engine : : get_license_text ( ) const {
return : : Engine : : get_singleton ( ) - > get_license_text ( ) ;
2018-05-16 06:54:22 +02:00
}
2022-07-20 19:05:49 +02:00
String Engine : : get_architecture_name ( ) const {
return : : Engine : : get_singleton ( ) - > get_architecture_name ( ) ;
}
2021-08-13 16:46:14 +02:00
bool Engine : : is_in_physics_frame ( ) const {
return : : Engine : : get_singleton ( ) - > is_in_physics_frame ( ) ;
2017-06-13 17:49:28 +02:00
}
2021-08-25 00:03:10 +02:00
bool Engine : : has_singleton ( const StringName & p_name ) const {
2021-08-13 16:46:14 +02:00
return : : Engine : : get_singleton ( ) - > has_singleton ( p_name ) ;
2017-11-13 21:46:57 +01:00
}
2021-08-25 00:03:10 +02:00
Object * Engine : : get_singleton_object ( const StringName & p_name ) const {
2021-08-13 16:46:14 +02:00
return : : Engine : : get_singleton ( ) - > get_singleton_object ( p_name ) ;
2017-11-13 21:46:57 +01:00
}
2021-08-25 00:03:10 +02:00
void Engine : : register_singleton ( const StringName & p_name , Object * p_object ) {
ERR_FAIL_COND_MSG ( has_singleton ( p_name ) , " Singleton already registered: " + String ( p_name ) ) ;
2024-08-23 08:30:51 +02:00
ERR_FAIL_COND_MSG ( ! String ( p_name ) . is_valid_ascii_identifier ( ) , " Singleton name is not a valid identifier: " + p_name ) ;
2021-08-25 00:03:10 +02:00
: : Engine : : Singleton s ;
s . class_name = p_name ;
s . name = p_name ;
s . ptr = p_object ;
s . user_created = true ;
: : Engine : : get_singleton ( ) - > add_singleton ( s ) ;
}
2022-02-16 13:56:32 +01:00
2021-08-25 00:03:10 +02:00
void Engine : : unregister_singleton ( const StringName & p_name ) {
Fix various typos
Found via ` codespell -q 3 -S ./thirdparty,*.po,./DONORS.md -L ackward,ang,ans,ba,beng,cas,childs,childrens,dof,doubleclick,expct,fave,findn,gird,hist,inout,leapyear,lod,nd,numer,ois,ony,paket,seeked,sinc,switchs,te,uint,varn`
Update editor/import/resource_importer_layered_texture.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update doc/classes/TileSetScenesCollectionSource.xml
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/gui/graph_edit.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/resources/animation.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/resources/animation.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/resources/animation.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Update scene/gui/rich_text_label.cpp
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Revert previously committed change
2022-01-02 07:03:58 +01:00
ERR_FAIL_COND_MSG ( ! has_singleton ( p_name ) , " Attempt to remove unregistered singleton: " + String ( p_name ) ) ;
2021-08-25 00:03:10 +02:00
ERR_FAIL_COND_MSG ( ! : : Engine : : get_singleton ( ) - > is_singleton_user_created ( p_name ) , " Attempt to remove non-user created singleton: " + String ( p_name ) ) ;
: : Engine : : get_singleton ( ) - > remove_singleton ( p_name ) ;
}
Vector < String > Engine : : get_singleton_list ( ) const {
List < : : Engine : : Singleton > singletons ;
: : Engine : : get_singleton ( ) - > get_singletons ( & singletons ) ;
Vector < String > ret ;
for ( List < : : Engine : : Singleton > : : Element * E = singletons . front ( ) ; E ; E = E - > next ( ) ) {
ret . push_back ( E - > get ( ) . name ) ;
}
return ret ;
}
2022-10-09 22:03:59 +02:00
Error Engine : : register_script_language ( ScriptLanguage * p_language ) {
return ScriptServer : : register_language ( p_language ) ;
}
Error Engine : : unregister_script_language ( const ScriptLanguage * p_language ) {
return ScriptServer : : unregister_language ( p_language ) ;
2022-03-26 16:48:43 +01:00
}
int Engine : : get_script_language_count ( ) {
return ScriptServer : : get_language_count ( ) ;
}
ScriptLanguage * Engine : : get_script_language ( int p_index ) const {
return ScriptServer : : get_language ( p_index ) ;
}
2021-08-13 16:46:14 +02:00
void Engine : : set_editor_hint ( bool p_enabled ) {
: : Engine : : get_singleton ( ) - > set_editor_hint ( p_enabled ) ;
2017-08-13 16:21:45 +02:00
}
2021-08-13 16:46:14 +02:00
bool Engine : : is_editor_hint ( ) const {
return : : Engine : : get_singleton ( ) - > is_editor_hint ( ) ;
2017-08-13 16:21:45 +02:00
}
2022-06-26 01:38:20 +02:00
String Engine : : get_write_movie_path ( ) const {
return : : Engine : : get_singleton ( ) - > get_write_movie_path ( ) ;
}
2021-08-13 16:46:14 +02:00
void Engine : : set_print_error_messages ( bool p_enabled ) {
: : Engine : : get_singleton ( ) - > set_print_error_messages ( p_enabled ) ;
2021-05-01 23:09:48 +02:00
}
2021-08-13 16:46:14 +02:00
bool Engine : : is_printing_error_messages ( ) const {
return : : Engine : : get_singleton ( ) - > is_printing_error_messages ( ) ;
2021-05-01 23:09:48 +02:00
}
2024-01-03 12:10:11 +01:00
# ifdef TOOLS_ENABLED
2024-01-03 18:29:05 +01:00
void Engine : : get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const {
2024-01-03 12:10:11 +01:00
const String pf = p_function ;
2024-01-03 18:29:05 +01:00
if ( p_idx = = 0 & & ( pf = = " has_singleton " | | pf = = " get_singleton " | | pf = = " unregister_singleton " ) ) {
for ( const String & E : get_singleton_list ( ) ) {
r_options - > push_back ( E . quote ( ) ) ;
}
}
Object : : get_argument_options ( p_function , p_idx , r_options ) ;
}
2024-01-03 12:10:11 +01:00
# endif
2024-01-03 18:29:05 +01:00
2021-08-13 16:46:14 +02:00
void Engine : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_physics_ticks_per_second " , " physics_ticks_per_second " ) , & Engine : : set_physics_ticks_per_second ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_ticks_per_second " ) , & Engine : : get_physics_ticks_per_second ) ;
2022-09-15 18:57:34 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_max_physics_steps_per_frame " , " max_physics_steps " ) , & Engine : : set_max_physics_steps_per_frame ) ;
ClassDB : : bind_method ( D_METHOD ( " get_max_physics_steps_per_frame " ) , & Engine : : get_max_physics_steps_per_frame ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_physics_jitter_fix " , " physics_jitter_fix " ) , & Engine : : set_physics_jitter_fix ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_jitter_fix " ) , & Engine : : get_physics_jitter_fix ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_interpolation_fraction " ) , & Engine : : get_physics_interpolation_fraction ) ;
2022-09-22 22:15:07 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_max_fps " , " max_fps " ) , & Engine : : set_max_fps ) ;
ClassDB : : bind_method ( D_METHOD ( " get_max_fps " ) , & Engine : : get_max_fps ) ;
2017-01-13 16:51:14 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_time_scale " , " time_scale " ) , & Engine : : set_time_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_time_scale " ) , & Engine : : get_time_scale ) ;
2017-01-13 16:51:14 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_frames_drawn " ) , & Engine : : get_frames_drawn ) ;
ClassDB : : bind_method ( D_METHOD ( " get_frames_per_second " ) , & Engine : : get_frames_per_second ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_frames " ) , & Engine : : get_physics_frames ) ;
ClassDB : : bind_method ( D_METHOD ( " get_process_frames " ) , & Engine : : get_process_frames ) ;
2017-01-13 16:51:14 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_main_loop " ) , & Engine : : get_main_loop ) ;
2017-01-13 16:51:14 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_version_info " ) , & Engine : : get_version_info ) ;
ClassDB : : bind_method ( D_METHOD ( " get_author_info " ) , & Engine : : get_author_info ) ;
ClassDB : : bind_method ( D_METHOD ( " get_copyright_info " ) , & Engine : : get_copyright_info ) ;
ClassDB : : bind_method ( D_METHOD ( " get_donor_info " ) , & Engine : : get_donor_info ) ;
ClassDB : : bind_method ( D_METHOD ( " get_license_info " ) , & Engine : : get_license_info ) ;
ClassDB : : bind_method ( D_METHOD ( " get_license_text " ) , & Engine : : get_license_text ) ;
2017-06-13 17:49:28 +02:00
2022-07-20 19:05:49 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_architecture_name " ) , & Engine : : get_architecture_name ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_in_physics_frame " ) , & Engine : : is_in_physics_frame ) ;
2017-08-13 16:21:45 +02:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " has_singleton " , " name " ) , & Engine : : has_singleton ) ;
ClassDB : : bind_method ( D_METHOD ( " get_singleton " , " name " ) , & Engine : : get_singleton_object ) ;
2017-11-13 21:46:57 +01:00
2021-08-25 00:03:10 +02:00
ClassDB : : bind_method ( D_METHOD ( " register_singleton " , " name " , " instance " ) , & Engine : : register_singleton ) ;
ClassDB : : bind_method ( D_METHOD ( " unregister_singleton " , " name " ) , & Engine : : unregister_singleton ) ;
ClassDB : : bind_method ( D_METHOD ( " get_singleton_list " ) , & Engine : : get_singleton_list ) ;
2022-03-26 16:48:43 +01:00
ClassDB : : bind_method ( D_METHOD ( " register_script_language " , " language " ) , & Engine : : register_script_language ) ;
2022-10-09 22:03:59 +02:00
ClassDB : : bind_method ( D_METHOD ( " unregister_script_language " , " language " ) , & Engine : : unregister_script_language ) ;
2022-03-26 16:48:43 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_script_language_count " ) , & Engine : : get_script_language_count ) ;
ClassDB : : bind_method ( D_METHOD ( " get_script_language " , " index " ) , & Engine : : get_script_language ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_editor_hint " ) , & Engine : : is_editor_hint ) ;
2018-01-11 23:35:12 +01:00
2022-06-26 01:38:20 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_write_movie_path " ) , & Engine : : get_write_movie_path ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_print_error_messages " , " enabled " ) , & Engine : : set_print_error_messages ) ;
ClassDB : : bind_method ( D_METHOD ( " is_printing_error_messages " ) , & Engine : : is_printing_error_messages ) ;
2021-05-01 23:09:48 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " print_error_messages " ) , " set_print_error_messages " , " is_printing_error_messages " ) ;
2021-08-11 02:35:16 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " physics_ticks_per_second " ) , " set_physics_ticks_per_second " , " get_physics_ticks_per_second " ) ;
2022-09-15 18:57:34 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " max_physics_steps_per_frame " ) , " set_max_physics_steps_per_frame " , " get_max_physics_steps_per_frame " ) ;
2022-09-22 22:15:07 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " max_fps " ) , " set_max_fps " , " get_max_fps " ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-24 19:20:53 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " time_scale " ) , " set_time_scale " , " get_time_scale " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " physics_jitter_fix " ) , " set_physics_jitter_fix " , " get_physics_jitter_fix " ) ;
2017-01-13 16:51:14 +01:00
}
2021-08-13 16:46:14 +02:00
Engine * Engine : : singleton = nullptr ;
2020-05-18 16:55:49 +02:00
2021-08-13 16:46:14 +02:00
////// EngineDebugger //////
2020-05-18 16:55:49 +02:00
2021-08-13 16:46:14 +02:00
bool EngineDebugger : : is_active ( ) {
return : : EngineDebugger : : is_active ( ) ;
2020-05-18 16:55:49 +02:00
}
2022-02-06 01:55:58 +01:00
void EngineDebugger : : register_profiler ( const StringName & p_name , Ref < EngineProfiler > p_profiler ) {
ERR_FAIL_COND ( p_profiler . is_null ( ) ) ;
ERR_FAIL_COND_MSG ( p_profiler - > is_bound ( ) , " Profiler already registered. " ) ;
ERR_FAIL_COND_MSG ( profilers . has ( p_name ) | | has_profiler ( p_name ) , " Profiler name already in use: " + p_name ) ;
Error err = p_profiler - > bind ( p_name ) ;
ERR_FAIL_COND_MSG ( err ! = OK , " Profiler failed to register with error: " + itos ( err ) ) ;
profilers . insert ( p_name , p_profiler ) ;
2020-05-18 16:55:49 +02:00
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : unregister_profiler ( const StringName & p_name ) {
2020-05-18 16:55:49 +02:00
ERR_FAIL_COND_MSG ( ! profilers . has ( p_name ) , " Profiler not registered: " + p_name ) ;
2022-02-06 01:55:58 +01:00
profilers [ p_name ] - > unbind ( ) ;
2020-05-18 16:55:49 +02:00
profilers . erase ( p_name ) ;
}
2021-08-13 16:46:14 +02:00
bool EngineDebugger : : is_profiling ( const StringName & p_name ) {
return : : EngineDebugger : : is_profiling ( p_name ) ;
2020-05-18 16:55:49 +02:00
}
2021-08-13 16:46:14 +02:00
bool EngineDebugger : : has_profiler ( const StringName & p_name ) {
return : : EngineDebugger : : has_profiler ( p_name ) ;
2020-05-18 16:55:49 +02:00
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : profiler_add_frame_data ( const StringName & p_name , const Array & p_data ) {
: : EngineDebugger : : profiler_add_frame_data ( p_name , p_data ) ;
2020-05-18 16:55:49 +02:00
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : profiler_enable ( const StringName & p_name , bool p_enabled , const Array & p_opts ) {
if ( : : EngineDebugger : : get_singleton ( ) ) {
: : EngineDebugger : : get_singleton ( ) - > profiler_enable ( p_name , p_enabled , p_opts ) ;
2020-05-18 16:55:49 +02:00
}
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : register_message_capture ( const StringName & p_name , const Callable & p_callable ) {
2020-05-18 16:55:49 +02:00
ERR_FAIL_COND_MSG ( captures . has ( p_name ) | | has_capture ( p_name ) , " Capture already registered: " + p_name ) ;
captures . insert ( p_name , p_callable ) ;
Callable & c = captures [ p_name ] ;
2021-08-13 16:46:14 +02:00
: : EngineDebugger : : Capture capture ( & c , & EngineDebugger : : call_capture ) ;
: : EngineDebugger : : register_message_capture ( p_name , capture ) ;
2020-05-18 16:55:49 +02:00
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : unregister_message_capture ( const StringName & p_name ) {
2020-05-18 16:55:49 +02:00
ERR_FAIL_COND_MSG ( ! captures . has ( p_name ) , " Capture not registered: " + p_name ) ;
2021-08-13 16:46:14 +02:00
: : EngineDebugger : : unregister_message_capture ( p_name ) ;
2020-05-18 16:55:49 +02:00
captures . erase ( p_name ) ;
}
2021-08-13 16:46:14 +02:00
bool EngineDebugger : : has_capture ( const StringName & p_name ) {
return : : EngineDebugger : : has_capture ( p_name ) ;
2020-05-18 16:55:49 +02:00
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : send_message ( const String & p_msg , const Array & p_data ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : is_active ( ) , " Can't send message. No active debugger " ) ;
: : EngineDebugger : : get_singleton ( ) - > send_message ( p_msg , p_data ) ;
2020-05-18 16:55:49 +02:00
}
2024-01-02 20:07:10 +01:00
void EngineDebugger : : debug ( bool p_can_continue , bool p_is_error_breakpoint ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : is_active ( ) , " Can't send debug. No active debugger " ) ;
: : EngineDebugger : : get_singleton ( ) - > debug ( p_can_continue , p_is_error_breakpoint ) ;
}
void EngineDebugger : : script_debug ( ScriptLanguage * p_lang , bool p_can_continue , bool p_is_error_breakpoint ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , " Can't send debug. No active debugger " ) ;
: : EngineDebugger : : get_script_debugger ( ) - > debug ( p_lang , p_can_continue , p_is_error_breakpoint ) ;
}
2021-08-13 16:46:14 +02:00
Error EngineDebugger : : call_capture ( void * p_user , const String & p_cmd , const Array & p_data , bool & r_captured ) {
2020-05-18 16:55:49 +02:00
Callable & capture = * ( Callable * ) p_user ;
2024-04-27 11:56:39 +02:00
if ( ! capture . is_valid ( ) ) {
2020-05-18 16:55:49 +02:00
return FAILED ;
}
Variant cmd = p_cmd , data = p_data ;
const Variant * args [ 2 ] = { & cmd , & data } ;
Variant retval ;
Callable : : CallError err ;
2022-07-28 22:56:41 +02:00
capture . callp ( args , 2 , retval , err ) ;
2020-05-18 16:55:49 +02:00
ERR_FAIL_COND_V_MSG ( err . error ! = Callable : : CallError : : CALL_OK , FAILED , " Error calling 'capture' to callable: " + Variant : : get_callable_error_text ( capture , args , 2 , err ) ) ;
ERR_FAIL_COND_V_MSG ( retval . get_type ( ) ! = Variant : : BOOL , FAILED , " Error calling 'capture' to callable: " + String ( capture ) + " . Return type is not bool. " ) ;
r_captured = retval ;
return OK ;
}
2024-01-02 20:07:10 +01:00
void EngineDebugger : : line_poll ( ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : is_active ( ) , " Can't poll. No active debugger " ) ;
: : EngineDebugger : : get_singleton ( ) - > line_poll ( ) ;
}
void EngineDebugger : : set_lines_left ( int p_lines ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , " Can't set lines left. No active debugger " ) ;
: : EngineDebugger : : get_script_debugger ( ) - > set_lines_left ( p_lines ) ;
}
int EngineDebugger : : get_lines_left ( ) const {
ERR_FAIL_COND_V_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , 0 , " Can't get lines left. No active debugger " ) ;
return : : EngineDebugger : : get_script_debugger ( ) - > get_lines_left ( ) ;
}
void EngineDebugger : : set_depth ( int p_depth ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , " Can't set depth. No active debugger " ) ;
: : EngineDebugger : : get_script_debugger ( ) - > set_depth ( p_depth ) ;
}
int EngineDebugger : : get_depth ( ) const {
ERR_FAIL_COND_V_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , 0 , " Can't get depth. No active debugger " ) ;
return : : EngineDebugger : : get_script_debugger ( ) - > get_depth ( ) ;
}
bool EngineDebugger : : is_breakpoint ( int p_line , const StringName & p_source ) const {
ERR_FAIL_COND_V_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , false , " Can't check breakpoint. No active debugger " ) ;
return : : EngineDebugger : : get_script_debugger ( ) - > is_breakpoint ( p_line , p_source ) ;
}
bool EngineDebugger : : is_skipping_breakpoints ( ) const {
ERR_FAIL_COND_V_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , false , " Can't check skipping breakpoint. No active debugger " ) ;
return : : EngineDebugger : : get_script_debugger ( ) - > is_skipping_breakpoints ( ) ;
}
void EngineDebugger : : insert_breakpoint ( int p_line , const StringName & p_source ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , " Can't insert breakpoint. No active debugger " ) ;
: : EngineDebugger : : get_script_debugger ( ) - > insert_breakpoint ( p_line , p_source ) ;
}
void EngineDebugger : : remove_breakpoint ( int p_line , const StringName & p_source ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , " Can't remove breakpoint. No active debugger " ) ;
: : EngineDebugger : : get_script_debugger ( ) - > remove_breakpoint ( p_line , p_source ) ;
}
void EngineDebugger : : clear_breakpoints ( ) {
ERR_FAIL_COND_MSG ( ! : : EngineDebugger : : get_script_debugger ( ) , " Can't clear breakpoints. No active debugger " ) ;
: : EngineDebugger : : get_script_debugger ( ) - > clear_breakpoints ( ) ;
}
2021-08-13 16:46:14 +02:00
EngineDebugger : : ~ EngineDebugger ( ) {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < StringName , Callable > & E : captures ) {
: : EngineDebugger : : unregister_message_capture ( E . key ) ;
2020-05-18 16:55:49 +02:00
}
captures . clear ( ) ;
}
2021-08-13 16:46:14 +02:00
EngineDebugger * EngineDebugger : : singleton = nullptr ;
void EngineDebugger : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " is_active " ) , & EngineDebugger : : is_active ) ;
2022-02-06 01:55:58 +01:00
ClassDB : : bind_method ( D_METHOD ( " register_profiler " , " name " , " profiler " ) , & EngineDebugger : : register_profiler ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " unregister_profiler " , " name " ) , & EngineDebugger : : unregister_profiler ) ;
2022-02-06 01:55:58 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_profiling " , " name " ) , & EngineDebugger : : is_profiling ) ;
ClassDB : : bind_method ( D_METHOD ( " has_profiler " , " name " ) , & EngineDebugger : : has_profiler ) ;
ClassDB : : bind_method ( D_METHOD ( " profiler_add_frame_data " , " name " , " data " ) , & EngineDebugger : : profiler_add_frame_data ) ;
ClassDB : : bind_method ( D_METHOD ( " profiler_enable " , " name " , " enable " , " arguments " ) , & EngineDebugger : : profiler_enable , DEFVAL ( Array ( ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " register_message_capture " , " name " , " callable " ) , & EngineDebugger : : register_message_capture ) ;
ClassDB : : bind_method ( D_METHOD ( " unregister_message_capture " , " name " ) , & EngineDebugger : : unregister_message_capture ) ;
ClassDB : : bind_method ( D_METHOD ( " has_capture " , " name " ) , & EngineDebugger : : has_capture ) ;
2024-01-02 20:07:10 +01:00
ClassDB : : bind_method ( D_METHOD ( " line_poll " ) , & EngineDebugger : : line_poll ) ;
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " send_message " , " message " , " data " ) , & EngineDebugger : : send_message ) ;
2024-01-02 20:07:10 +01:00
ClassDB : : bind_method ( D_METHOD ( " debug " , " can_continue " , " is_error_breakpoint " ) , & EngineDebugger : : debug , DEFVAL ( true ) , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " script_debug " , " language " , " can_continue " , " is_error_breakpoint " ) , & EngineDebugger : : script_debug , DEFVAL ( true ) , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " set_lines_left " , " lines " ) , & EngineDebugger : : set_lines_left ) ;
ClassDB : : bind_method ( D_METHOD ( " get_lines_left " ) , & EngineDebugger : : get_lines_left ) ;
ClassDB : : bind_method ( D_METHOD ( " set_depth " , " depth " ) , & EngineDebugger : : set_depth ) ;
ClassDB : : bind_method ( D_METHOD ( " get_depth " ) , & EngineDebugger : : get_depth ) ;
ClassDB : : bind_method ( D_METHOD ( " is_breakpoint " , " line " , " source " ) , & EngineDebugger : : is_breakpoint ) ;
ClassDB : : bind_method ( D_METHOD ( " is_skipping_breakpoints " ) , & EngineDebugger : : is_skipping_breakpoints ) ;
ClassDB : : bind_method ( D_METHOD ( " insert_breakpoint " , " line " , " source " ) , & EngineDebugger : : insert_breakpoint ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_breakpoint " , " line " , " source " ) , & EngineDebugger : : remove_breakpoint ) ;
ClassDB : : bind_method ( D_METHOD ( " clear_breakpoints " ) , & EngineDebugger : : clear_breakpoints ) ;
2021-08-13 16:46:14 +02:00
}
} // namespace core_bind