2017-12-06 21:36:34 +01:00
/*************************************************************************/
2014-02-10 02:10:30 +01:00
/* object.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# ifndef OBJECT_H
# define OBJECT_H
2021-06-19 17:58:49 +02:00
# include "core/extension/gdnative_interface.h"
2022-03-09 14:58:40 +01:00
# include "core/object/message_queue.h"
2020-11-07 23:33:38 +01:00
# include "core/object/object_id.h"
2018-09-11 18:13:45 +02:00
# include "core/os/rw_lock.h"
2020-11-07 23:33:38 +01:00
# include "core/os/spin_lock.h"
# include "core/templates/hash_map.h"
2022-05-19 17:00:06 +02:00
# include "core/templates/hash_set.h"
2020-11-07 23:33:38 +01:00
# include "core/templates/list.h"
2022-05-13 15:04:37 +02:00
# include "core/templates/rb_map.h"
2021-02-10 19:22:13 +01:00
# include "core/templates/safe_refcount.h"
2020-11-07 23:33:38 +01:00
# include "core/templates/vmap.h"
# include "core/variant/callable_bind.h"
# include "core/variant/variant.h"
2014-02-10 02:10:30 +01:00
enum PropertyHint {
PROPERTY_HINT_NONE , ///< no hint provided.
2022-06-24 10:45:34 +02:00
PROPERTY_HINT_RANGE , ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,no_slider][,radians][,degrees][,exp][,suffix:<keyword>] range.
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_ENUM , ///< hint_text= "val1,val2,val3,etc"
2021-07-04 22:42:23 +02:00
PROPERTY_HINT_ENUM_SUGGESTION , ///< hint_text= "val1,val2,val3,etc"
2018-05-15 22:12:35 +02:00
PROPERTY_HINT_EXP_EASING , /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_LENGTH , ///< hint_text= "length" (as integer)
2022-04-05 02:58:21 +02:00
PROPERTY_HINT_LINK ,
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_KEY_ACCEL , ///< hint_text= "length" (as integer)
PROPERTY_HINT_FLAGS , ///< hint_text= "flag1,flag2,etc" (as bit flags)
2017-01-11 02:20:57 +01:00
PROPERTY_HINT_LAYERS_2D_RENDER ,
PROPERTY_HINT_LAYERS_2D_PHYSICS ,
2021-03-08 20:56:33 +01:00
PROPERTY_HINT_LAYERS_2D_NAVIGATION ,
2017-01-11 02:20:57 +01:00
PROPERTY_HINT_LAYERS_3D_RENDER ,
PROPERTY_HINT_LAYERS_3D_PHYSICS ,
2021-03-08 20:56:33 +01:00
PROPERTY_HINT_LAYERS_3D_NAVIGATION ,
2015-08-30 02:09:11 +02:00
PROPERTY_HINT_FILE , ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
2017-09-22 05:58:29 +02:00
PROPERTY_HINT_DIR , ///< a directory path must be passed
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_GLOBAL_FILE , ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
2017-09-22 05:58:29 +02:00
PROPERTY_HINT_GLOBAL_DIR , ///< a directory path must be passed
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_RESOURCE_TYPE , ///< a resource object type
2015-08-30 02:09:11 +02:00
PROPERTY_HINT_MULTILINE_TEXT , ///< used for string properties that can contain multiple lines
2022-06-27 22:10:04 +02:00
PROPERTY_HINT_EXPRESSION , ///< used for string properties that can contain multiple lines
2018-08-17 03:50:12 +02:00
PROPERTY_HINT_PLACEHOLDER_TEXT , ///< used to set a placeholder text for string properties
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_COLOR_NO_ALPHA , ///< used for ignoring alpha component when editing a color
PROPERTY_HINT_IMAGE_COMPRESS_LOSSY ,
PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS ,
2016-05-23 00:28:37 +02:00
PROPERTY_HINT_OBJECT_ID ,
2016-08-03 00:11:05 +02:00
PROPERTY_HINT_TYPE_STRING , ///< a type string, the hint is the base type to choose
PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE , ///< so something else can provide this (used in scripts)
2016-08-24 00:29:07 +02:00
PROPERTY_HINT_METHOD_OF_VARIANT_TYPE , ///< a method of a type
PROPERTY_HINT_METHOD_OF_BASE_TYPE , ///< a method of a base type
PROPERTY_HINT_METHOD_OF_INSTANCE , ///< a method of an instance
PROPERTY_HINT_METHOD_OF_SCRIPT , ///< a method of a script & base
PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE , ///< a property of a type
PROPERTY_HINT_PROPERTY_OF_BASE_TYPE , ///< a property of a base type
PROPERTY_HINT_PROPERTY_OF_INSTANCE , ///< a property of an instance
PROPERTY_HINT_PROPERTY_OF_SCRIPT , ///< a property of a script & base
2017-08-18 15:59:31 +02:00
PROPERTY_HINT_OBJECT_TOO_BIG , ///< object is too big to send
2018-06-28 01:50:25 +02:00
PROPERTY_HINT_NODE_PATH_VALID_TYPES ,
2019-04-19 20:54:33 +02:00
PROPERTY_HINT_SAVE_FILE , ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
Implement Running Godot as Movie Writer
* Allows running the game in "movie writer" mode.
* It ensures entirely stable framerate, so your run can be saved stable and with proper sound (which is impossible if your CPU/GPU can't sustain doing this in real-time).
* If disabling vsync, it can save movies faster than the game is run, but if you want to control the interaction it can get difficult.
* Implements a simple, default MJPEG writer.
This new features has two main use cases, which have high demand:
* Saving game videos in high quality and ensuring the frame rate is *completely* stable, always.
* Using Godot as a tool to make movies and animations (which is ideal if you want interaction, or creating them procedurally. No other software is as good for this).
**Note**: This feature **IS NOT** for capturing real-time footage. Use something like OBS, SimpleScreenRecorder or FRAPS to achieve that, as they do a much better job at intercepting the compositor than Godot can probably do using Vulkan or OpenGL natively. If your game runs near real-time when capturing, you can still use this feature but it will play no sound (sound will be saved directly).
Usage:
$ godot --write-movie movie.avi [scene_file.tscn]
Missing:
* Options for configuring video writing via GLOBAL_DEF
* UI Menu for launching with this mode from the editor.
* Add to list of command line options.
* Add a feature tag to override configurations when movie writing (fantastic for saving videos with highest quality settings).
2022-06-17 00:55:19 +02:00
PROPERTY_HINT_GLOBAL_SAVE_FILE , ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
2020-02-12 18:24:06 +01:00
PROPERTY_HINT_INT_IS_OBJECTID ,
2020-04-21 00:06:00 +02:00
PROPERTY_HINT_ARRAY_TYPE ,
2021-08-23 19:53:27 +02:00
PROPERTY_HINT_INT_IS_POINTER ,
2021-09-23 13:08:50 +02:00
PROPERTY_HINT_LOCALE_ID ,
2022-03-04 14:04:59 +01:00
PROPERTY_HINT_LOCALIZABLE_STRING ,
2022-06-19 00:42:02 +02:00
PROPERTY_HINT_NODE_TYPE , ///< a node object type
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_MAX ,
2018-01-13 18:13:15 +01:00
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
2014-02-10 02:10:30 +01:00
} ;
enum PropertyUsageFlags {
2021-06-18 01:10:18 +02:00
PROPERTY_USAGE_NONE = 0 ,
2017-03-05 16:44:50 +01:00
PROPERTY_USAGE_STORAGE = 1 ,
PROPERTY_USAGE_EDITOR = 2 ,
PROPERTY_USAGE_NETWORK = 4 ,
PROPERTY_USAGE_EDITOR_HELPER = 8 ,
PROPERTY_USAGE_CHECKABLE = 16 , //used for editing global variables
PROPERTY_USAGE_CHECKED = 32 , //used for editing global variables
PROPERTY_USAGE_INTERNATIONALIZED = 64 , //hint for internationalized strings
PROPERTY_USAGE_GROUP = 128 , //used for grouping props in the editor
PROPERTY_USAGE_CATEGORY = 256 ,
2020-04-08 03:51:52 +02:00
PROPERTY_USAGE_SUBGROUP = 512 ,
2022-06-24 11:16:37 +02:00
PROPERTY_USAGE_CLASS_IS_BITFIELD = 1024 ,
2017-03-05 16:44:50 +01:00
PROPERTY_USAGE_NO_INSTANCE_STATE = 2048 ,
PROPERTY_USAGE_RESTART_IF_CHANGED = 4096 ,
PROPERTY_USAGE_SCRIPT_VARIABLE = 8192 ,
PROPERTY_USAGE_STORE_IF_NULL = 16384 ,
PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 32768 ,
PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 65536 ,
2017-08-06 14:32:52 +02:00
PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 < < 17 ,
2017-08-24 00:10:32 +02:00
PROPERTY_USAGE_CLASS_IS_ENUM = 1 < < 18 ,
PROPERTY_USAGE_NIL_IS_VARIANT = 1 < < 19 ,
2017-12-06 21:16:25 +01:00
PROPERTY_USAGE_INTERNAL = 1 < < 20 ,
2018-01-11 19:50:33 +01:00
PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 < < 21 , // If the object is duplicated also this property will be duplicated
2018-09-29 01:32:40 +02:00
PROPERTY_USAGE_HIGH_END_GFX = 1 < < 22 ,
2019-01-14 19:46:56 +01:00
PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 < < 23 ,
2019-02-22 00:49:42 +01:00
PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 < < 24 ,
2019-07-25 09:11:41 +02:00
PROPERTY_USAGE_KEYING_INCREMENTS = 1 < < 25 , // Used in inspector to increment property when keyed in animation player
2020-02-28 12:27:04 +01:00
PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 < < 26 , // when loading, the resource for this property can be set at the end of loading
2020-06-12 13:16:14 +02:00
PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 < < 27 , // For Object properties, instantiate them when creating in editor.
2021-02-17 17:44:49 +01:00
PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 < < 28 , //for project or editor settings, show when basic settings are selected
2021-08-31 10:48:45 +02:00
PROPERTY_USAGE_READ_ONLY = 1 < < 29 , // Mark a property as read-only in the inspector.
PROPERTY_USAGE_ARRAY = 1 < < 30 , // Used in the inspector to group properties as elements of an array.
2017-03-05 16:44:50 +01:00
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK ,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED ,
2021-11-03 23:06:17 +01:00
PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK ,
2014-02-10 02:10:30 +01:00
} ;
2021-08-13 16:46:14 +02:00
# define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal)
# define ADD_PROPERTY(m_property, m_setter, m_getter) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter))
# define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index)
# define ADD_PROPERTY_DEFAULT(m_property, m_default) ::ClassDB::set_property_default_value(get_class_static(), m_property, m_default)
# define ADD_GROUP(m_name, m_prefix) ::ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
2021-11-08 21:53:41 +01:00
# define ADD_GROUP_INDENT(m_name, m_prefix, m_depth) ::ClassDB::add_property_group(get_class_static(), m_name, m_prefix, m_depth)
2021-08-13 16:46:14 +02:00
# define ADD_SUBGROUP(m_name, m_prefix) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
2021-11-08 21:53:41 +01:00
# define ADD_SUBGROUP_INDENT(m_name, m_prefix, m_depth) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix, m_depth)
2021-08-12 20:26:47 +02:00
# define ADD_LINKED_PROPERTY(m_property, m_linked_property) ::ClassDB::add_linked_property(get_class_static(), m_property, m_linked_property)
2014-02-10 02:10:30 +01:00
2021-08-31 10:48:45 +02:00
# define ADD_ARRAY_COUNT(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, _scs_create(m_count_property_setter), _scs_create(m_count_property_getter), m_prefix)
# define ADD_ARRAY_COUNT_WITH_USAGE_FLAGS(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix, m_property_usage_flags) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, _scs_create(m_count_property_setter), _scs_create(m_count_property_getter), m_prefix, m_property_usage_flags)
# define ADD_ARRAY(m_array_path, m_prefix) ClassDB::add_property_array(get_class_static(), m_array_path, m_prefix)
2014-02-10 02:10:30 +01:00
struct PropertyInfo {
2020-05-12 17:01:17 +02:00
Variant : : Type type = Variant : : NIL ;
2014-02-10 02:10:30 +01:00
String name ;
2021-08-13 16:46:14 +02:00
StringName class_name ; // For classes
2020-05-12 17:01:17 +02:00
PropertyHint hint = PROPERTY_HINT_NONE ;
2015-08-30 02:09:11 +02:00
String hint_string ;
2020-05-12 17:01:17 +02:00
uint32_t usage = PROPERTY_USAGE_DEFAULT ;
2014-02-10 02:10:30 +01:00
2021-08-12 20:26:47 +02:00
# ifdef TOOLS_ENABLED
Vector < String > linked_properties ;
# endif
2021-07-01 03:24:34 +02:00
_FORCE_INLINE_ PropertyInfo added_usage ( uint32_t p_fl ) const {
2017-03-05 16:44:50 +01:00
PropertyInfo pi = * this ;
pi . usage | = p_fl ;
return pi ;
}
2016-08-25 22:45:20 +02:00
operator Dictionary ( ) const ;
2017-03-05 16:44:50 +01:00
static PropertyInfo from_dict ( const Dictionary & p_dict ) ;
2016-08-25 22:45:20 +02:00
2020-05-12 17:01:17 +02:00
PropertyInfo ( ) { }
2017-09-14 18:54:37 +02:00
2021-07-01 03:24:34 +02:00
PropertyInfo ( const Variant : : Type p_type , const String p_name , const PropertyHint p_hint = PROPERTY_HINT_NONE , const String & p_hint_string = " " , const uint32_t p_usage = PROPERTY_USAGE_DEFAULT , const StringName & p_class_name = StringName ( ) ) :
2017-12-06 21:36:34 +01:00
type ( p_type ) ,
name ( p_name ) ,
hint ( p_hint ) ,
hint_string ( p_hint_string ) ,
usage ( p_usage ) {
2017-08-24 00:10:32 +02:00
if ( hint = = PROPERTY_HINT_RESOURCE_TYPE ) {
class_name = hint_string ;
} else {
class_name = p_class_name ;
}
}
2017-09-14 18:54:37 +02:00
2017-12-06 21:36:34 +01:00
PropertyInfo ( const StringName & p_class_name ) :
type ( Variant : : OBJECT ) ,
2020-05-12 17:01:17 +02:00
class_name ( p_class_name ) { }
2017-08-24 00:10:32 +02:00
2022-06-06 22:24:13 +02:00
explicit PropertyInfo ( const GDNativePropertyInfo & pinfo ) :
type ( ( Variant : : Type ) pinfo . type ) ,
name ( pinfo . name ) ,
class_name ( pinfo . class_name ) , // can be null
hint ( ( PropertyHint ) pinfo . hint ) ,
hint_string ( pinfo . hint_string ) , // can be null
usage ( pinfo . usage ) { }
2019-07-05 22:30:01 +02:00
bool operator = = ( const PropertyInfo & p_info ) const {
return ( ( type = = p_info . type ) & &
( name = = p_info . name ) & &
( class_name = = p_info . class_name ) & &
( hint = = p_info . hint ) & &
( hint_string = = p_info . hint_string ) & &
( usage = = p_info . usage ) ) ;
}
2017-03-05 16:44:50 +01:00
bool operator < ( const PropertyInfo & p_info ) const {
return name < p_info . name ;
2015-05-01 02:53:41 +02:00
}
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
Array convert_property_list ( const List < PropertyInfo > * p_list ) ;
2014-02-10 02:10:30 +01:00
2022-06-23 12:21:07 +02:00
enum MethodFlags {
METHOD_FLAG_NORMAL = 1 ,
METHOD_FLAG_EDITOR = 2 ,
METHOD_FLAG_NOSCRIPT = 4 ,
METHOD_FLAG_CONST = 8 ,
METHOD_FLAG_REVERSE = 16 , // used for events
METHOD_FLAG_VIRTUAL = 32 ,
METHOD_FLAG_FROM_SCRIPT = 64 ,
METHOD_FLAG_VARARG = 128 ,
METHOD_FLAG_STATIC = 256 ,
METHOD_FLAG_OBJECT_CORE = 512 ,
METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL ,
} ;
2014-02-10 02:10:30 +01:00
struct MethodInfo {
String name ;
PropertyInfo return_val ;
2022-06-23 12:21:07 +02:00
uint32_t flags = METHOD_FLAGS_DEFAULT ;
2020-05-12 17:01:17 +02:00
int id = 0 ;
2018-09-28 17:17:38 +02:00
List < PropertyInfo > arguments ;
Vector < Variant > default_arguments ;
2015-08-30 02:09:11 +02:00
2017-08-26 21:41:25 +02:00
inline bool operator = = ( const MethodInfo & p_method ) const { return id = = p_method . id ; }
2017-03-05 16:44:50 +01:00
inline bool operator < ( const MethodInfo & p_method ) const { return id = = p_method . id ? ( name < p_method . name ) : ( id < p_method . id ) ; }
2015-08-30 02:09:11 +02:00
2016-08-25 22:45:20 +02:00
operator Dictionary ( ) const ;
2017-03-05 16:44:50 +01:00
static MethodInfo from_dict ( const Dictionary & p_dict ) ;
2020-05-12 17:01:17 +02:00
2022-06-23 12:21:07 +02:00
MethodInfo ( ) { }
void _push_params ( const PropertyInfo & p_param ) {
arguments . push_back ( p_param ) ;
}
template < typename . . . VarArgs >
void _push_params ( const PropertyInfo & p_param , VarArgs . . . p_params ) {
arguments . push_back ( p_param ) ;
_push_params ( p_params . . . ) ;
}
MethodInfo ( const String & p_name ) { name = p_name ; }
template < typename . . . VarArgs >
MethodInfo ( const String & p_name , VarArgs . . . p_params ) {
name = p_name ;
_push_params ( p_params . . . ) ;
}
MethodInfo ( Variant : : Type ret ) { return_val . type = ret ; }
MethodInfo ( Variant : : Type ret , const String & p_name ) {
return_val . type = ret ;
name = p_name ;
}
template < typename . . . VarArgs >
MethodInfo ( Variant : : Type ret , const String & p_name , VarArgs . . . p_params ) {
name = p_name ;
return_val . type = ret ;
_push_params ( p_params . . . ) ;
}
MethodInfo ( const PropertyInfo & p_ret , const String & p_name ) {
return_val = p_ret ;
name = p_name ;
}
template < typename . . . VarArgs >
MethodInfo ( const PropertyInfo & p_ret , const String & p_name , VarArgs . . . p_params ) {
return_val = p_ret ;
name = p_name ;
_push_params ( p_params . . . ) ;
}
2014-02-10 02:10:30 +01:00
} ;
2022-02-16 13:56:32 +01:00
// API used to extend in GDNative and other C compatible compiled languages.
2021-06-04 19:33:48 +02:00
class MethodBind ;
struct ObjectNativeExtension {
ObjectNativeExtension * parent = nullptr ;
2021-06-19 17:58:49 +02:00
List < ObjectNativeExtension * > children ;
2021-06-04 19:33:48 +02:00
StringName parent_class_name ;
StringName class_name ;
bool editor_class = false ;
2021-06-19 17:58:49 +02:00
GDNativeExtensionClassSet set ;
GDNativeExtensionClassGet get ;
GDNativeExtensionClassGetPropertyList get_property_list ;
GDNativeExtensionClassFreePropertyList free_property_list ;
GDNativeExtensionClassNotification notification ;
GDNativeExtensionClassToString to_string ;
GDNativeExtensionClassReference reference ;
GDNativeExtensionClassReference unreference ;
2022-03-10 08:17:38 +01:00
GDNativeExtensionClassGetRID get_rid ;
2021-06-04 19:33:48 +02:00
_FORCE_INLINE_ bool is_class ( const String & p_class ) const {
const ObjectNativeExtension * e = this ;
while ( e ) {
if ( p_class = = e - > class_name . operator String ( ) ) {
return true ;
}
e = e - > parent ;
}
return false ;
}
2021-06-19 17:58:49 +02:00
void * class_userdata = nullptr ;
GDNativeExtensionClassCreateInstance create_instance ;
GDNativeExtensionClassFreeInstance free_instance ;
GDNativeExtensionClassGetVirtual get_virtual ;
2021-06-04 19:33:48 +02:00
} ;
2022-03-10 08:17:38 +01:00
# define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__)
# define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__)
# define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__)
# define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__)
2021-08-22 03:52:44 +02:00
# ifdef DEBUG_METHODS_ENABLED
# define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__));
# else
# define GDVIRTUAL_BIND(m_name, ...)
# endif
2021-08-25 19:44:01 +02:00
# define GDVIRTUAL_IS_OVERRIDDEN(m_name) _gdvirtual_##m_name##_overridden()
# define GDVIRTUAL_IS_OVERRIDDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overridden()
2021-06-19 17:58:49 +02:00
2014-02-10 02:10:30 +01:00
/*
2022-02-16 13:56:32 +01:00
* The following is an incomprehensible blob of hacks and workarounds to
* compensate for many of the fallacies in C + + . As a plus , this macro pretty
* much alone defines the object model .
*/
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
# define REVERSE_GET_PROPERTY_LIST \
public : \
_FORCE_INLINE_ bool _is_gpl_reversed ( ) const { return true ; } ; \
\
2014-02-10 02:10:30 +01:00
private :
2017-03-05 16:44:50 +01:00
# define UNREVERSE_GET_PROPERTY_LIST \
public : \
_FORCE_INLINE_ bool _is_gpl_reversed ( ) const { return false ; } ; \
\
2014-02-10 02:10:30 +01:00
private :
2020-07-10 12:34:39 +02:00
# define GDCLASS(m_class, m_inherits) \
private : \
void operator = ( const m_class & p_rval ) { } \
mutable StringName _class_name ; \
2021-08-13 16:46:14 +02:00
friend class : : ClassDB ; \
2020-07-10 12:34:39 +02:00
\
public : \
virtual String get_class ( ) const override { \
2021-06-04 19:33:48 +02:00
if ( _get_extension ( ) ) { \
return _get_extension ( ) - > class_name . operator String ( ) ; \
} \
2020-07-10 12:34:39 +02:00
return String ( # m_class ) ; \
} \
virtual const StringName * _get_class_namev ( ) const override { \
2021-06-04 19:33:48 +02:00
if ( _get_extension ( ) ) { \
return & _get_extension ( ) - > class_name ; \
} \
2020-07-10 12:34:39 +02:00
if ( ! _class_name ) { \
_class_name = get_class_static ( ) ; \
} \
return & _class_name ; \
} \
static _FORCE_INLINE_ void * get_class_ptr_static ( ) { \
static int ptr ; \
return & ptr ; \
} \
static _FORCE_INLINE_ String get_class_static ( ) { \
return String ( # m_class ) ; \
} \
static _FORCE_INLINE_ String get_parent_class_static ( ) { \
return m_inherits : : get_class_static ( ) ; \
} \
static void get_inheritance_list_static ( List < String > * p_inheritance_list ) { \
m_inherits : : get_inheritance_list_static ( p_inheritance_list ) ; \
p_inheritance_list - > push_back ( String ( # m_class ) ) ; \
} \
2021-06-04 19:33:48 +02:00
virtual bool is_class ( const String & p_class ) const override { \
if ( _get_extension ( ) & & _get_extension ( ) - > is_class ( p_class ) ) { \
return true ; \
} \
return ( p_class = = ( # m_class ) ) ? true : m_inherits : : is_class ( p_class ) ; \
} \
2020-07-10 12:34:39 +02:00
virtual bool is_class_ptr ( void * p_ptr ) const override { return ( p_ptr = = get_class_ptr_static ( ) ) ? true : m_inherits : : is_class_ptr ( p_ptr ) ; } \
\
static void get_valid_parents_static ( List < String > * p_parents ) { \
if ( m_class : : _get_valid_parents_static ! = m_inherits : : _get_valid_parents_static ) { \
m_class : : _get_valid_parents_static ( p_parents ) ; \
} \
\
m_inherits : : get_valid_parents_static ( p_parents ) ; \
} \
\
protected : \
_FORCE_INLINE_ static void ( * _get_bind_methods ( ) ) ( ) { \
return & m_class : : _bind_methods ; \
} \
\
public : \
static void initialize_class ( ) { \
static bool initialized = false ; \
if ( initialized ) { \
return ; \
} \
m_inherits : : initialize_class ( ) ; \
2021-08-13 16:46:14 +02:00
: : ClassDB : : _add_class < m_class > ( ) ; \
2020-07-10 12:34:39 +02:00
if ( m_class : : _get_bind_methods ( ) ! = m_inherits : : _get_bind_methods ( ) ) { \
_bind_methods ( ) ; \
} \
initialized = true ; \
} \
\
protected : \
virtual void _initialize_classv ( ) override { \
initialize_class ( ) ; \
} \
_FORCE_INLINE_ bool ( Object : : * _get_get ( ) const ) ( const StringName & p_name , Variant & ) const { \
2021-10-28 16:01:30 +02:00
return ( bool ( Object : : * ) ( const StringName & , Variant & ) const ) & m_class : : _get ; \
2020-07-10 12:34:39 +02:00
} \
virtual bool _getv ( const StringName & p_name , Variant & r_ret ) const override { \
if ( m_class : : _get_get ( ) ! = m_inherits : : _get_get ( ) ) { \
if ( _get ( p_name , r_ret ) ) { \
return true ; \
} \
} \
return m_inherits : : _getv ( p_name , r_ret ) ; \
} \
_FORCE_INLINE_ bool ( Object : : * _get_set ( ) const ) ( const StringName & p_name , const Variant & p_property ) { \
2021-10-28 16:01:30 +02:00
return ( bool ( Object : : * ) ( const StringName & , const Variant & ) ) & m_class : : _set ; \
2020-07-10 12:34:39 +02:00
} \
virtual bool _setv ( const StringName & p_name , const Variant & p_property ) override { \
if ( m_inherits : : _setv ( p_name , p_property ) ) { \
return true ; \
} \
if ( m_class : : _get_set ( ) ! = m_inherits : : _get_set ( ) ) { \
return _set ( p_name , p_property ) ; \
} \
return false ; \
} \
_FORCE_INLINE_ void ( Object : : * _get_get_property_list ( ) const ) ( List < PropertyInfo > * p_list ) const { \
2021-10-28 16:01:30 +02:00
return ( void ( Object : : * ) ( List < PropertyInfo > * ) const ) & m_class : : _get_property_list ; \
2020-07-10 12:34:39 +02:00
} \
virtual void _get_property_listv ( List < PropertyInfo > * p_list , bool p_reversed ) const override { \
if ( ! p_reversed ) { \
m_inherits : : _get_property_listv ( p_list , p_reversed ) ; \
} \
p_list - > push_back ( PropertyInfo ( Variant : : NIL , get_class_static ( ) , PROPERTY_HINT_NONE , String ( ) , PROPERTY_USAGE_CATEGORY ) ) ; \
if ( ! _is_gpl_reversed ( ) ) { \
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_property_list ( # m_class , p_list , true , this ) ; \
2020-07-10 12:34:39 +02:00
} \
if ( m_class : : _get_get_property_list ( ) ! = m_inherits : : _get_get_property_list ( ) ) { \
_get_property_list ( p_list ) ; \
} \
if ( _is_gpl_reversed ( ) ) { \
2021-08-13 16:46:14 +02:00
: : ClassDB : : get_property_list ( # m_class , p_list , true , this ) ; \
2020-07-10 12:34:39 +02:00
} \
if ( p_reversed ) { \
m_inherits : : _get_property_listv ( p_list , p_reversed ) ; \
} \
} \
_FORCE_INLINE_ void ( Object : : * _get_notification ( ) const ) ( int ) { \
2021-10-28 16:01:30 +02:00
return ( void ( Object : : * ) ( int ) ) & m_class : : _notification ; \
2020-07-10 12:34:39 +02:00
} \
virtual void _notificationv ( int p_notification , bool p_reversed ) override { \
if ( ! p_reversed ) { \
m_inherits : : _notificationv ( p_notification , p_reversed ) ; \
} \
if ( m_class : : _get_notification ( ) ! = m_inherits : : _get_notification ( ) ) { \
_notification ( p_notification ) ; \
} \
if ( p_reversed ) { \
m_inherits : : _notificationv ( p_notification , p_reversed ) ; \
} \
} \
\
2014-02-10 02:10:30 +01:00
private :
2020-07-10 12:34:39 +02:00
# define OBJ_SAVE_TYPE(m_class) \
public : \
virtual String get_save_class ( ) const override { return # m_class ; } \
\
2014-02-10 02:10:30 +01:00
private :
class ScriptInstance ;
2015-08-30 02:09:11 +02:00
class Object {
2014-02-10 02:10:30 +01:00
public :
enum ConnectFlags {
2017-03-05 16:44:50 +01:00
CONNECT_DEFERRED = 1 ,
CONNECT_PERSIST = 2 , // hint for scene to save this connection
2018-08-20 18:38:18 +02:00
CONNECT_ONESHOT = 4 ,
CONNECT_REFERENCE_COUNTED = 8 ,
2014-02-10 02:10:30 +01:00
} ;
struct Connection {
2020-02-19 20:27:19 +01:00
: : Signal signal ;
Callable callable ;
2020-05-12 17:01:17 +02:00
uint32_t flags = 0 ;
2014-02-10 02:10:30 +01:00
Vector < Variant > binds ;
2017-03-05 16:44:50 +01:00
bool operator < ( const Connection & p_conn ) const ;
2014-02-10 02:10:30 +01:00
operator Variant ( ) const ;
2020-05-12 17:01:17 +02:00
Connection ( ) { }
2017-03-05 16:44:50 +01:00
Connection ( const Variant & p_variant ) ;
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
2014-02-10 02:10:30 +01:00
private :
2014-04-05 17:39:30 +02:00
# ifdef DEBUG_ENABLED
2018-10-01 16:46:50 +02:00
friend struct _ObjectDebugLock ;
2014-04-05 17:39:30 +02:00
# endif
2017-03-05 16:44:50 +01:00
friend bool predelete_handler ( Object * ) ;
friend void postinitialize_handler ( Object * ) ;
2014-02-10 02:10:30 +01:00
2021-06-04 19:33:48 +02:00
ObjectNativeExtension * _extension = nullptr ;
2021-06-19 17:58:49 +02:00
GDExtensionClassInstancePtr _extension_instance = nullptr ;
2021-06-04 19:33:48 +02:00
2020-02-19 20:27:19 +01:00
struct SignalData {
2014-02-10 02:10:30 +01:00
struct Slot {
2020-05-12 17:01:17 +02:00
int reference_count = 0 ;
2014-02-10 02:10:30 +01:00
Connection conn ;
2020-05-12 17:01:17 +02:00
List < Connection > : : Element * cE = nullptr ;
2014-02-10 02:10:30 +01:00
} ;
MethodInfo user ;
2020-02-19 20:27:19 +01:00
VMap < Callable , Slot > slot_map ;
2014-02-10 02:10:30 +01:00
} ;
2020-02-19 20:27:19 +01:00
HashMap < StringName , SignalData > signal_map ;
2014-02-10 02:10:30 +01:00
List < Connection > connections ;
2014-04-05 17:39:30 +02:00
# ifdef DEBUG_ENABLED
SafeRefCount _lock_index ;
# endif
2020-05-12 17:01:17 +02:00
bool _block_signals = false ;
int _predelete_ok = 0 ;
2019-05-09 11:21:49 +02:00
ObjectID _instance_id ;
2014-02-10 02:10:30 +01:00
bool _predelete ( ) ;
void _postinitialize ( ) ;
2020-05-12 17:01:17 +02:00
bool _can_translate = true ;
bool _emitting = false ;
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
2020-05-12 17:01:17 +02:00
bool _edited = false ;
uint32_t _edited_version = 0 ;
2022-05-19 17:00:06 +02:00
HashSet < String > editor_section_folding ;
2014-02-10 02:10:30 +01:00
# endif
2020-05-12 17:01:17 +02:00
ScriptInstance * script_instance = nullptr ;
2022-02-16 13:56:32 +01:00
Variant script ; // Reference does not exist yet, store it in a Variant.
2022-05-08 10:09:19 +02:00
HashMap < StringName , Variant > metadata ;
HashMap < StringName , Variant * > metadata_properties ;
2017-01-03 03:03:46 +01:00
mutable StringName _class_name ;
2020-05-12 17:01:17 +02:00
mutable const StringName * _class_ptr = nullptr ;
2014-02-10 02:10:30 +01:00
2017-08-11 21:10:05 +02:00
void _add_user_signal ( const String & p_name , const Array & p_args = Array ( ) ) ;
2017-03-05 16:44:50 +01:00
bool _has_user_signal ( const StringName & p_name ) const ;
2022-02-22 12:15:43 +01:00
Error _emit_signal ( const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2014-02-10 02:10:30 +01:00
Array _get_signal_list ( ) const ;
2022-06-14 15:28:59 +02:00
Array _get_signal_connection_list ( const StringName & p_signal ) const ;
2017-06-15 15:31:57 +02:00
Array _get_incoming_connections ( ) const ;
2022-06-14 15:28:59 +02:00
void _set_bind ( const StringName & p_set , const Variant & p_value ) ;
Variant _get_bind ( const StringName & p_name ) const ;
2017-05-30 22:20:15 +02:00
void _set_indexed_bind ( const NodePath & p_name , const Variant & p_value ) ;
Variant _get_indexed_bind ( const NodePath & p_name ) const ;
2014-02-10 02:10:30 +01:00
2020-02-13 20:03:10 +01:00
_FORCE_INLINE_ void _construct_object ( bool p_reference ) ;
2021-06-04 18:03:15 +02:00
friend class RefCounted ;
2020-02-13 20:03:10 +01:00
bool type_is_reference = false ;
2021-07-08 21:16:02 +02:00
std : : mutex _instance_binding_mutex ;
struct InstanceBinding {
2022-04-04 15:06:57 +02:00
void * binding = nullptr ;
void * token = nullptr ;
2021-07-08 21:16:02 +02:00
GDNativeInstanceBindingFreeCallback free_callback = nullptr ;
GDNativeInstanceBindingReferenceCallback reference_callback = nullptr ;
} ;
InstanceBinding * _instance_bindings = nullptr ;
uint32_t _instance_binding_count = 0 ;
2020-05-12 17:01:17 +02:00
2020-02-13 20:03:10 +01:00
Object ( bool p_reference ) ;
2018-02-22 15:34:08 +01:00
2015-08-30 02:09:11 +02:00
protected :
2021-07-08 21:16:02 +02:00
_FORCE_INLINE_ bool _instance_binding_reference ( bool p_reference ) {
bool can_die = true ;
if ( _instance_bindings ) {
_instance_binding_mutex . lock ( ) ;
for ( uint32_t i = 0 ; i < _instance_binding_count ; i + + ) {
if ( _instance_bindings [ i ] . reference_callback ) {
if ( ! _instance_bindings [ i ] . reference_callback ( _instance_bindings [ i ] . token , _instance_bindings [ i ] . binding , p_reference ) ) {
can_die = false ;
}
}
}
_instance_binding_mutex . unlock ( ) ;
}
return can_die ;
}
2022-02-16 13:56:32 +01:00
2021-06-19 17:58:49 +02:00
friend class NativeExtensionMethodBind ;
2021-06-04 19:33:48 +02:00
_ALWAYS_INLINE_ const ObjectNativeExtension * _get_extension ( ) const { return _extension ; }
2021-06-19 17:58:49 +02:00
_ALWAYS_INLINE_ GDExtensionClassInstancePtr _get_extension_instance ( ) const { return _extension_instance ; }
2017-01-03 03:03:46 +01:00
virtual void _initialize_classv ( ) { initialize_class ( ) ; }
2017-03-05 16:44:50 +01:00
virtual bool _setv ( const StringName & p_name , const Variant & p_property ) { return false ; } ;
virtual bool _getv ( const StringName & p_name , Variant & r_property ) const { return false ; } ;
virtual void _get_property_listv ( List < PropertyInfo > * p_list , bool p_reversed ) const { } ;
2020-05-12 17:01:17 +02:00
virtual void _notificationv ( int p_notification , bool p_reversed ) { }
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
static void _bind_methods ( ) ;
2017-03-05 16:44:50 +01:00
bool _set ( const StringName & p_name , const Variant & p_property ) { return false ; } ;
bool _get ( const StringName & p_name , Variant & r_property ) const { return false ; } ;
2014-02-10 02:10:30 +01:00
void _get_property_list ( List < PropertyInfo > * p_list ) const { } ;
2020-05-12 17:01:17 +02:00
void _notification ( int p_notification ) { }
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ static void ( * _get_bind_methods ( ) ) ( ) {
return & Object : : _bind_methods ;
}
2018-09-30 22:25:55 +02:00
_FORCE_INLINE_ bool ( Object : : * _get_get ( ) const ) ( const StringName & p_name , Variant & r_ret ) const {
2014-02-10 02:10:30 +01:00
return & Object : : _get ;
}
2018-09-30 22:25:55 +02:00
_FORCE_INLINE_ bool ( Object : : * _get_set ( ) const ) ( const StringName & p_name , const Variant & p_property ) {
2017-03-05 16:44:50 +01:00
return & Object : : _set ;
2014-02-10 02:10:30 +01:00
}
2018-09-30 22:25:55 +02:00
_FORCE_INLINE_ void ( Object : : * _get_get_property_list ( ) const ) ( List < PropertyInfo > * p_list ) const {
2017-03-05 16:44:50 +01:00
return & Object : : _get_property_list ;
2015-08-30 02:09:11 +02:00
}
2018-09-30 22:25:55 +02:00
_FORCE_INLINE_ void ( Object : : * _get_notification ( ) const ) ( int ) {
2017-03-05 16:44:50 +01:00
return & Object : : _notification ;
2015-08-30 02:09:11 +02:00
}
2014-02-10 02:10:30 +01:00
static void get_valid_parents_static ( List < String > * p_parents ) ;
static void _get_valid_parents_static ( List < String > * p_parents ) ;
2015-08-30 02:09:11 +02:00
2020-02-19 20:27:19 +01:00
Variant _call_bind ( const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
Variant _call_deferred_bind ( const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
virtual const StringName * _get_class_namev ( ) const {
2020-05-14 16:41:43 +02:00
if ( ! _class_name ) {
2017-03-05 16:44:50 +01:00
_class_name = get_class_static ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-01-03 03:03:46 +01:00
return & _class_name ;
2015-06-29 05:29:49 +02:00
}
2014-02-10 02:10:30 +01:00
2021-07-22 22:37:17 +02:00
Vector < StringName > _get_meta_list_bind ( ) const ;
2014-02-10 02:10:30 +01:00
Array _get_property_list_bind ( ) const ;
2015-05-25 06:46:45 +02:00
Array _get_method_list_bind ( ) const ;
2014-02-10 02:10:30 +01:00
2015-06-22 05:03:19 +02:00
void _clear_internal_resource_paths ( const Variant & p_var ) ;
2017-03-05 16:44:50 +01:00
friend class ClassDB ;
virtual void _validate_property ( PropertyInfo & property ) const ;
2016-05-15 04:48:23 +02:00
2020-02-19 20:27:19 +01:00
void _disconnect ( const StringName & p_signal , const Callable & p_callable , bool p_force = false ) ;
2018-08-20 21:35:36 +02:00
2022-02-16 13:56:32 +01:00
public : // Should be protected, but bug in clang++.
2017-01-03 03:03:46 +01:00
static void initialize_class ( ) ;
2020-05-12 17:01:17 +02:00
_FORCE_INLINE_ static void register_custom_data_to_otdb ( ) { }
2014-02-10 02:10:30 +01:00
public :
2021-02-10 21:18:45 +01:00
void notify_property_list_changed ( ) ;
2017-03-05 16:44:50 +01:00
static void * get_class_ptr_static ( ) {
2014-02-10 02:10:30 +01:00
static int ptr ;
return & ptr ;
}
bool _is_gpl_reversed ( ) const { return false ; }
2022-03-23 10:08:58 +01:00
void detach_from_objectdb ( ) ;
2019-05-09 11:21:49 +02:00
_FORCE_INLINE_ ObjectID get_instance_id ( ) const { return _instance_id ; }
2014-02-10 02:10:30 +01:00
2017-08-24 21:58:13 +02:00
template < class T >
static T * cast_to ( Object * p_object ) {
# ifndef NO_SAFE_CAST
return dynamic_cast < T * > ( p_object ) ;
# else
2020-05-14 16:41:43 +02:00
if ( ! p_object ) {
2020-04-02 01:20:12 +02:00
return nullptr ;
2020-05-14 16:41:43 +02:00
}
if ( p_object - > is_class_ptr ( T : : get_class_ptr_static ( ) ) ) {
2017-08-26 17:10:58 +02:00
return static_cast < T * > ( p_object ) ;
2020-05-14 16:41:43 +02:00
} else {
2020-04-02 01:20:12 +02:00
return nullptr ;
2020-05-14 16:41:43 +02:00
}
2017-08-24 21:58:13 +02:00
# endif
}
template < class T >
static const T * cast_to ( const Object * p_object ) {
# ifndef NO_SAFE_CAST
return dynamic_cast < const T * > ( p_object ) ;
# else
2020-05-14 16:41:43 +02:00
if ( ! p_object ) {
2020-04-02 01:20:12 +02:00
return nullptr ;
2020-05-14 16:41:43 +02:00
}
if ( p_object - > is_class_ptr ( T : : get_class_ptr_static ( ) ) ) {
2017-08-24 21:58:13 +02:00
return static_cast < const T * > ( p_object ) ;
2020-05-14 16:41:43 +02:00
} else {
2020-04-02 01:20:12 +02:00
return nullptr ;
2020-05-14 16:41:43 +02:00
}
2017-08-24 21:58:13 +02:00
# endif
}
2014-02-10 02:10:30 +01:00
enum {
2017-03-05 16:44:50 +01:00
NOTIFICATION_POSTINITIALIZE = 0 ,
NOTIFICATION_PREDELETE = 1
2014-02-10 02:10:30 +01:00
} ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
/* TYPE API */
2017-03-05 16:44:50 +01:00
static void get_inheritance_list_static ( List < String > * p_inheritance_list ) { p_inheritance_list - > push_back ( " Object " ) ; }
2014-02-10 02:10:30 +01:00
2017-01-03 03:03:46 +01:00
static String get_class_static ( ) { return " Object " ; }
static String get_parent_class_static ( ) { return String ( ) ; }
2014-02-10 02:10:30 +01:00
2021-06-04 19:33:48 +02:00
virtual String get_class ( ) const {
2022-01-27 17:34:33 +01:00
if ( _extension ) {
2021-06-04 19:33:48 +02:00
return _extension - > class_name . operator String ( ) ;
2022-01-27 17:34:33 +01:00
}
2021-06-04 19:33:48 +02:00
return " Object " ;
}
2017-01-03 03:03:46 +01:00
virtual String get_save_class ( ) const { return get_class ( ) ; } //class stored when saving
2015-06-29 05:29:49 +02:00
2021-06-04 19:33:48 +02:00
virtual bool is_class ( const String & p_class ) const {
if ( _extension & & _extension - > is_class ( p_class ) ) {
return true ;
}
return ( p_class = = " Object " ) ;
}
2017-03-05 16:44:50 +01:00
virtual bool is_class_ptr ( void * p_ptr ) const { return get_class_ptr_static ( ) = = p_ptr ; }
2015-06-29 05:29:49 +02:00
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ const StringName & get_class_name ( ) const {
2021-06-04 19:33:48 +02:00
if ( _extension ) {
return _extension - > class_name ;
}
2017-01-03 03:03:46 +01:00
if ( ! _class_ptr ) {
return * _get_class_namev ( ) ;
2015-06-29 05:29:49 +02:00
} else {
2017-01-03 03:03:46 +01:00
return * _class_ptr ;
2015-06-29 05:29:49 +02:00
}
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
/* IAPI */
2020-04-02 01:20:12 +02:00
void set ( const StringName & p_name , const Variant & p_value , bool * r_valid = nullptr ) ;
Variant get ( const StringName & p_name , bool * r_valid = nullptr ) const ;
void set_indexed ( const Vector < StringName > & p_names , const Variant & p_value , bool * r_valid = nullptr ) ;
Variant get_indexed ( const Vector < StringName > & p_names , bool * r_valid = nullptr ) const ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
void get_property_list ( List < PropertyInfo > * p_list , bool p_reversed = false ) const ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
bool has_method ( const StringName & p_method ) const ;
2014-02-10 02:10:30 +01:00
void get_method_list ( List < MethodInfo > * p_list ) const ;
2017-03-05 16:44:50 +01:00
Variant callv ( const StringName & p_method , const Array & p_args ) ;
2022-03-09 14:58:40 +01:00
virtual Variant callp ( const StringName & p_method , const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2022-06-27 22:10:04 +02:00
virtual Variant call_const ( const StringName & p_method , const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2022-03-09 14:58:40 +01:00
template < typename . . . VarArgs >
Variant call ( const StringName & p_method , VarArgs . . . p_args ) {
Variant args [ sizeof . . . ( p_args ) + 1 ] = { p_args . . . , Variant ( ) } ; // +1 makes sure zero sized arrays are also supported.
const Variant * argptrs [ sizeof . . . ( p_args ) + 1 ] ;
for ( uint32_t i = 0 ; i < sizeof . . . ( p_args ) ; i + + ) {
argptrs [ i ] = & args [ i ] ;
}
Callable : : CallError cerr ;
return callp ( p_method , sizeof . . . ( p_args ) = = 0 ? nullptr : ( const Variant * * ) argptrs , sizeof . . . ( p_args ) , cerr ) ;
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
void notification ( int p_notification , bool p_reversed = false ) ;
2020-09-15 17:14:45 +02:00
virtual String to_string ( ) ;
2014-02-10 02:10:30 +01:00
2022-02-16 13:56:32 +01:00
// Used mainly by script, get and set all INCLUDING string.
2020-04-02 01:20:12 +02:00
virtual Variant getvar ( const Variant & p_key , bool * r_valid = nullptr ) const ;
virtual void setvar ( const Variant & p_key , const Variant & p_value , bool * r_valid = nullptr ) ;
2014-02-10 02:10:30 +01:00
/* SCRIPT */
2015-08-30 02:09:11 +02:00
2020-02-13 20:03:10 +01:00
void set_script ( const Variant & p_script ) ;
Variant get_script ( ) const ;
2014-02-10 02:10:30 +01:00
2021-07-22 22:37:17 +02:00
bool has_meta ( const StringName & p_name ) const ;
void set_meta ( const StringName & p_name , const Variant & p_value ) ;
void remove_meta ( const StringName & p_name ) ;
2022-02-27 22:03:33 +01:00
Variant get_meta ( const StringName & p_name , const Variant & p_default = Variant ( ) ) const ;
2021-07-22 22:37:17 +02:00
void get_meta_list ( List < StringName > * p_list ) const ;
2014-02-10 02:10:30 +01:00
# ifdef TOOLS_ENABLED
void set_edited ( bool p_edited ) ;
bool is_edited ( ) const ;
2022-02-16 13:56:32 +01:00
// This function is used to check when something changed beyond a point, it's used mainly for generating previews.
uint32_t get_edited_version ( ) const ;
2014-02-10 02:10:30 +01:00
# endif
void set_script_instance ( ScriptInstance * p_instance ) ;
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ ScriptInstance * get_script_instance ( ) const { return script_instance ; }
2014-02-10 02:10:30 +01:00
2022-02-16 13:56:32 +01:00
// Some script languages can't control instance creation, so this function eases the process.
void set_script_and_instance ( const Variant & p_script , ScriptInstance * p_instance ) ;
2017-07-22 21:57:56 +02:00
2017-03-05 16:44:50 +01:00
void add_user_signal ( const MethodInfo & p_signal ) ;
2022-03-09 14:58:40 +01:00
template < typename . . . VarArgs >
Error emit_signal ( const StringName & p_name , VarArgs . . . p_args ) {
Variant args [ sizeof . . . ( p_args ) + 1 ] = { p_args . . . , Variant ( ) } ; // +1 makes sure zero sized arrays are also supported.
const Variant * argptrs [ sizeof . . . ( p_args ) + 1 ] ;
for ( uint32_t i = 0 ; i < sizeof . . . ( p_args ) ; i + + ) {
argptrs [ i ] = & args [ i ] ;
}
return emit_signalp ( p_name , sizeof . . . ( p_args ) = = 0 ? nullptr : ( const Variant * * ) argptrs , sizeof . . . ( p_args ) ) ;
}
Error emit_signalp ( const StringName & p_name , const Variant * * p_args , int p_argcount ) ;
2019-11-10 06:59:44 +01:00
bool has_signal ( const StringName & p_name ) const ;
2017-03-05 16:44:50 +01:00
void get_signal_list ( List < MethodInfo > * p_signals ) const ;
void get_signal_connection_list ( const StringName & p_signal , List < Connection > * p_connections ) const ;
2015-05-10 20:45:33 +02:00
void get_all_signal_connections ( List < Connection > * p_connections ) const ;
2019-08-16 22:30:31 +02:00
int get_persistent_signal_connection_count ( ) const ;
2016-06-07 07:39:40 +02:00
void get_signals_connected_to_this ( List < Connection > * p_connections ) const ;
2014-02-10 02:10:30 +01:00
2020-02-19 20:27:19 +01:00
Error connect ( const StringName & p_signal , const Callable & p_callable , const Vector < Variant > & p_binds = Vector < Variant > ( ) , uint32_t p_flags = 0 ) ;
void disconnect ( const StringName & p_signal , const Callable & p_callable ) ;
bool is_connected ( const StringName & p_signal , const Callable & p_callable ) const ;
2014-02-10 02:10:30 +01:00
2022-03-09 14:58:40 +01:00
template < typename . . . VarArgs >
void call_deferred ( const StringName & p_name , VarArgs . . . p_args ) {
MessageQueue : : get_singleton ( ) - > push_call ( this , p_name , p_args . . . ) ;
}
2018-11-16 12:49:26 +01:00
void set_deferred ( const StringName & p_property , const Variant & p_value ) ;
2014-02-10 02:10:30 +01:00
void set_block_signals ( bool p_block ) ;
bool is_blocking_signals ( ) const ;
2020-04-02 01:20:12 +02:00
Variant : : Type get_static_property_type ( const StringName & p_property , bool * r_valid = nullptr ) const ;
Variant : : Type get_static_property_type_indexed ( const Vector < StringName > & p_path , bool * r_valid = nullptr ) const ;
2015-12-05 18:18:22 +01:00
2014-02-10 02:10:30 +01:00
virtual void get_translatable_strings ( List < String > * p_strings ) const ;
2017-03-05 16:44:50 +01:00
virtual void get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const ;
2014-02-10 02:10:30 +01:00
2022-02-16 13:56:32 +01:00
// Translate message (internationalization).
String tr ( const StringName & p_message , const StringName & p_context = " " ) const ;
2020-07-16 10:52:06 +02:00
String tr_n ( const StringName & p_message , const StringName & p_message_plural , int p_n , const StringName & p_context = " " ) const ;
2014-02-10 02:10:30 +01:00
2022-02-16 13:56:32 +01:00
bool _is_queued_for_deletion = false ; // Set to true by SceneTree::queue_delete().
2015-08-30 02:09:11 +02:00
bool is_queued_for_deletion ( ) const ;
2015-03-28 18:34:28 +01:00
2017-08-18 22:29:15 +02:00
_FORCE_INLINE_ void set_message_translation ( bool p_enable ) { _can_translate = p_enable ; }
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ bool can_translate_messages ( ) const { return _can_translate ; }
2015-06-22 05:03:19 +02:00
2017-06-25 22:30:28 +02:00
# ifdef TOOLS_ENABLED
void editor_set_section_unfold ( const String & p_section , bool p_unfolded ) ;
bool editor_is_section_unfolded ( const String & p_section ) ;
2022-05-19 17:00:06 +02:00
const HashSet < String > & editor_get_section_folding ( ) const { return editor_section_folding ; }
2018-10-29 20:36:31 +01:00
void editor_clear_section_folding ( ) { editor_section_folding . clear ( ) ; }
2017-06-25 22:30:28 +02:00
# endif
2021-07-15 16:41:57 +02:00
// Used by script languages to store binding data.
2021-07-08 21:16:02 +02:00
void * get_instance_binding ( void * p_token , const GDNativeInstanceBindingCallbacks * p_callbacks ) ;
2021-07-15 16:41:57 +02:00
// Used on creation by binding only.
void set_instance_binding ( void * p_token , void * p_binding , const GDNativeInstanceBindingCallbacks * p_callbacks ) ;
2021-08-16 17:16:36 +02:00
bool has_instance_binding ( void * p_token ) ;
2017-07-16 17:39:23 +02:00
2015-06-22 05:03:19 +02:00
void clear_internal_resource_paths ( ) ;
2021-06-04 18:03:15 +02:00
_ALWAYS_INLINE_ bool is_ref_counted ( ) const { return type_is_reference ; }
2020-05-12 17:01:17 +02:00
2015-08-30 02:09:11 +02:00
Object ( ) ;
2014-02-10 02:10:30 +01:00
virtual ~ Object ( ) ;
} ;
bool predelete_handler ( Object * p_object ) ;
void postinitialize_handler ( Object * p_object ) ;
class ObjectDB {
2022-02-16 13:56:32 +01:00
// This needs to add up to 63, 1 bit is for reference.
2020-02-13 20:03:10 +01:00
# define OBJECTDB_VALIDATOR_BITS 39
# define OBJECTDB_VALIDATOR_MASK ((uint64_t(1) << OBJECTDB_VALIDATOR_BITS) - 1)
# define OBJECTDB_SLOT_MAX_COUNT_BITS 24
# define OBJECTDB_SLOT_MAX_COUNT_MASK ((uint64_t(1) << OBJECTDB_SLOT_MAX_COUNT_BITS) - 1)
# define OBJECTDB_REFERENCE_BIT (uint64_t(1) << (OBJECTDB_SLOT_MAX_COUNT_BITS + OBJECTDB_VALIDATOR_BITS))
2022-02-16 13:56:32 +01:00
struct ObjectSlot { // 128 bits per slot.
2020-02-13 20:03:10 +01:00
uint64_t validator : OBJECTDB_VALIDATOR_BITS ;
uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS ;
2021-06-04 18:03:15 +02:00
uint64_t is_ref_counted : 1 ;
2022-04-04 15:06:57 +02:00
Object * object = nullptr ;
2014-02-10 02:10:30 +01:00
} ;
2020-02-13 20:03:10 +01:00
static SpinLock spin_lock ;
static uint32_t slot_count ;
static uint32_t slot_max ;
static ObjectSlot * object_slots ;
static uint64_t validator_counter ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
friend class Object ;
friend void unregister_core_types ( ) ;
2014-02-10 02:10:30 +01:00
static void cleanup ( ) ;
2020-02-13 20:03:10 +01:00
2017-06-09 05:23:50 +02:00
static ObjectID add_instance ( Object * p_object ) ;
2014-02-10 02:10:30 +01:00
static void remove_instance ( Object * p_object ) ;
2020-02-13 20:03:10 +01:00
2017-03-05 16:44:50 +01:00
friend void register_core_types ( ) ;
2017-01-07 22:25:37 +01:00
static void setup ( ) ;
2015-08-30 02:09:11 +02:00
public :
2014-02-10 02:10:30 +01:00
typedef void ( * DebugFunc ) ( Object * p_obj ) ;
2020-02-13 20:03:10 +01:00
_ALWAYS_INLINE_ static Object * get_instance ( ObjectID p_instance_id ) {
uint64_t id = p_instance_id ;
uint32_t slot = id & OBJECTDB_SLOT_MAX_COUNT_MASK ;
2022-02-16 13:56:32 +01:00
ERR_FAIL_COND_V ( slot > = slot_max , nullptr ) ; // This should never happen unless RID is corrupted.
2020-02-13 20:03:10 +01:00
spin_lock . lock ( ) ;
2014-02-10 02:10:30 +01:00
2020-02-13 20:03:10 +01:00
uint64_t validator = ( id > > OBJECTDB_SLOT_MAX_COUNT_BITS ) & OBJECTDB_VALIDATOR_MASK ;
2014-02-10 02:10:30 +01:00
2020-02-13 20:03:10 +01:00
if ( unlikely ( object_slots [ slot ] . validator ! = validator ) ) {
spin_lock . unlock ( ) ;
return nullptr ;
}
Object * object = object_slots [ slot ] . object ;
2019-07-28 22:19:44 +02:00
2020-02-13 20:03:10 +01:00
spin_lock . unlock ( ) ;
2019-07-28 22:19:44 +02:00
2020-02-13 20:03:10 +01:00
return object ;
2014-02-10 02:10:30 +01:00
}
2020-02-13 20:03:10 +01:00
static void debug_objects ( DebugFunc p_func ) ;
static int get_object_count ( ) ;
2014-02-10 02:10:30 +01:00
} ;
2020-03-25 11:10:34 +01:00
# endif // OBJECT_H