2016-06-18 14:46:12 +02:00
/*************************************************************************/
/* core_bind.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2016-06-18 14:46:12 +02:00
/*************************************************************************/
2021-01-01 20:13:46 +01:00
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
2016-06-18 14:46:12 +02:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-09 22:10:30 -03:00
# include "core_bind.h"
2017-04-28 18:29:15 +02:00
2020-11-07 19:33:38 -03:00
# include "core/config/project_settings.h"
2019-07-11 15:21:47 +02:00
# include "core/crypto/crypto_core.h"
2020-05-18 20:25:49 +05:30
# include "core/debugger/engine_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 20:20:45 +03: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"
# include "core/os/os.h"
2016-03-03 23:31:27 -07: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-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
ResourceLoader * ResourceLoader : : singleton = nullptr ;
Error ResourceLoader : : load_threaded_request ( const String & p_path , const String & p_type_hint , bool p_use_sub_threads ) {
return : : ResourceLoader : : load_threaded_request ( p_path , p_type_hint , p_use_sub_threads ) ;
2020-02-28 08:27:04 -03: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 08:27:04 -03: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 08:27:04 -03:00
r_progress . resize ( 1 ) ;
r_progress [ 0 ] = progress ;
return ( ThreadLoadStatus ) tls ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
RES ResourceLoader : : load_threaded_get ( const String & p_path ) {
2020-02-28 08:27:04 -03:00
Error error ;
2021-08-13 16:46:14 +02:00
RES res = : : ResourceLoader : : load_threaded_get ( p_path , & error ) ;
2020-02-28 08:27:04 -03:00
return res ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
RES ResourceLoader : : load ( const String & p_path , const String & p_type_hint , CacheMode p_cache_mode ) {
2018-01-05 17:35:48 -03:00
Error err = OK ;
2021-08-13 16:46:14 +02:00
RES ret = : : ResourceLoader : : load ( p_path , p_type_hint , ResourceFormatLoader : : CacheMode ( p_cache_mode ) , & err ) ;
2018-01-05 17:35:48 -03:00
2019-08-14 20:57:49 -06:00
ERR_FAIL_COND_V_MSG ( err ! = OK , ret , " Error loading resource: ' " + p_path + " '. " ) ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
List < String > exts ;
2021-08-13 16:46:14 +02:00
: : ResourceLoader : : get_recognized_extensions_for_type ( p_type , & exts ) ;
2020-02-17 18:06:54 -03:00
Vector < String > ret ;
2021-07-24 15:46:25 +02:00
for ( const String & E : exts ) {
2021-07-15 23:45:57 -04:00
ret . push_back ( E ) ;
2014-02-09 22:10:30 -03:00
}
return ret ;
}
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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
PackedStringArray ResourceLoader : : get_dependencies ( const String & p_path ) {
2014-02-09 22:10:30 -03:00
List < String > deps ;
2021-08-13 16:46:14 +02:00
: : ResourceLoader : : get_dependencies ( p_path , & deps ) ;
2014-02-09 22:10:30 -03:00
2020-02-17 18:06:54 -03:00
PackedStringArray ret ;
2021-07-24 15:46:25 +02:00
for ( const String & E : deps ) {
2021-07-15 23:45:57 -04:00
ret . push_back ( E ) ;
2014-02-09 22:10:30 -03:00
}
return ret ;
2020-05-19 15:46:49 +02:00
}
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
bool ResourceLoader : : has_cached ( const String & p_path ) {
2017-07-19 17:00:46 -03:00
String local_path = ProjectSettings : : get_singleton ( ) - > localize_path ( p_path ) ;
2014-02-09 22:10:30 -03:00
return ResourceCache : : has ( local_path ) ;
2018-08-10 15:57:43 -03: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 15:57:43 -03:00
}
2014-02-09 22:10:30 -03: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 ( ) {
ClassDB : : bind_method ( D_METHOD ( " load_threaded_request " , " path " , " type_hint " , " use_sub_threads " ) , & ResourceLoader : : load_threaded_request , DEFVAL ( " " ) , DEFVAL ( false ) ) ;
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 08:27:04 -03: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 ) ;
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 08:27:04 -03: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 14:18:45 -03:00
BIND_ENUM_CONSTANT ( CACHE_MODE_IGNORE ) ;
BIND_ENUM_CONSTANT ( CACHE_MODE_REUSE ) ;
BIND_ENUM_CONSTANT ( CACHE_MODE_REPLACE ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// ResourceSaver //////
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Error ResourceSaver : : save ( const String & p_path , const RES & p_resource , SaverFlags p_flags ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( p_resource . is_null ( ) , ERR_INVALID_PARAMETER , " Can't save empty resource to path ' " + String ( p_path ) + " '. " ) ;
2021-08-13 16:46:14 +02:00
return : : ResourceSaver : : save ( p_path , p_resource , p_flags ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
Vector < String > ResourceSaver : : get_recognized_extensions ( const RES & p_resource ) {
2020-02-17 18:06:54 -03:00
ERR_FAIL_COND_V_MSG ( p_resource . is_null ( ) , Vector < String > ( ) , " It's not a reference to a valid Resource object. " ) ;
2014-02-09 22:10:30 -03:00
List < String > exts ;
2021-08-13 16:46:14 +02:00
: : ResourceSaver : : get_recognized_extensions ( p_resource , & exts ) ;
2020-02-17 18:06:54 -03:00
Vector < String > ret ;
2021-07-24 15:46:25 +02:00
for ( const String & E : exts ) {
2021-07-15 23:45:57 -04:00
ret . push_back ( E ) ;
2014-02-09 22:10:30 -03:00
}
return ret ;
}
2021-08-13 16:46:14 +02:00
ResourceSaver * ResourceSaver : : singleton = nullptr ;
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
void ResourceSaver : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " save " , " path " , " resource " , " flags " ) , & ResourceSaver : : save , DEFVAL ( 0 ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_recognized_extensions " , " type " ) , & ResourceSaver : : get_recognized_extensions ) ;
2014-05-24 01:35:47 -03:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( FLAG_RELATIVE_PATHS ) ;
BIND_ENUM_CONSTANT ( FLAG_BUNDLE_RESOURCES ) ;
BIND_ENUM_CONSTANT ( FLAG_CHANGE_PATH ) ;
BIND_ENUM_CONSTANT ( FLAG_OMIT_EDITOR_PROPERTIES ) ;
BIND_ENUM_CONSTANT ( FLAG_SAVE_BIG_ENDIAN ) ;
BIND_ENUM_CONSTANT ( FLAG_COMPRESS ) ;
2018-10-18 17:58:44 +03:00
BIND_ENUM_CONSTANT ( FLAG_REPLACE_SUBRESOURCE_PATHS ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// OS //////
2014-02-09 22:10:30 -03:00
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 09:11:28 -03:00
}
2021-08-13 16:46:14 +02:00
void OS : : open_midi_inputs ( ) {
: : OS : : get_singleton ( ) - > open_midi_inputs ( ) ;
2018-08-03 21:17:33 -03:00
}
2021-08-13 16:46:14 +02:00
void OS : : close_midi_inputs ( ) {
: : OS : : get_singleton ( ) - > close_midi_inputs ( ) ;
2018-08-03 21:17:33 -03:00
}
2021-08-13 16:46:14 +02:00
void OS : : set_use_file_access_save_and_swap ( bool p_enable ) {
2014-08-01 22:10:38 -03: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-09 22:10:30 -03: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-09 22:10:30 -03: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-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 19:23:48 +03:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_executable_path ( ) const {
return : : OS : : get_singleton ( ) - > get_executable_path ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
Error OS : : shell_open ( 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-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
int OS : : execute ( const String & p_path , const Vector < String > & p_arguments , Array r_output , bool p_read_stderr ) {
2014-02-09 22:10:30 -03:00
List < String > args ;
2020-05-14 16:41:43 +02:00
for ( int i = 0 ; i < p_arguments . size ( ) ; i + + ) {
2014-02-09 22:10:30 -03:00
args . push_back ( p_arguments [ i ] ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
String pipe ;
2020-12-18 18:49:13 +00:00
int exitcode = 0 ;
2021-08-13 16:46:14 +02:00
Error err = : : OS : : get_singleton ( ) - > execute ( p_path , args , & pipe , & exitcode , p_read_stderr ) ;
2020-12-18 18:49:13 +00:00
r_output . push_back ( pipe ) ;
if ( err ! = OK ) {
return - 1 ;
}
return exitcode ;
}
2021-08-13 16:46:14 +02:00
int OS : : create_process ( const String & p_path , const Vector < String > & p_arguments ) {
2020-12-18 18:49:13 +00:00
List < String > args ;
for ( int i = 0 ; i < p_arguments . size ( ) ; i + + ) {
args . push_back ( p_arguments [ i ] ) ;
}
2021-08-13 16:46:14 +02:00
: : OS : : ProcessID pid = 0 ;
Error err = : : OS : : get_singleton ( ) - > create_process ( p_path , args , & pid ) ;
2020-05-14 16:41:43 +02:00
if ( err ! = OK ) {
2014-02-09 22:10:30 -03:00
return - 1 ;
2020-05-14 16:41:43 +02:00
}
2020-12-18 18:49:13 +00:00
return pid ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
}
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 12:39:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
bool OS : : set_environment ( const String & p_var , const String & p_value ) const {
return : : OS : : get_singleton ( ) - > set_environment ( p_var , p_value ) ;
2021-02-25 22:20:13 +11:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_name ( ) const {
return : : OS : : get_singleton ( ) - > get_name ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
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-09 22:10:30 -03:00
Vector < String > cmdlinev ;
2021-07-24 15:46:25 +02:00
for ( const String & E : cmdline ) {
2021-07-15 23:45:57 -04:00
cmdlinev . push_back ( E ) ;
2014-02-09 22:10:30 -03:00
}
return cmdlinev ;
}
2021-08-13 16:46:14 +02:00
String OS : : get_locale ( ) const {
return : : OS : : get_singleton ( ) - > get_locale ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_model_name ( ) const {
return : : OS : : get_singleton ( ) - > get_model_name ( ) ;
2014-02-09 22:10:30 -03: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-01-31 20:22:38 -03: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-08-13 16:46:14 +02:00
bool OS : : has_feature ( const String & p_feature ) const {
return : : OS : : get_singleton ( ) - > has_feature ( p_feature ) ;
2017-10-02 16:38:39 -03:00
}
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-09 22:10:30 -03: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-09 22:10:30 -03: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_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-09 22:10:30 -03: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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
bool OS : : can_use_threads ( ) const {
return : : OS : : get_singleton ( ) - > can_use_threads ( ) ;
2014-03-13 22:57:24 -03: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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
bool OS : : is_stdout_verbose ( ) const {
return : : OS : : get_singleton ( ) - > is_stdout_verbose ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
void OS : : dump_memory_to_file ( const String & p_file ) {
: : OS : : get_singleton ( ) - > dump_memory_to_file ( p_file . utf8 ( ) . get_data ( ) ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
struct OSCoreBindImg {
2014-02-26 10:08:17 -03:00
String path ;
Size2 size ;
2020-11-23 17:38:46 +01:00
int fmt = 0 ;
2014-02-26 10:08:17 -03:00
ObjectID id ;
2020-11-23 17:38:46 +01:00
int vram = 0 ;
2021-08-13 16:46:14 +02:00
bool operator < ( const OSCoreBindImg & p_img ) const { return vram = = p_img . vram ? id < p_img . id : vram > p_img . vram ; }
2014-02-26 10:08:17 -03:00
} ;
2021-08-13 16:46:14 +02:00
void OS : : print_all_textures_by_size ( ) {
List < OSCoreBindImg > imgs ;
2021-03-05 21:48:11 +00:00
uint64_t total = 0 ;
2014-02-26 10:08:17 -03:00
{
2020-03-17 07:33:00 +01:00
List < Ref < Resource > > rsrc ;
2014-02-26 10:08:17 -03:00
ResourceCache : : get_cached_resources ( & rsrc ) ;
2021-07-26 17:50:35 +02:00
for ( Ref < Resource > & res : rsrc ) {
2021-02-28 12:10:47 +01:00
if ( ! res - > is_class ( " Texture " ) ) {
2014-02-26 10:08:17 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2014-02-26 10:08:17 -03:00
2021-07-26 17:50:35 +02:00
Size2 size = res - > call ( " get_size " ) ;
int fmt = res - > call ( " get_format " ) ;
2014-02-26 10:08:17 -03:00
2021-08-13 16:46:14 +02:00
OSCoreBindImg img ;
2017-03-05 16:44:50 +01:00
img . size = size ;
img . fmt = fmt ;
2021-07-26 17:50:35 +02:00
img . path = res - > get_path ( ) ;
2017-03-05 16:44:50 +01:00
img . vram = Image : : get_image_data_size ( img . size . width , img . size . height , Image : : Format ( img . fmt ) ) ;
2021-07-26 17:50:35 +02:00
img . id = res - > get_instance_id ( ) ;
2017-03-05 16:44:50 +01:00
total + = img . vram ;
2014-02-26 10:08:17 -03:00
imgs . push_back ( img ) ;
}
}
imgs . sort ( ) ;
2021-02-28 12:10:47 +01:00
if ( imgs . size ( ) = = 0 ) {
print_line ( " No textures seem used in this project. " ) ;
} else {
print_line ( " Textures currently in use, sorted by VRAM usage: \n "
" Path - VRAM usage (Dimensions) " ) ;
2014-02-26 10:08:17 -03:00
}
2021-02-28 12:10:47 +01:00
2021-08-13 16:46:14 +02:00
for ( const OSCoreBindImg & img : imgs ) {
2021-02-28 12:10:47 +01:00
print_line ( vformat ( " %s - %s %s " ,
img . path ,
String : : humanize_size ( img . vram ) ,
img . size ) ) ;
}
print_line ( vformat ( " Total VRAM usage: %s. " , String : : humanize_size ( total ) ) ) ;
2014-05-14 01:22:15 -03:00
}
2014-02-26 10:08:17 -03:00
2021-08-13 16:46:14 +02:00
void OS : : print_resources_by_type ( const Vector < String > & p_types ) {
2021-02-28 12:10:47 +01:00
ERR_FAIL_COND_MSG ( p_types . size ( ) = = 0 ,
" At least one type should be provided to print resources by type. " ) ;
print_line ( vformat ( " Resources currently in use for the following types: %s " , p_types ) ) ;
2014-05-14 01:22:15 -03:00
2021-02-28 12:10:47 +01:00
Map < String , int > type_count ;
2020-03-17 07:33:00 +01:00
List < Ref < Resource > > resources ;
2014-05-14 01:22:15 -03:00
ResourceCache : : get_cached_resources ( & resources ) ;
2021-07-26 17:50:35 +02:00
for ( const Ref < Resource > & r : resources ) {
2014-05-14 01:22:15 -03:00
bool found = false ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < p_types . size ( ) ; i + + ) {
2020-05-14 16:41:43 +02:00
if ( r - > is_class ( p_types [ i ] ) ) {
2014-05-14 01:22:15 -03:00
found = true ;
2020-05-14 16:41:43 +02:00
}
2014-05-14 01:22:15 -03:00
}
2020-05-14 16:41:43 +02:00
if ( ! found ) {
2014-05-14 01:22:15 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2014-05-14 01:22:15 -03:00
2017-01-02 23:03:46 -03:00
if ( ! type_count . has ( r - > get_class ( ) ) ) {
2017-03-05 16:44:50 +01:00
type_count [ r - > get_class ( ) ] = 0 ;
2014-05-14 01:22:15 -03:00
}
2017-01-02 23:03:46 -03:00
type_count [ r - > get_class ( ) ] + + ;
2021-02-28 12:10:47 +01:00
print_line ( vformat ( " %s: %s " , r - > get_class ( ) , r - > get_path ( ) ) ) ;
List < StringName > metas ;
r - > get_meta_list ( & metas ) ;
for ( const StringName & meta : metas ) {
print_line ( vformat ( " %s: %s " , meta , r - > get_meta ( meta ) ) ) ;
}
}
for ( const KeyValue < String , int > & E : type_count ) {
print_line ( vformat ( " %s count: %d " , E . key , E . value ) ) ;
2014-05-14 01:22:15 -03:00
}
2020-05-19 15:46:49 +02:00
}
2014-02-26 10:08:17 -03:00
2021-08-13 16:46:14 +02:00
void OS : : print_all_resources ( const String & p_to_file ) {
: : OS : : get_singleton ( ) - > print_all_resources ( p_to_file ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
void OS : : print_resources_in_use ( bool p_short ) {
: : OS : : get_singleton ( ) - > print_resources_in_use ( p_short ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
void OS : : dump_resources_to_file ( const String & p_file ) {
: : OS : : get_singleton ( ) - > dump_resources_to_file ( p_file . utf8 ( ) . get_data ( ) ) ;
2014-02-09 22:10:30 -03:00
}
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-09 22:10:30 -03: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 11:31:01 -03:00
# ifdef DEBUG_ENABLED
return true ;
# else
return false ;
# endif
}
2014-12-02 14:02:41 -03: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 14:02:41 -03:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_keycode_string ( uint32_t p_code ) const {
return : : keycode_get_string ( p_code ) ;
2015-05-17 13:11:55 -03:00
}
2018-04-05 20:59:35 +03:00
2021-08-13 16:46:14 +02:00
bool OS : : is_keycode_unicode ( uint32_t p_unicode ) const {
return : : keycode_has_unicode ( p_unicode ) ;
2015-05-17 13:11:55 -03:00
}
2018-04-05 20:59:35 +03:00
2021-08-13 16:46:14 +02:00
int OS : : find_keycode_from_string ( const String & p_code ) const {
2015-05-17 13:11:55 -03: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-04 23:06:37 -03:00
}
2021-08-13 16:46:14 +02:00
bool OS : : request_permissions ( ) {
return : : OS : : get_singleton ( ) - > request_permissions ( ) ;
2019-10-06 21:17:44 +03: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 21:17:44 +03:00
}
2021-08-13 16:46:14 +02:00
String OS : : get_unique_id ( ) const {
return : : OS : : get_singleton ( ) - > get_unique_id ( ) ;
2020-03-03 10:36:29 -03:00
}
2020-05-12 17:01:17 +02:00
2021-08-13 16:46:14 +02:00
OS * OS : : singleton = nullptr ;
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
void OS : : _bind_methods ( ) {
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 14:18:05 -03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " alert " , " text " , " title " ) , & OS : : alert , DEFVAL ( " Alert! " ) ) ;
2021-07-22 19:23:48 +03: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-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_processor_count " ) , & OS : : get_processor_count ) ;
2017-02-13 12:47:24 +01:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_executable_path " ) , & OS : : get_executable_path ) ;
ClassDB : : bind_method ( D_METHOD ( " execute " , " path " , " arguments " , " output " , " read_stderr " ) , & OS : : execute , DEFVAL ( Array ( ) ) , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " create_process " , " path " , " arguments " ) , & OS : : create_process ) ;
ClassDB : : bind_method ( D_METHOD ( " kill " , " pid " ) , & OS : : kill ) ;
ClassDB : : bind_method ( D_METHOD ( " shell_open " , " uri " ) , & OS : : shell_open ) ;
ClassDB : : bind_method ( D_METHOD ( " get_process_id " ) , & OS : : get_process_id ) ;
2017-02-13 12:47:24 +01:00
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 ) ;
ClassDB : : bind_method ( D_METHOD ( " has_environment " , " variable " ) , & OS : : has_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 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_cmdline_args " ) , & OS : : get_cmdline_args ) ;
2017-02-13 12:47:24 +01:00
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 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_model_name " ) , & OS : : get_model_name ) ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " can_use_threads " ) , & OS : : can_use_threads ) ;
2014-03-13 22:57:24 -03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_debug_build " ) , & OS : : is_debug_build ) ;
2014-11-02 11:31:01 -03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " dump_memory_to_file " , " file " ) , & OS : : dump_memory_to_file ) ;
ClassDB : : bind_method ( D_METHOD ( " dump_resources_to_file " , " file " ) , & OS : : dump_resources_to_file ) ;
ClassDB : : bind_method ( D_METHOD ( " print_resources_in_use " , " short " ) , & OS : : print_resources_in_use , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " print_all_resources " , " tofile " ) , & OS : : print_all_resources , DEFVAL ( " " ) ) ;
2017-03-05 16:44:50 +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 ) ;
2017-03-05 16:44:50 +01:00
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 ( " print_all_textures_by_size " ) , & OS : : print_all_textures_by_size ) ;
ClassDB : : bind_method ( D_METHOD ( " print_resources_by_type " , " types " ) , & OS : : print_resources_by_type ) ;
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 ) ;
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 ) ;
2017-10-02 16:38:39 -03: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 ) ;
2019-03-04 23:06:37 -03:00
2018-01-12 00:35:12 +02: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 " ) ;
2018-01-12 00:35:12 +02: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 ( " exit_code " , 0 ) ;
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
2019-02-16 14:40:52 +01:00
BIND_ENUM_CONSTANT ( VIDEO_DRIVER_GLES2 ) ;
2020-02-13 10:08:52 +01:00
BIND_ENUM_CONSTANT ( VIDEO_DRIVER_VULKAN ) ;
2019-02-16 14:40:52 +01:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( DAY_SUNDAY ) ;
BIND_ENUM_CONSTANT ( DAY_MONDAY ) ;
BIND_ENUM_CONSTANT ( DAY_TUESDAY ) ;
BIND_ENUM_CONSTANT ( DAY_WEDNESDAY ) ;
BIND_ENUM_CONSTANT ( DAY_THURSDAY ) ;
BIND_ENUM_CONSTANT ( DAY_FRIDAY ) ;
BIND_ENUM_CONSTANT ( DAY_SATURDAY ) ;
BIND_ENUM_CONSTANT ( MONTH_JANUARY ) ;
BIND_ENUM_CONSTANT ( MONTH_FEBRUARY ) ;
BIND_ENUM_CONSTANT ( MONTH_MARCH ) ;
BIND_ENUM_CONSTANT ( MONTH_APRIL ) ;
BIND_ENUM_CONSTANT ( MONTH_MAY ) ;
BIND_ENUM_CONSTANT ( MONTH_JUNE ) ;
BIND_ENUM_CONSTANT ( MONTH_JULY ) ;
BIND_ENUM_CONSTANT ( MONTH_AUGUST ) ;
BIND_ENUM_CONSTANT ( MONTH_SEPTEMBER ) ;
BIND_ENUM_CONSTANT ( MONTH_OCTOBER ) ;
BIND_ENUM_CONSTANT ( MONTH_NOVEMBER ) ;
BIND_ENUM_CONSTANT ( MONTH_DECEMBER ) ;
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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// Geometry2D //////
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Geometry2D * Geometry2D : : singleton = nullptr ;
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Geometry2D * Geometry2D : : get_singleton ( ) {
2014-02-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03:00
return result ;
} else {
return Variant ( ) ;
2020-05-19 15:46:49 +02:00
}
}
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
Vector2 r1 , r2 ;
2021-08-13 16:46:14 +02:00
: : Geometry2D : : get_closest_points_between_segments ( p1 , q1 , p2 , q2 , r1 , r2 ) ;
2020-02-17 18:06:54 -03:00
Vector < Vector2 > r ;
2014-02-09 22:10:30 -03:00
r . resize ( 2 ) ;
2017-03-05 16:44:50 +01:00
r . set ( 0 , r1 ) ;
r . set ( 1 , r2 ) ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03: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-27 00:20:22 +03: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-09 22:10:30 -03: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 16:53:53 +03: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
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : merge_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : merge_polygons ( p_polygon_a , p_polygon_b ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : clip_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : clip_polygons ( p_polygon_a , p_polygon_b ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : intersect_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : intersect_polygons ( p_polygon_a , p_polygon_b ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : exclude_polygons ( const Vector < Vector2 > & p_polygon_a , const Vector < Vector2 > & p_polygon_b ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : exclude_polygons ( p_polygon_a , p_polygon_b ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : clip_polyline_with_polygon ( const Vector < Vector2 > & p_polyline , const Vector < Vector2 > & p_polygon ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : clip_polyline_with_polygon ( p_polyline , p_polygon ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : intersect_polyline_with_polygon ( const Vector < Vector2 > & p_polyline , const Vector < Vector2 > & p_polygon ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : intersect_polyline_with_polygon ( p_polyline , p_polygon ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : offset_polygon ( const Vector < Vector2 > & p_polygon , real_t p_delta , PolyJoinType p_join_type ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : offset_polygon ( p_polygon , p_delta , : : Geometry2D : : PolyJoinType ( p_join_type ) ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
for ( int i = 0 ; i < polys . size ( ) ; + + i ) {
ret . push_back ( polys [ i ] ) ;
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array Geometry2D : : offset_polyline ( const Vector < Vector2 > & p_polygon , real_t p_delta , PolyJoinType p_join_type , PolyEndType p_end_type ) {
Vector < Vector < Point2 > > polys = : : Geometry2D : : offset_polyline ( p_polygon , p_delta , : : Geometry2D : : PolyJoinType ( p_join_type ) , : : Geometry2D : : PolyEndType ( p_end_type ) ) ;
2019-05-18 20:01:42 +03:00
Array ret ;
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 00:10:51 -03: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 00:10:51 -03:00
rects . push_back ( p_rects [ i ] ) ;
2020-05-19 15:46:49 +02:00
}
2014-10-03 00:10:51 -03:00
Vector < Point2i > result ;
Size2i size ;
2021-08-13 16:46:14 +02:00
: : Geometry2D : : make_atlas ( rects , result , size ) ;
2014-10-03 00:10:51 -03:00
Size2 r_size = size ;
Vector < Point2 > r_result ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < result . size ( ) ; i + + ) {
2014-10-03 00:10:51 -03:00
r_result . push_back ( result [ i ] ) ;
2020-05-19 15:46:49 +02:00
}
2014-10-03 00:10:51 -03:00
ret [ " points " ] = r_result ;
ret [ " size " ] = r_size ;
return ret ;
2020-05-19 15:46:49 +02:00
}
2014-10-03 00:10:51 -03: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 ) ;
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-09 22:10:30 -03: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-09 22:10:30 -03: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 01:31:49 -03: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-09 22:10:30 -03: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 ) ;
2014-02-09 22:10:30 -03: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 ) ;
2019-05-18 20:01:42 +03: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 ) ;
2019-05-18 20:01:42 +03: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 ) ) ;
2019-05-18 20:01:42 +03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " make_atlas " , " sizes " ) , & Geometry2D : : make_atlas ) ;
2019-05-18 20:01:42 +03: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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// Geometry3D //////
2020-05-25 20:20:45 +03:00
2021-08-13 16:46:14 +02:00
Geometry3D * Geometry3D : : singleton = nullptr ;
2020-05-25 20:20:45 +03:00
2021-08-13 16:46:14 +02:00
Geometry3D * Geometry3D : : get_singleton ( ) {
2020-05-25 20:20:45 +03:00
return singleton ;
}
2021-08-13 16:46:14 +02:00
Vector < Plane > Geometry3D : : build_box_planes ( const Vector3 & p_extents ) {
return : : Geometry3D : : build_box_planes ( p_extents ) ;
2020-05-25 20:20:45 +03:00
}
2021-08-13 16:46:14 +02:00
Vector < Plane > Geometry3D : : build_cylinder_planes ( float p_radius , float p_height , int p_sides , Vector3 : : Axis p_axis ) {
return : : Geometry3D : : build_cylinder_planes ( p_radius , p_height , p_sides , p_axis ) ;
2020-05-25 20:20:45 +03:00
}
2021-08-13 16:46:14 +02:00
Vector < Plane > Geometry3D : : build_capsule_planes ( float p_radius , float p_height , int p_sides , int p_lats , Vector3 : : Axis p_axis ) {
return : : Geometry3D : : build_capsule_planes ( p_radius , p_height , p_sides , p_lats , p_axis ) ;
2020-05-25 20:20:45 +03: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 20:20:45 +03:00
Vector3 r1 , r2 ;
2021-08-13 16:46:14 +02:00
: : Geometry3D : : get_closest_points_between_segments ( p1 , p2 , q1 , q2 , r1 , r2 ) ;
2020-05-25 20:20:45 +03:00
Vector < Vector3 > r ;
r . resize ( 2 ) ;
r . set ( 0 , r1 ) ;
r . set ( 1 , r2 ) ;
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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03:00
}
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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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_convex ( const Vector3 & p_from , const Vector3 & p_to , const Vector < Plane > & p_planes ) {
2020-05-25 20:20:45 +03:00
Vector < Vector3 > r ;
Vector3 res , norm ;
2021-08-13 16:46:14 +02:00
if ( ! : : Geometry3D : : segment_intersects_convex ( p_from , p_to , p_planes . ptr ( ) , p_planes . size ( ) , & res , & norm ) ) {
2020-05-25 20:20:45 +03: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 20:20:45 +03:00
}
2021-08-13 16:46:14 +02:00
void Geometry3D : : _bind_methods ( ) {
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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03: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 20:20:45 +03:00
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 20:20:45 +03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " clip_polygon " , " points " , " plane " ) , & Geometry3D : : clip_polygon ) ;
2020-05-25 20:20:45 +03:00
}
2021-08-13 16:46:14 +02:00
////// File //////
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Error File : : open_encrypted ( const String & p_path , ModeFlags p_mode_flags , const Vector < uint8_t > & p_key ) {
2017-03-05 16:44:50 +01:00
Error err = open ( p_path , p_mode_flags ) ;
2020-05-14 16:41:43 +02:00
if ( err ) {
2014-04-14 22:43:44 -03:00
return err ;
2020-05-14 16:41:43 +02:00
}
2014-04-14 22:43:44 -03:00
2017-03-05 16:44:50 +01:00
FileAccessEncrypted * fae = memnew ( FileAccessEncrypted ) ;
err = fae - > open_and_parse ( f , p_key , ( p_mode_flags = = WRITE ) ? FileAccessEncrypted : : MODE_WRITE_AES256 : FileAccessEncrypted : : MODE_READ ) ;
2014-04-14 22:43:44 -03:00
if ( err ) {
memdelete ( fae ) ;
close ( ) ;
return err ;
}
2017-03-05 16:44:50 +01:00
f = fae ;
2014-04-14 22:43:44 -03:00
return OK ;
}
2021-08-13 16:46:14 +02:00
Error File : : open_encrypted_pass ( const String & p_path , ModeFlags p_mode_flags , const String & p_pass ) {
2017-03-05 16:44:50 +01:00
Error err = open ( p_path , p_mode_flags ) ;
2020-05-14 16:41:43 +02:00
if ( err ) {
2014-04-14 22:43:44 -03:00
return err ;
2020-05-14 16:41:43 +02:00
}
2014-04-14 22:43:44 -03:00
2017-03-05 16:44:50 +01:00
FileAccessEncrypted * fae = memnew ( FileAccessEncrypted ) ;
err = fae - > open_and_parse_password ( f , p_pass , ( p_mode_flags = = WRITE ) ? FileAccessEncrypted : : MODE_WRITE_AES256 : FileAccessEncrypted : : MODE_READ ) ;
2014-04-14 22:43:44 -03:00
if ( err ) {
memdelete ( fae ) ;
close ( ) ;
return err ;
}
2017-03-05 16:44:50 +01:00
f = fae ;
2014-04-14 22:43:44 -03:00
return OK ;
}
2021-08-13 16:46:14 +02:00
Error File : : open_compressed ( const String & p_path , ModeFlags p_mode_flags , CompressionMode p_compress_mode ) {
2017-06-19 13:28:00 -03:00
FileAccessCompressed * fac = memnew ( FileAccessCompressed ) ;
fac - > configure ( " GCPF " , ( Compression : : Mode ) p_compress_mode ) ;
2017-08-21 15:15:36 -04:00
Error err = fac - > _open ( p_path , p_mode_flags ) ;
2017-06-19 13:28:00 -03:00
if ( err ) {
memdelete ( fac ) ;
return err ;
}
f = fac ;
return OK ;
}
2021-08-13 16:46:14 +02:00
Error File : : open ( const String & p_path , ModeFlags p_mode_flags ) {
2014-02-09 22:10:30 -03:00
close ( ) ;
Error err ;
2017-03-05 16:44:50 +01:00
f = FileAccess : : open ( p_path , p_mode_flags , & err ) ;
2020-05-14 16:41:43 +02:00
if ( f ) {
2021-05-20 14:58:03 +02:00
f - > set_big_endian ( big_endian ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
return err ;
}
2021-08-13 16:46:14 +02:00
void File : : flush ( ) {
2020-12-15 15:31:04 +01:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before flushing. " ) ;
f - > flush ( ) ;
}
2021-08-13 16:46:14 +02:00
void File : : close ( ) {
2020-05-14 16:41:43 +02:00
if ( f ) {
2014-02-09 22:10:30 -03:00
memdelete ( f ) ;
2020-05-14 16:41:43 +02:00
}
2020-04-02 01:20:12 +02:00
f = nullptr ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool File : : is_open ( ) const {
2020-04-02 01:20:12 +02:00
return f ! = nullptr ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
String File : : get_path ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , " " , " File must be opened before use. " ) ;
2018-03-09 11:45:21 -03:00
return f - > get_path ( ) ;
}
2021-08-13 16:46:14 +02:00
String File : : get_path_absolute ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , " " , " File must be opened before use. " ) ;
2018-03-09 11:45:21 -03:00
return f - > get_path_absolute ( ) ;
}
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
void File : : seek ( int64_t p_position ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2019-03-26 18:51:13 +01:00
ERR_FAIL_COND_MSG ( p_position < 0 , " Seek position must be a positive integer. " ) ;
2014-02-09 22:10:30 -03:00
f - > seek ( p_position ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
void File : : seek_end ( int64_t p_position ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > seek_end ( p_position ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
uint64_t File : : get_position ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2017-09-10 15:37:49 +02:00
return f - > get_position ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
uint64_t File : : get_length ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2021-05-25 07:58:49 +01:00
return f - > get_length ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
bool File : : eof_reached ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , false , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > eof_reached ( ) ;
}
2021-08-13 16:46:14 +02:00
uint8_t File : : get_8 ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_8 ( ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
uint16_t File : : get_16 ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_16 ( ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
uint32_t File : : get_32 ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_32 ( ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
uint64_t File : : get_64 ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_64 ( ) ;
}
2021-08-13 16:46:14 +02:00
float File : : get_float ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_float ( ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
double File : : get_double ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_double ( ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
real_t File : : get_real ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , 0 , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_real ( ) ;
}
2021-08-13 16:46:14 +02:00
Vector < uint8_t > File : : get_buffer ( int64_t p_length ) const {
2020-02-17 18:06:54 -03:00
Vector < uint8_t > data ;
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , data , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( p_length < 0 , data , " Length of buffer cannot be smaller than 0. " ) ;
2020-05-14 16:41:43 +02:00
if ( p_length = = 0 ) {
2014-02-09 22:10:30 -03:00
return data ;
2020-05-14 16:41:43 +02:00
}
2019-07-05 18:08:43 +01:00
2014-02-09 22:10:30 -03:00
Error err = data . resize ( p_length ) ;
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( err ! = OK , data , " Can't resize data to " + itos ( p_length ) + " elements. " ) ;
2019-07-05 18:08:43 +01:00
2020-02-17 18:06:54 -03:00
uint8_t * w = data . ptrw ( ) ;
2019-03-26 18:51:13 +01:00
int64_t len = f - > get_buffer ( & w [ 0 ] , p_length ) ;
2014-02-09 22:10:30 -03:00
2020-05-14 16:41:43 +02:00
if ( len < p_length ) {
2021-04-11 23:11:13 +02:00
data . resize ( len ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
return data ;
}
2021-08-13 16:46:14 +02:00
String File : : get_as_text ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , String ( ) , " File must be opened before use. " ) ;
2016-06-20 18:39:37 -03:00
2014-02-09 22:10:30 -03:00
String text ;
2019-03-26 18:51:13 +01:00
uint64_t original_pos = f - > get_position ( ) ;
2016-06-20 18:39:37 -03:00
f - > seek ( 0 ) ;
2014-02-09 22:10:30 -03:00
String l = get_line ( ) ;
2017-03-05 16:44:50 +01:00
while ( ! eof_reached ( ) ) {
text + = l + " \n " ;
2014-02-09 22:10:30 -03:00
l = get_line ( ) ;
}
2017-03-05 16:44:50 +01:00
text + = l ;
2014-02-09 22:10:30 -03:00
2016-06-20 18:39:37 -03:00
f - > seek ( original_pos ) ;
2014-02-09 22:10:30 -03:00
return text ;
}
2016-02-25 19:25:29 +01:00
2021-08-13 16:46:14 +02:00
String File : : get_md5 ( const String & p_path ) const {
2016-02-25 19:25:29 +01:00
return FileAccess : : get_md5 ( p_path ) ;
}
2021-08-13 16:46:14 +02:00
String File : : get_sha256 ( const String & p_path ) const {
2016-06-17 10:55:16 +03:00
return FileAccess : : get_sha256 ( p_path ) ;
}
2021-08-13 16:46:14 +02:00
String File : : get_line ( ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , String ( ) , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return f - > get_line ( ) ;
}
2021-08-13 16:46:14 +02:00
Vector < String > File : : get_csv_line ( const String & p_delim ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , Vector < String > ( ) , " File must be opened before use. " ) ;
2018-11-13 12:53:24 +01:00
return f - > get_csv_line ( p_delim ) ;
2014-02-09 22:10:30 -03:00
}
2021-03-12 19:05:16 +05:30
/**< use this for files WRITTEN in _big_ endian machines (i.e. amiga/mac)
2014-02-09 22:10:30 -03:00
* It's not about the current CPU type but file formats.
2021-03-12 19:05:16 +05:30
* These flags get reset to false (little endian) on each open
2014-02-09 22:10:30 -03:00
*/
2021-08-13 16:46:14 +02:00
void File : : set_big_endian ( bool p_big_endian ) {
2021-05-20 14:58:03 +02:00
big_endian = p_big_endian ;
2020-05-14 16:41:43 +02:00
if ( f ) {
2021-05-20 14:58:03 +02:00
f - > set_big_endian ( p_big_endian ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool File : : is_big_endian ( ) {
2021-05-20 14:58:03 +02:00
return big_endian ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
Error File : : get_error ( ) const {
2020-05-14 16:41:43 +02:00
if ( ! f ) {
2014-02-09 22:10:30 -03:00
return ERR_UNCONFIGURED ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
return f - > get_error ( ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_8 ( uint8_t p_dest ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_8 ( p_dest ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
void File : : store_16 ( uint16_t p_dest ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_16 ( p_dest ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
void File : : store_32 ( uint32_t p_dest ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_32 ( p_dest ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
void File : : store_64 ( uint64_t p_dest ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_64 ( p_dest ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_float ( float p_dest ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_float ( p_dest ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
void File : : store_double ( double p_dest ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_double ( p_dest ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
void File : : store_real ( real_t p_real ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_real ( p_real ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_string ( const String & p_string ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_string ( p_string ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_pascal_string ( const String & p_string ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-03-13 22:57:24 -03:00
f - > store_pascal_string ( p_string ) ;
2020-05-19 15:46:49 +02:00
}
2014-03-13 22:57:24 -03:00
2021-08-13 16:46:14 +02:00
String File : : get_pascal_string ( ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , " " , " File must be opened before use. " ) ;
2014-03-13 22:57:24 -03:00
return f - > get_pascal_string ( ) ;
2020-05-19 15:46:49 +02:00
}
2014-03-13 22:57:24 -03:00
2021-08-13 16:46:14 +02:00
void File : : store_line ( const String & p_string ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
f - > store_line ( p_string ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_csv_line ( const Vector < String > & p_values , const String & p_delim ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2018-11-13 12:53:24 +01:00
f - > store_csv_line ( p_values , p_delim ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_buffer ( const Vector < uint8_t > & p_buffer ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
2019-03-26 18:51:13 +01:00
uint64_t len = p_buffer . size ( ) ;
2020-05-14 16:41:43 +02:00
if ( len = = 0 ) {
2014-02-09 22:10:30 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
2020-02-17 18:06:54 -03:00
const uint8_t * r = p_buffer . ptr ( ) ;
2014-02-09 22:10:30 -03:00
2017-03-05 16:44:50 +01:00
f - > store_buffer ( & r [ 0 ] , len ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
bool File : : file_exists ( const String & p_name ) const {
2014-02-09 22:10:30 -03:00
return FileAccess : : exists ( p_name ) ;
}
2021-08-13 16:46:14 +02:00
void File : : store_var ( const Variant & p_var , bool p_full_objects ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( ! f , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03: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_MSG ( err ! = OK , " Error when trying to encode Variant. " ) ;
2014-02-09 22:10:30 -03:00
2020-02-17 18:06:54 -03:00
Vector < uint8_t > buff ;
2014-02-09 22:10:30 -03:00
buff . resize ( len ) ;
2020-02-17 18:06:54 -03:00
uint8_t * w = buff . ptrw ( ) ;
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_MSG ( err ! = OK , " Error when trying to encode Variant. " ) ;
2014-02-09 22:10:30 -03:00
store_32 ( len ) ;
store_buffer ( buff ) ;
}
2021-08-13 16:46:14 +02:00
Variant File : : get_var ( bool p_allow_objects ) const {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_V_MSG ( ! f , Variant ( ) , " File must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
uint32_t len = get_32 ( ) ;
2020-02-17 18:06:54 -03:00
Vector < uint8_t > buff = get_buffer ( len ) ;
2017-08-31 23:30:35 +02:00
ERR_FAIL_COND_V ( ( uint32_t ) buff . size ( ) ! = len , Variant ( ) ) ;
2014-02-09 22:10:30 -03:00
2020-02-17 18:06:54 -03:00
const uint8_t * r = buff . ptr ( ) ;
2014-02-09 22:10:30 -03:00
Variant v ;
2020-04-02 01:20:12 +02:00
Error err = decode_variant ( v , & r [ 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 encode Variant. " ) ;
2014-02-09 22:10:30 -03:00
return v ;
}
2021-08-13 16:46:14 +02:00
uint64_t File : : get_modified_time ( const String & p_file ) const {
2017-01-23 22:33:02 +01:00
return FileAccess : : get_modified_time ( p_file ) ;
}
2021-08-13 16:46:14 +02:00
void File : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " open_encrypted " , " path " , " mode_flags " , " key " ) , & File : : open_encrypted ) ;
ClassDB : : bind_method ( D_METHOD ( " open_encrypted_with_pass " , " path " , " mode_flags " , " pass " ) , & File : : open_encrypted_pass ) ;
ClassDB : : bind_method ( D_METHOD ( " open_compressed " , " path " , " mode_flags " , " compression_mode " ) , & File : : open_compressed , DEFVAL ( 0 ) ) ;
ClassDB : : bind_method ( D_METHOD ( " open " , " path " , " flags " ) , & File : : open ) ;
ClassDB : : bind_method ( D_METHOD ( " flush " ) , & File : : flush ) ;
ClassDB : : bind_method ( D_METHOD ( " close " ) , & File : : close ) ;
ClassDB : : bind_method ( D_METHOD ( " get_path " ) , & File : : get_path ) ;
ClassDB : : bind_method ( D_METHOD ( " get_path_absolute " ) , & File : : get_path_absolute ) ;
ClassDB : : bind_method ( D_METHOD ( " is_open " ) , & File : : is_open ) ;
ClassDB : : bind_method ( D_METHOD ( " seek " , " position " ) , & File : : seek ) ;
ClassDB : : bind_method ( D_METHOD ( " seek_end " , " position " ) , & File : : seek_end , DEFVAL ( 0 ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_position " ) , & File : : get_position ) ;
ClassDB : : bind_method ( D_METHOD ( " get_length " ) , & File : : get_length ) ;
ClassDB : : bind_method ( D_METHOD ( " eof_reached " ) , & File : : eof_reached ) ;
ClassDB : : bind_method ( D_METHOD ( " get_8 " ) , & File : : get_8 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_16 " ) , & File : : get_16 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_32 " ) , & File : : get_32 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_64 " ) , & File : : get_64 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_float " ) , & File : : get_float ) ;
ClassDB : : bind_method ( D_METHOD ( " get_double " ) , & File : : get_double ) ;
ClassDB : : bind_method ( D_METHOD ( " get_real " ) , & File : : get_real ) ;
ClassDB : : bind_method ( D_METHOD ( " get_buffer " , " length " ) , & File : : get_buffer ) ;
ClassDB : : bind_method ( D_METHOD ( " get_line " ) , & File : : get_line ) ;
ClassDB : : bind_method ( D_METHOD ( " get_csv_line " , " delim " ) , & File : : get_csv_line , DEFVAL ( " , " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_as_text " ) , & File : : get_as_text ) ;
ClassDB : : bind_method ( D_METHOD ( " get_md5 " , " path " ) , & File : : get_md5 ) ;
ClassDB : : bind_method ( D_METHOD ( " get_sha256 " , " path " ) , & File : : get_sha256 ) ;
ClassDB : : bind_method ( D_METHOD ( " is_big_endian " ) , & File : : is_big_endian ) ;
ClassDB : : bind_method ( D_METHOD ( " set_big_endian " , " big_endian " ) , & File : : set_big_endian ) ;
ClassDB : : bind_method ( D_METHOD ( " get_error " ) , & File : : get_error ) ;
ClassDB : : bind_method ( D_METHOD ( " get_var " , " allow_objects " ) , & File : : get_var , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " store_8 " , " value " ) , & File : : store_8 ) ;
ClassDB : : bind_method ( D_METHOD ( " store_16 " , " value " ) , & File : : store_16 ) ;
ClassDB : : bind_method ( D_METHOD ( " store_32 " , " value " ) , & File : : store_32 ) ;
ClassDB : : bind_method ( D_METHOD ( " store_64 " , " value " ) , & File : : store_64 ) ;
ClassDB : : bind_method ( D_METHOD ( " store_float " , " value " ) , & File : : store_float ) ;
ClassDB : : bind_method ( D_METHOD ( " store_double " , " value " ) , & File : : store_double ) ;
ClassDB : : bind_method ( D_METHOD ( " store_real " , " value " ) , & File : : store_real ) ;
ClassDB : : bind_method ( D_METHOD ( " store_buffer " , " buffer " ) , & File : : store_buffer ) ;
ClassDB : : bind_method ( D_METHOD ( " store_line " , " line " ) , & File : : store_line ) ;
ClassDB : : bind_method ( D_METHOD ( " store_csv_line " , " values " , " delim " ) , & File : : store_csv_line , DEFVAL ( " , " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " store_string " , " string " ) , & File : : store_string ) ;
ClassDB : : bind_method ( D_METHOD ( " store_var " , " value " , " full_objects " ) , & File : : store_var , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " store_pascal_string " , " string " ) , & File : : store_pascal_string ) ;
ClassDB : : bind_method ( D_METHOD ( " get_pascal_string " ) , & File : : get_pascal_string ) ;
ClassDB : : bind_method ( D_METHOD ( " file_exists " , " path " ) , & File : : file_exists ) ;
ClassDB : : bind_method ( D_METHOD ( " get_modified_time " , " file " ) , & File : : get_modified_time ) ;
2017-03-05 16:44:50 +01:00
2021-05-20 14:58:03 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " big_endian " ) , " set_big_endian " , " is_big_endian " ) ;
2018-01-12 00:35:12 +02:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( READ ) ;
BIND_ENUM_CONSTANT ( WRITE ) ;
BIND_ENUM_CONSTANT ( READ_WRITE ) ;
BIND_ENUM_CONSTANT ( WRITE_READ ) ;
2017-06-19 13:28:00 -03:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( COMPRESSION_FASTLZ ) ;
BIND_ENUM_CONSTANT ( COMPRESSION_DEFLATE ) ;
BIND_ENUM_CONSTANT ( COMPRESSION_ZSTD ) ;
BIND_ENUM_CONSTANT ( COMPRESSION_GZIP ) ;
2017-03-05 16:44:50 +01:00
}
2021-08-13 16:46:14 +02:00
File : : ~ File ( ) {
2020-05-14 16:41:43 +02:00
if ( f ) {
2014-02-09 22:10:30 -03:00
memdelete ( f ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// Directory //////
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Error Directory : : open ( const String & p_path ) {
2014-02-09 22:10:30 -03:00
Error err ;
2017-03-05 16:44:50 +01:00
DirAccess * alt = DirAccess : : open ( p_path , & err ) ;
2014-02-09 22:10:30 -03:00
2020-05-14 16:41:43 +02:00
if ( ! alt ) {
2014-02-09 22:10:30 -03:00
return err ;
2020-05-14 16:41:43 +02:00
}
if ( d ) {
2014-02-09 22:10:30 -03:00
memdelete ( d ) ;
2020-05-14 16:41:43 +02:00
}
2017-03-05 16:44:50 +01:00
d = alt ;
2020-07-06 01:17:16 -05:00
dir_open = true ;
2014-02-09 22:10:30 -03:00
return OK ;
}
2021-08-13 16:46:14 +02:00
bool Directory : : is_open ( ) const {
2020-07-06 01:17:16 -05:00
return d & & dir_open ;
}
2021-08-13 16:46:14 +02:00
Error Directory : : list_dir_begin ( bool p_show_navigational , bool p_show_hidden ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , ERR_UNCONFIGURED , " Directory must be opened before use. " ) ;
2017-01-16 23:19:43 +01:00
2021-05-28 20:24:40 +02:00
_list_skip_navigational = ! p_show_navigational ;
_list_skip_hidden = ! p_show_hidden ;
2017-01-16 23:19:43 +01:00
2014-02-09 22:10:30 -03:00
return d - > list_dir_begin ( ) ;
}
2021-08-13 16:46:14 +02:00
String Directory : : get_next ( ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , " " , " Directory must be opened before use. " ) ;
2017-01-16 23:19:43 +01:00
String next = d - > get_next ( ) ;
2017-03-05 16:44:50 +01:00
while ( next ! = " " & & ( ( _list_skip_navigational & & ( next = = " . " | | next = = " .. " ) ) | | ( _list_skip_hidden & & d - > current_is_hidden ( ) ) ) ) {
2017-01-16 23:19:43 +01:00
next = d - > get_next ( ) ;
}
return next ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
bool Directory : : current_is_dir ( ) const {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , false , " Directory must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return d - > current_is_dir ( ) ;
}
2021-08-13 16:46:14 +02:00
void Directory : : list_dir_end ( ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_MSG ( ! is_open ( ) , " Directory must be opened before use. " ) ;
2019-07-01 12:59:42 +02:00
d - > list_dir_end ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
int Directory : : get_drive_count ( ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , 0 , " Directory must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return d - > get_drive_count ( ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
String Directory : : get_drive ( int p_drive ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , " " , " Directory must be opened before use. " ) ;
2014-02-09 22:10:30 -03:00
return d - > get_drive ( p_drive ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
int Directory : : get_current_drive ( ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , 0 , " Directory must be opened before use. " ) ;
2017-01-14 17:01:43 +01:00
return d - > get_current_drive ( ) ;
}
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Error Directory : : change_dir ( String p_dir ) {
2020-07-09 14:23:59 -05:00
ERR_FAIL_COND_V_MSG ( ! d , ERR_UNCONFIGURED , " Directory is not configured properly. " ) ;
Error err = d - > change_dir ( p_dir ) ;
if ( err ! = OK ) {
return err ;
}
dir_open = true ;
return OK ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
String Directory : : get_current_dir ( ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , " " , " Directory must be opened before use. " ) ;
2020-03-17 14:32:03 +01:00
return d - > get_current_dir ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Error Directory : : make_dir ( String p_dir ) {
2020-07-19 23:53:19 -05:00
ERR_FAIL_COND_V_MSG ( ! d , ERR_UNCONFIGURED , " Directory is not configured properly. " ) ;
2016-06-18 12:11:48 -03:00
if ( ! p_dir . is_rel_path ( ) ) {
DirAccess * d = DirAccess : : create_for_path ( p_dir ) ;
Error err = d - > make_dir ( p_dir ) ;
memdelete ( d ) ;
return err ;
}
2014-02-09 22:10:30 -03:00
return d - > make_dir ( p_dir ) ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Error Directory : : make_dir_recursive ( String p_dir ) {
2020-07-19 23:53:19 -05:00
ERR_FAIL_COND_V_MSG ( ! d , ERR_UNCONFIGURED , " Directory is not configured properly. " ) ;
2016-08-08 18:20:16 -03:00
if ( ! p_dir . is_rel_path ( ) ) {
DirAccess * d = DirAccess : : create_for_path ( p_dir ) ;
Error err = d - > make_dir_recursive ( p_dir ) ;
memdelete ( d ) ;
return err ;
}
2014-02-09 22:10:30 -03:00
return d - > make_dir_recursive ( p_dir ) ;
}
2021-08-13 16:46:14 +02:00
bool Directory : : file_exists ( String p_file ) {
2020-07-09 14:23:59 -05:00
ERR_FAIL_COND_V_MSG ( ! d , false , " Directory is not configured properly. " ) ;
2016-06-18 12:11:48 -03:00
if ( ! p_file . is_rel_path ( ) ) {
return FileAccess : : exists ( p_file ) ;
}
2014-02-09 22:10:30 -03:00
return d - > file_exists ( p_file ) ;
}
2021-08-13 16:46:14 +02:00
bool Directory : : dir_exists ( String p_dir ) {
2020-07-09 14:23:59 -05:00
ERR_FAIL_COND_V_MSG ( ! d , false , " Directory is not configured properly. " ) ;
2016-06-18 12:11:48 -03:00
if ( ! p_dir . is_rel_path ( ) ) {
DirAccess * d = DirAccess : : create_for_path ( p_dir ) ;
bool exists = d - > dir_exists ( p_dir ) ;
memdelete ( d ) ;
return exists ;
}
2020-07-09 14:23:59 -05:00
return d - > dir_exists ( p_dir ) ;
2014-05-25 11:34:51 +08:00
}
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
uint64_t Directory : : get_space_left ( ) {
2019-03-26 18:51:13 +01:00
ERR_FAIL_COND_V_MSG ( ! d , 0 , " Directory must be opened before use. " ) ;
return d - > get_space_left ( ) / 1024 * 1024 ; // Truncate to closest MiB.
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
Error Directory : : copy ( String p_from , String p_to ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , ERR_UNCONFIGURED , " Directory must be opened before use. " ) ;
2017-03-05 16:44:50 +01:00
return d - > copy ( p_from , p_to ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Error Directory : : rename ( String p_from , String p_to ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , ERR_UNCONFIGURED , " Directory must be opened before use. " ) ;
2021-08-17 14:15:51 +02:00
ERR_FAIL_COND_V_MSG ( p_from . is_empty ( ) | | p_from = = " . " | | p_from = = " .. " , ERR_INVALID_PARAMETER , " Invalid path to rename. " ) ;
2016-06-18 12:11:48 -03:00
if ( ! p_from . is_rel_path ( ) ) {
DirAccess * d = DirAccess : : create_for_path ( p_from ) ;
2021-08-17 14:15:51 +02:00
ERR_FAIL_COND_V_MSG ( ! d - > file_exists ( p_from ) & & ! d - > dir_exists ( p_from ) , ERR_DOES_NOT_EXIST , " File or directory does not exist. " ) ;
2017-03-05 16:44:50 +01:00
Error err = d - > rename ( p_from , p_to ) ;
2016-06-18 12:11:48 -03:00
memdelete ( d ) ;
return err ;
}
2021-08-17 14:15:51 +02:00
ERR_FAIL_COND_V_MSG ( ! d - > file_exists ( p_from ) & & ! d - > dir_exists ( p_from ) , ERR_DOES_NOT_EXIST , " File or directory does not exist. " ) ;
2017-03-05 16:44:50 +01:00
return d - > rename ( p_from , p_to ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Error Directory : : remove ( String p_name ) {
2020-07-06 01:17:16 -05:00
ERR_FAIL_COND_V_MSG ( ! is_open ( ) , ERR_UNCONFIGURED , " Directory must be opened before use. " ) ;
2016-06-18 12:11:48 -03:00
if ( ! p_name . is_rel_path ( ) ) {
DirAccess * d = DirAccess : : create_for_path ( p_name ) ;
Error err = d - > remove ( p_name ) ;
memdelete ( d ) ;
return err ;
}
2014-02-09 22:10:30 -03:00
return d - > remove ( p_name ) ;
}
2021-08-13 16:46:14 +02:00
void Directory : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " open " , " path " ) , & Directory : : open ) ;
ClassDB : : bind_method ( D_METHOD ( " list_dir_begin " , " show_navigational " , " show_hidden " ) , & Directory : : list_dir_begin , DEFVAL ( false ) , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_next " ) , & Directory : : get_next ) ;
ClassDB : : bind_method ( D_METHOD ( " current_is_dir " ) , & Directory : : current_is_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " list_dir_end " ) , & Directory : : list_dir_end ) ;
ClassDB : : bind_method ( D_METHOD ( " get_drive_count " ) , & Directory : : get_drive_count ) ;
ClassDB : : bind_method ( D_METHOD ( " get_drive " , " idx " ) , & Directory : : get_drive ) ;
ClassDB : : bind_method ( D_METHOD ( " get_current_drive " ) , & Directory : : get_current_drive ) ;
ClassDB : : bind_method ( D_METHOD ( " change_dir " , " todir " ) , & Directory : : change_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " get_current_dir " ) , & Directory : : get_current_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " make_dir " , " path " ) , & Directory : : make_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " make_dir_recursive " , " path " ) , & Directory : : make_dir_recursive ) ;
ClassDB : : bind_method ( D_METHOD ( " file_exists " , " path " ) , & Directory : : file_exists ) ;
ClassDB : : bind_method ( D_METHOD ( " dir_exists " , " path " ) , & Directory : : dir_exists ) ;
//ClassDB::bind_method(D_METHOD("get_modified_time","file"),&Directory::get_modified_time);
ClassDB : : bind_method ( D_METHOD ( " get_space_left " ) , & Directory : : get_space_left ) ;
ClassDB : : bind_method ( D_METHOD ( " copy " , " from " , " to " ) , & Directory : : copy ) ;
ClassDB : : bind_method ( D_METHOD ( " rename " , " from " , " to " ) , & Directory : : rename ) ;
ClassDB : : bind_method ( D_METHOD ( " remove " , " path " ) , & Directory : : remove ) ;
}
Directory : : Directory ( ) {
2014-02-09 22:10:30 -03:00
d = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
}
2021-08-13 16:46:14 +02:00
Directory : : ~ Directory ( ) {
2020-05-14 16:41:43 +02:00
if ( d ) {
2014-02-09 22:10:30 -03:00
memdelete ( d ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03:00
2020-02-17 18:06:54 -03:00
Vector < uint8_t > buff ;
2014-02-09 22:10:30 -03:00
buff . resize ( len ) ;
2020-02-17 18:06:54 -03:00
uint8_t * w = buff . ptrw ( ) ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
2019-07-02 17:47:34 +02:00
String ret = CryptoCore : : b64_encode_str ( & w [ 0 ] , len ) ;
ERR_FAIL_COND_V ( ret = = " " , ret ) ;
2014-02-09 22:10:30 -03:00
return ret ;
2020-05-19 15:46:49 +02:00
}
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Variant Marshalls : : base64_to_variant ( const String & p_str , bool p_allow_objects ) {
2014-02-09 22:10:30 -03:00
int strlen = p_str . length ( ) ;
CharString cstr = p_str . ascii ( ) ;
2020-02-17 18:06:54 -03:00
Vector < uint8_t > buf ;
2014-06-11 10:41:03 -03:00
buf . resize ( strlen / 4 * 3 + 1 ) ;
2020-02-17 18:06:54 -03:00
uint8_t * w = buf . ptrw ( ) ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03: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-09 22:10:30 -03:00
return v ;
2020-05-19 15:46:49 +02:00
}
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
String Marshalls : : raw_to_base64 ( const Vector < uint8_t > & p_arr ) {
2020-02-17 18:06:54 -03:00
String ret = CryptoCore : : b64_encode_str ( p_arr . ptr ( ) , p_arr . size ( ) ) ;
2019-07-02 17:47:34 +02:00
ERR_FAIL_COND_V ( ret = = " " , 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 18:06:54 -03:00
Vector < uint8_t > buf ;
2015-07-28 12:50:52 +02:00
{
buf . resize ( strlen / 4 * 3 + 1 ) ;
2020-02-17 18:06:54 -03:00
uint8_t * w = buf . ptrw ( ) ;
2015-07-28 12:50:52 +02:00
2020-02-17 18:06:54 -03: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 ( ) ) ;
ERR_FAIL_COND_V ( ret = = " " , 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 18:06:54 -03:00
Vector < uint8_t > buf ;
2015-07-28 12:50:52 +02:00
buf . resize ( strlen / 4 * 3 + 1 + 1 ) ;
2020-02-17 18:06:54 -03: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-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
////// Semaphore //////
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
void Semaphore : : wait ( ) {
2020-03-03 09:26:42 +01:00
semaphore . wait ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
Error Semaphore : : try_wait ( ) {
2020-03-03 09:26:42 +01:00
return semaphore . try_wait ( ) ? OK : ERR_BUSY ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
void Semaphore : : post ( ) {
2020-03-03 09:26:42 +01:00
semaphore . post ( ) ;
2014-02-09 22:10:30 -03: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 ) ;
ClassDB : : bind_method ( D_METHOD ( " post " ) , & Semaphore : : post ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// Mutex //////
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
void Mutex : : lock ( ) {
2020-02-26 11:28:13 +01:00
mutex . lock ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
Error Mutex : : try_lock ( ) {
2020-02-26 11:28:13 +01:00
return mutex . try_lock ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
void Mutex : : unlock ( ) {
2020-02-26 11:28:13 +01:00
mutex . unlock ( ) ;
2014-02-09 22:10:30 -03: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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
////// Thread //////
2014-02-09 22:10:30 -03: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 12:45:53 -03:00
memdelete ( tud ) ;
2020-02-19 16:27:19 -03:00
Callable : : CallError ce ;
2017-03-05 16:44:50 +01:00
const Variant * arg [ 1 ] = { & t - > userdata } ;
2021-07-31 09:36:34 +02:00
int argc = 0 ;
if ( arg [ 0 ] - > get_type ( ) ! = Variant : : NIL ) {
// Just pass to the target function whatever came as user data
argc = 1 ;
} else {
// There are two cases of null user data:
// a) The target function has zero parameters and the caller is just honoring that.
// b) The target function has at least one parameter with no default and the caller is
// leveraging the fact that user data defaults to null in Thread.start().
// We care about the case of more than one parameter because, even if a thread
// function can have one at most, out mindset here is to do our best with the
// only/first one and let the call handle any other error conditions, like too
// much arguments.
// We must check if we are in case b).
int target_param_count = 0 ;
int target_default_arg_count = 0 ;
Ref < Script > script = t - > target_instance - > get_script ( ) ;
if ( script . is_valid ( ) ) {
MethodInfo mi = script - > get_method_info ( t - > target_method ) ;
target_param_count = mi . arguments . size ( ) ;
target_default_arg_count = mi . default_arguments . size ( ) ;
} else {
MethodBind * method = ClassDB : : get_method ( t - > target_instance - > get_class_name ( ) , t - > target_method ) ;
target_param_count = method - > get_argument_count ( ) ;
target_default_arg_count = method - > get_default_argument_count ( ) ;
}
2021-08-08 12:53:30 +02:00
if ( target_param_count > = 1 & & target_default_arg_count < target_param_count ) {
2021-07-31 09:36:34 +02:00
argc = 1 ;
}
}
2015-06-29 00:29:49 -03:00
2021-08-13 16:46:14 +02:00
: : Thread : : set_name ( t - > target_method ) ;
2015-12-18 03:06:51 -03:00
2020-04-21 15:18:50 +02:00
t - > ret = t - > target_instance - > call ( t - > target_method , arg , argc , ce ) ;
2020-02-19 16:27:19 -03:00
if ( ce . error ! = Callable : : CallError : : CALL_OK ) {
2014-02-09 22:10:30 -03:00
String reason ;
2017-03-05 16:44:50 +01:00
switch ( ce . error ) {
2020-02-19 16:27:19 -03:00
case Callable : : CallError : : CALL_ERROR_INVALID_ARGUMENT : {
2017-03-05 16:44:50 +01:00
reason = " Invalid Argument # " + itos ( ce . argument ) ;
2014-02-09 22:10:30 -03:00
} break ;
2020-02-19 16:27:19 -03:00
case Callable : : CallError : : CALL_ERROR_TOO_MANY_ARGUMENTS : {
2017-03-05 16:44:50 +01:00
reason = " Too Many Arguments " ;
2014-02-09 22:10:30 -03:00
} break ;
2020-02-19 16:27:19 -03:00
case Callable : : CallError : : CALL_ERROR_TOO_FEW_ARGUMENTS : {
2019-01-11 10:12:13 +07:00
reason = " Too Few Arguments " ;
2014-02-09 22:10:30 -03:00
} break ;
2020-02-19 16:27:19 -03:00
case Callable : : CallError : : CALL_ERROR_INVALID_METHOD : {
2017-03-05 16:44:50 +01:00
reason = " Method Not Found " ;
2014-02-09 22:10:30 -03:00
} break ;
2019-04-09 17:08:36 +02:00
default : {
}
2014-02-09 22:10:30 -03:00
}
2019-09-25 10:28:50 +02:00
ERR_FAIL_MSG ( " Could not call function ' " + t - > target_method . operator String ( ) + " ' to start thread " + t - > get_id ( ) + " : " + reason + " . " ) ;
2014-02-09 22:10:30 -03:00
}
}
2021-08-13 16:46:14 +02:00
Error Thread : : start ( Object * p_instance , const StringName & p_method , const Variant & p_userdata , Priority p_priority ) {
2021-02-10 19:22:13 +01:00
ERR_FAIL_COND_V_MSG ( active . is_set ( ) , ERR_ALREADY_IN_USE , " Thread already started. " ) ;
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( ! p_instance , ERR_INVALID_PARAMETER ) ;
ERR_FAIL_COND_V ( p_method = = StringName ( ) , ERR_INVALID_PARAMETER ) ;
2019-04-07 18:52:39 +02:00
ERR_FAIL_INDEX_V ( p_priority , PRIORITY_MAX , ERR_INVALID_PARAMETER ) ;
2014-02-09 22:10:30 -03:00
2017-03-05 16:44:50 +01:00
ret = Variant ( ) ;
target_method = p_method ;
target_instance = p_instance ;
userdata = p_userdata ;
2021-02-10 19:22:13 +01:00
active . set ( ) ;
2014-02-09 22:10:30 -03:00
2021-08-13 16:46:14 +02:00
Ref < Thread > * ud = memnew ( Ref < Thread > ( this ) ) ;
2015-05-18 12:45:53 -03: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-09 22:10:30 -03: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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
bool Thread : : is_active ( ) const {
2021-02-10 19:22:13 +01:00
return active . is_set ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Variant Thread : : wait_to_finish ( ) {
2021-02-10 19:22:13 +01:00
ERR_FAIL_COND_V_MSG ( ! active . is_set ( ) , Variant ( ) , " Thread must be active to wait for its completion. " ) ;
2021-01-19 13:29:41 +01:00
thread . wait_to_finish ( ) ;
2014-02-09 22:10:30 -03:00
Variant r = ret ;
2021-02-10 19:22:13 +01:00
active . clear ( ) ;
2017-03-05 16:44:50 +01:00
target_method = StringName ( ) ;
2020-04-02 01:20:12 +02:00
target_instance = nullptr ;
2017-03-05 16:44:50 +01:00
userdata = Variant ( ) ;
2014-02-09 22:10:30 -03:00
return r ;
}
2021-08-13 16:46:14 +02:00
void Thread : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " start " , " instance " , " method " , " userdata " , " priority " ) , & Thread : : start , DEFVAL ( Variant ( ) ) , DEFVAL ( PRIORITY_NORMAL ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_id " ) , & Thread : : get_id ) ;
ClassDB : : bind_method ( D_METHOD ( " is_active " ) , & Thread : : is_active ) ;
ClassDB : : bind_method ( D_METHOD ( " wait_to_finish " ) , & Thread : : wait_to_finish ) ;
2014-02-09 22:10:30 -03:00
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-09 22:10:30 -03:00
}
2021-08-13 16:46:14 +02:00
namespace special {
////// ClassDB //////
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
PackedStringArray ClassDB : : get_class_list ( ) const {
2017-01-02 23:03:46 -03:00
List < StringName > classes ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_class_list ( & classes ) ;
2017-01-02 23:03:46 -03:00
2020-02-17 18:06:54 -03:00
PackedStringArray ret ;
2017-01-02 23:03:46 -03: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-15 23:45:57 -04:00
ret . set ( idx + + , E ) ;
2017-01-02 23:03:46 -03: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-02 23:03:46 -03:00
List < StringName > classes ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_inheriters_from_class ( p_class , & classes ) ;
2017-01-02 23:03:46 -03:00
2020-02-17 18:06:54 -03:00
PackedStringArray ret ;
2017-01-02 23:03:46 -03: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-15 23:45:57 -04:00
ret . set ( idx + + , E ) ;
2017-01-02 23:03:46 -03: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-02 23:03:46 -03: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-02 23:03:46 -03: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-02 23:03:46 -03: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-02 23:03:46 -03: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-02 23:03:46 -03:00
return Variant ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-01-02 23:03:46 -03:00
2021-06-04 18:03:15 +02:00
RefCounted * r = Object : : cast_to < RefCounted > ( obj ) ;
2017-01-02 23:03:46 -03:00
if ( r ) {
return REF ( r ) ;
} else {
return obj ;
}
}
2021-08-13 16:46:14 +02:00
bool ClassDB : : has_signal ( StringName p_class , StringName p_signal ) const {
return : : ClassDB : : has_signal ( p_class , p_signal ) ;
2017-01-02 23:03:46 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Dictionary ClassDB : : get_signal ( StringName p_class , StringName p_signal ) const {
2017-01-02 23:03:46 -03:00
MethodInfo signal ;
2021-08-13 16:46:14 +02:00
if ( : : ClassDB : : get_signal ( p_class , p_signal , & signal ) ) {
2017-01-02 23:03:46 -03:00
return signal . operator Dictionary ( ) ;
} else {
return Dictionary ( ) ;
}
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
Array ClassDB : : get_signal_list ( StringName p_class , bool p_no_inheritance ) const {
2017-01-02 23:03:46 -03:00
List < MethodInfo > signals ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_signal_list ( p_class , & signals , p_no_inheritance ) ;
2017-01-02 23:03:46 -03:00
Array ret ;
2021-07-24 15:46:25 +02:00
for ( const MethodInfo & E : signals ) {
2021-07-15 23:45:57 -04:00
ret . push_back ( E . operator Dictionary ( ) ) ;
2017-01-02 23:03:46 -03:00
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Array ClassDB : : get_property_list ( StringName p_class , bool p_no_inheritance ) const {
2017-01-02 23:03:46 -03:00
List < PropertyInfo > plist ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_property_list ( p_class , & plist , p_no_inheritance ) ;
2017-01-02 23:03:46 -03:00
Array ret ;
2021-07-24 15:46:25 +02:00
for ( const PropertyInfo & E : plist ) {
2021-07-15 23:45:57 -04:00
ret . push_back ( E . operator Dictionary ( ) ) ;
2017-01-02 23:03:46 -03:00
}
return ret ;
}
2021-08-13 16:46:14 +02:00
Variant ClassDB : : 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 ;
}
2021-08-13 16:46:14 +02:00
Error ClassDB : : 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 ;
}
2021-08-13 16:46:14 +02:00
bool ClassDB : : has_method ( StringName p_class , StringName p_method , bool p_no_inheritance ) const {
return : : ClassDB : : has_method ( p_class , p_method , p_no_inheritance ) ;
2017-01-02 23:03:46 -03:00
}
2021-08-13 16:46:14 +02:00
Array ClassDB : : get_method_list ( StringName p_class , bool p_no_inheritance ) const {
2017-01-02 23:03:46 -03:00
List < MethodInfo > methods ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_method_list ( p_class , & methods , p_no_inheritance ) ;
2017-01-02 23:03:46 -03:00
Array ret ;
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-15 23:45:57 -04:00
ret . push_back ( E . operator Dictionary ( ) ) ;
2018-01-04 19:04:05 +01:00
# else
Dictionary dict ;
2021-07-15 23:45:57 -04:00
dict [ " name " ] = E . name ;
2018-01-04 19:04:05 +01:00
ret . push_back ( dict ) ;
# endif
2017-01-02 23:03:46 -03:00
}
return ret ;
}
2021-08-13 16:46:14 +02:00
PackedStringArray ClassDB : : get_integer_constant_list ( const StringName & p_class , bool p_no_inheritance ) const {
2017-01-02 23:03:46 -03: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-02 23:03:46 -03:00
2020-02-17 18:06:54 -03:00
PackedStringArray ret ;
2017-01-02 23:03:46 -03: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-15 23:45:57 -04:00
ret . set ( idx + + , E ) ;
2017-01-02 23:03:46 -03:00
}
return ret ;
}
2021-08-13 16:46:14 +02:00
bool ClassDB : : has_integer_constant ( const StringName & p_class , const StringName & p_name ) const {
2017-01-02 23:03:46 -03:00
bool success ;
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_integer_constant ( p_class , p_name , & success ) ;
2017-01-02 23:03:46 -03:00
return success ;
}
2021-08-13 16:46:14 +02:00
int ClassDB : : get_integer_constant ( const StringName & p_class , const StringName & p_name ) const {
2017-01-02 23:03:46 -03:00
bool found ;
2021-08-13 16:46:14 +02:00
int 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-02 23:03:46 -03:00
return c ;
}
2020-05-14 14:29:06 +02:00
2021-08-13 16:46:14 +02:00
StringName ClassDB : : get_category ( const StringName & p_node ) const {
return : : ClassDB : : get_category ( p_node ) ;
2017-01-02 23:03:46 -03:00
}
2021-08-13 16:46:14 +02:00
bool ClassDB : : is_class_enabled ( StringName p_class ) const {
return : : ClassDB : : is_class_enabled ( p_class ) ;
2017-01-02 23:03:46 -03:00
}
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-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_signal " , " class " , " signal " ) , & ClassDB : : has_signal ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_signal " , " class " , " signal " ) , & ClassDB : : get_signal ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_signal_list " , " class " , " no_inheritance " ) , & ClassDB : : get_signal_list , DEFVAL ( false ) ) ;
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property_list " , " class " , " no_inheritance " ) , & ClassDB : : get_property_list , DEFVAL ( false ) ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_property " , " object " , " property " ) , & ClassDB : : get_property ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_set_property " , " object " , " property " , " value " ) , & ClassDB : : set_property ) ;
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_method " , " class " , " method " , " no_inheritance " ) , & ClassDB : : has_method , DEFVAL ( false ) ) ;
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_method_list " , " class " , " no_inheritance " ) , & ClassDB : : get_method_list , DEFVAL ( false ) ) ;
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_integer_constant_list " , " class " , " no_inheritance " ) , & ClassDB : : get_integer_constant_list , DEFVAL ( false ) ) ;
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_has_integer_constant " , " class " , " name " ) , & ClassDB : : has_integer_constant ) ;
: : ClassDB : : bind_method ( D_METHOD ( " class_get_integer_constant " , " class " , " name " ) , & ClassDB : : get_integer_constant ) ;
2017-01-02 23:03:46 -03:00
2021-08-13 16:46:14 +02:00
: : ClassDB : : bind_method ( D_METHOD ( " class_get_category " , " class " ) , & ClassDB : : get_category ) ;
: : ClassDB : : bind_method ( D_METHOD ( " is_class_enabled " , " class " ) , & ClassDB : : is_class_enabled ) ;
2017-01-02 23:03:46 -03:00
}
2021-08-13 16:46:14 +02:00
} // namespace special
2017-01-13 12:51:14 -03: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 12:51:14 -03: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 12:51:14 -03:00
}
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 ) ;
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 ( ) ;
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 17:42:02 +01:00
}
2021-08-13 16:46:14 +02:00
void Engine : : set_target_fps ( int p_fps ) {
: : Engine : : get_singleton ( ) - > set_target_fps ( p_fps ) ;
2017-01-13 12:51:14 -03:00
}
2021-08-13 16:46:14 +02:00
int Engine : : get_target_fps ( ) const {
return : : Engine : : get_singleton ( ) - > get_target_fps ( ) ;
2017-01-13 12:51:14 -03: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 12:51:14 -03: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 12:51:14 -03:00
}
2021-08-13 16:46:14 +02:00
double Engine : : get_time_scale ( ) {
return : : Engine : : get_singleton ( ) - > get_time_scale ( ) ;
2017-01-13 12:51:14 -03:00
}
2021-08-13 16:46:14 +02:00
int Engine : : get_frames_drawn ( ) {
return : : Engine : : get_singleton ( ) - > get_frames_drawn ( ) ;
2017-01-13 12:51:14 -03: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 12:51:14 -03: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 12:51:14 -03: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 05:54:22 +01:00
}
2021-08-13 16:46:14 +02:00
Array Engine : : get_copyright_info ( ) const {
return : : Engine : : get_singleton ( ) - > get_copyright_info ( ) ;
2018-05-16 05:54:22 +01: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 05:54:22 +01: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 05:54:22 +01: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 05:54:22 +01:00
}
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-13 16:46:14 +02:00
bool Engine : : has_singleton ( const String & p_name ) const {
return : : Engine : : get_singleton ( ) - > has_singleton ( p_name ) ;
2017-11-13 21:46:57 +01:00
}
2021-08-13 16:46:14 +02:00
Object * Engine : : get_singleton_object ( const String & p_name ) const {
return : : Engine : : get_singleton ( ) - > get_singleton_object ( p_name ) ;
2017-11-13 21:46:57 +01:00
}
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
}
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
}
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 ) ;
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 ) ;
ClassDB : : bind_method ( D_METHOD ( " set_target_fps " , " target_fps " ) , & Engine : : set_target_fps ) ;
ClassDB : : bind_method ( D_METHOD ( " get_target_fps " ) , & Engine : : get_target_fps ) ;
2017-01-13 12:51:14 -03: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 12:51:14 -03: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 12:51:14 -03:00
2021-08-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_main_loop " ) , & Engine : : get_main_loop ) ;
2017-01-13 12:51:14 -03: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
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-13 16:46:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_editor_hint " , " enabled " ) , & Engine : : set_editor_hint ) ;
ClassDB : : bind_method ( D_METHOD ( " is_editor_hint " ) , & Engine : : is_editor_hint ) ;
2018-01-12 00:35:12 +02:00
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
2018-01-12 00:35:12 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " editor_hint " ) , " set_editor_hint " , " is_editor_hint " ) ;
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 " ) ;
2018-01-12 00:35:12 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " target_fps " ) , " set_target_fps " , " get_target_fps " ) ;
2020-02-24 15:20:53 -03: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 12:51:14 -03:00
}
2021-08-13 16:46:14 +02:00
Engine * Engine : : singleton = nullptr ;
2020-05-18 20:25:49 +05:30
2021-08-13 16:46:14 +02:00
////// EngineDebugger //////
2020-05-18 20:25:49 +05:30
2021-08-13 16:46:14 +02:00
bool EngineDebugger : : is_active ( ) {
return : : EngineDebugger : : is_active ( ) ;
2020-05-18 20:25:49 +05:30
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : register_profiler ( const StringName & p_name , const Callable & p_toggle , const Callable & p_add , const Callable & p_tick ) {
2020-05-18 20:25:49 +05:30
ERR_FAIL_COND_MSG ( profilers . has ( p_name ) | | has_profiler ( p_name ) , " Profiler already registered: " + p_name ) ;
profilers . insert ( p_name , ProfilerCallable ( p_toggle , p_add , p_tick ) ) ;
ProfilerCallable & p = profilers [ p_name ] ;
2021-08-13 16:46:14 +02:00
: : EngineDebugger : : Profiler profiler (
2020-05-18 20:25:49 +05:30
& p ,
2021-08-13 16:46:14 +02:00
& EngineDebugger : : call_toggle ,
& EngineDebugger : : call_add ,
& EngineDebugger : : call_tick ) ;
: : EngineDebugger : : register_profiler ( p_name , profiler ) ;
2020-05-18 20:25:49 +05:30
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : unregister_profiler ( const StringName & p_name ) {
2020-05-18 20:25:49 +05:30
ERR_FAIL_COND_MSG ( ! profilers . has ( p_name ) , " Profiler not registered: " + p_name ) ;
2021-08-13 16:46:14 +02:00
: : EngineDebugger : : unregister_profiler ( p_name ) ;
2020-05-18 20:25:49 +05:30
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 20:25:49 +05:30
}
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 20:25:49 +05:30
}
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 20:25:49 +05:30
}
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 20:25:49 +05:30
}
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : register_message_capture ( const StringName & p_name , const Callable & p_callable ) {
2020-05-18 20:25:49 +05:30
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 20:25:49 +05:30
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : unregister_message_capture ( const StringName & p_name ) {
2020-05-18 20:25:49 +05:30
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 20:25:49 +05:30
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 20:25:49 +05:30
}
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 20:25:49 +05:30
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : call_toggle ( void * p_user , bool p_enable , const Array & p_opts ) {
2020-05-18 20:25:49 +05:30
Callable & toggle = ( ( ProfilerCallable * ) p_user ) - > callable_toggle ;
if ( toggle . is_null ( ) ) {
return ;
}
Variant enable = p_enable , opts = p_opts ;
const Variant * args [ 2 ] = { & enable , & opts } ;
Variant retval ;
Callable : : CallError err ;
toggle . call ( args , 2 , retval , err ) ;
ERR_FAIL_COND_MSG ( err . error ! = Callable : : CallError : : CALL_OK , " Error calling 'toggle' to callable: " + Variant : : get_callable_error_text ( toggle , args , 2 , err ) ) ;
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : call_add ( void * p_user , const Array & p_data ) {
2020-05-18 20:25:49 +05:30
Callable & add = ( ( ProfilerCallable * ) p_user ) - > callable_add ;
if ( add . is_null ( ) ) {
return ;
}
Variant data = p_data ;
const Variant * args [ 1 ] = { & data } ;
Variant retval ;
Callable : : CallError err ;
add . call ( args , 1 , retval , err ) ;
ERR_FAIL_COND_MSG ( err . error ! = Callable : : CallError : : CALL_OK , " Error calling 'add' to callable: " + Variant : : get_callable_error_text ( add , args , 1 , err ) ) ;
}
2021-08-13 16:46:14 +02:00
void EngineDebugger : : call_tick ( void * p_user , double p_frame_time , double p_idle_time , double p_physics_time , double p_physics_frame_time ) {
2020-05-18 20:25:49 +05:30
Callable & tick = ( ( ProfilerCallable * ) p_user ) - > callable_tick ;
if ( tick . is_null ( ) ) {
return ;
}
Variant frame_time = p_frame_time , idle_time = p_idle_time , physics_time = p_physics_time , physics_frame_time = p_physics_frame_time ;
const Variant * args [ 4 ] = { & frame_time , & idle_time , & physics_time , & physics_frame_time } ;
Variant retval ;
Callable : : CallError err ;
tick . call ( args , 4 , retval , err ) ;
ERR_FAIL_COND_MSG ( err . error ! = Callable : : CallError : : CALL_OK , " Error calling 'tick' to callable: " + Variant : : get_callable_error_text ( tick , args , 4 , err ) ) ;
}
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 20:25:49 +05:30
Callable & capture = * ( Callable * ) p_user ;
if ( capture . is_null ( ) ) {
return FAILED ;
}
Variant cmd = p_cmd , data = p_data ;
const Variant * args [ 2 ] = { & cmd , & data } ;
Variant retval ;
Callable : : CallError err ;
capture . call ( args , 2 , retval , err ) ;
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 ;
}
2021-08-13 16:46:14 +02:00
EngineDebugger : : ~ EngineDebugger ( ) {
2020-05-18 20:25:49 +05:30
for ( Map < StringName , Callable > : : Element * E = captures . front ( ) ; E ; E = E - > next ( ) ) {
2021-08-13 16:46:14 +02:00
: : EngineDebugger : : unregister_message_capture ( E - > key ( ) ) ;
2020-05-18 20:25:49 +05:30
}
captures . clear ( ) ;
for ( Map < StringName , ProfilerCallable > : : Element * E = profilers . front ( ) ; E ; E = E - > next ( ) ) {
2021-08-13 16:46:14 +02:00
: : EngineDebugger : : unregister_profiler ( E - > key ( ) ) ;
2020-05-18 20:25:49 +05:30
}
profilers . 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 ) ;
ClassDB : : bind_method ( D_METHOD ( " register_profiler " , " name " , " toggle " , " add " , " tick " ) , & EngineDebugger : : register_profiler ) ;
ClassDB : : bind_method ( D_METHOD ( " unregister_profiler " , " name " ) , & EngineDebugger : : unregister_profiler ) ;
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 ) ;
ClassDB : : bind_method ( D_METHOD ( " send_message " , " message " , " data " ) , & EngineDebugger : : send_message ) ;
}
} // namespace core_bind