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
/*************************************************************************/
2020-01-01 11:16:22 +01:00
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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
2020-10-09 23:41:53 +02:00
# include "core/callable_bind.h"
2018-09-11 18:13:45 +02:00
# include "core/hash_map.h"
# include "core/list.h"
# include "core/map.h"
2020-02-12 18:24:06 +01:00
# include "core/object_id.h"
2018-09-11 18:13:45 +02:00
# include "core/os/rw_lock.h"
# include "core/set.h"
2020-02-13 20:03:10 +01:00
# include "core/spin_lock.h"
2018-09-11 18:13:45 +02:00
# include "core/variant.h"
# include "core/vmap.h"
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
# define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()
# define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5
# define VARIANT_ARG_DECLARE const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5
2014-02-10 02:10:30 +01:00
# define VARIANT_ARG_MAX 5
2017-03-05 16:44:50 +01:00
# define VARIANT_ARGPTRS const Variant *argptr[5] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5 };
# define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4]
# define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4]
2014-02-10 02:10:30 +01:00
/**
@ author Juan Linietsky < reduzio @ gmail . com >
*/
enum PropertyHint {
PROPERTY_HINT_NONE , ///< no hint provided.
2015-08-30 02:09:11 +02:00
PROPERTY_HINT_RANGE , ///< hint_text = "min,max,step,slider; //slider is optional"
2014-02-10 02:10:30 +01:00
PROPERTY_HINT_EXP_RANGE , ///< hint_text = "min,max,step", exponential edit
PROPERTY_HINT_ENUM , ///< 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)
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 ,
PROPERTY_HINT_LAYERS_3D_RENDER ,
PROPERTY_HINT_LAYERS_3D_PHYSICS ,
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
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
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 ,
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 {
2015-08-30 02:09:11 +02:00
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 ,
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.
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 ,
2018-01-11 23:35:12 +01:00
PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK ,
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01: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)
2019-06-01 15:42:22 +02:00
# define ADD_PROPERTY_DEFAULT(m_property, m_default) ClassDB::set_property_default_value(get_class_static(), m_property, m_default)
2017-03-05 16:44:50 +01:00
# define ADD_GROUP(m_name, m_prefix) ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
2020-04-08 03:51:52 +02:00
# define ADD_SUBGROUP(m_name, m_prefix) ClassDB::add_property_subgroup(get_class_static(), m_name, 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 ;
2017-08-24 00:10:32 +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
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ PropertyInfo added_usage ( int p_fl ) const {
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
2017-12-06 21:36:34 +01:00
PropertyInfo ( Variant : : Type p_type , const String p_name , PropertyHint p_hint = PROPERTY_HINT_NONE , const String & p_hint_string = " " , uint32_t p_usage = PROPERTY_USAGE_DEFAULT , const StringName & p_class_name = StringName ( ) ) :
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
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
struct MethodInfo {
String name ;
PropertyInfo return_val ;
2020-05-12 17:01:17 +02:00
uint32_t flags ; // NOLINT - prevent clang-tidy to assign method_bind.h constant here, it should stay in .cpp.
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
2014-02-10 02:10:30 +01:00
MethodInfo ( ) ;
2017-03-05 16:44:50 +01:00
MethodInfo ( const String & p_name ) ;
MethodInfo ( const String & p_name , const PropertyInfo & p_param1 ) ;
MethodInfo ( const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 ) ;
MethodInfo ( const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 ) ;
MethodInfo ( const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 , const PropertyInfo & p_param4 ) ;
MethodInfo ( const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 , const PropertyInfo & p_param4 , const PropertyInfo & p_param5 ) ;
2014-02-10 02:10:30 +01:00
MethodInfo ( Variant : : Type ret ) ;
2017-03-05 16:44:50 +01:00
MethodInfo ( Variant : : Type ret , const String & p_name ) ;
MethodInfo ( Variant : : Type ret , const String & p_name , const PropertyInfo & p_param1 ) ;
MethodInfo ( Variant : : Type ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 ) ;
MethodInfo ( Variant : : Type ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 ) ;
MethodInfo ( Variant : : Type ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 , const PropertyInfo & p_param4 ) ;
MethodInfo ( Variant : : Type ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 , const PropertyInfo & p_param4 , const PropertyInfo & p_param5 ) ;
2017-08-29 07:15:46 +02:00
MethodInfo ( const PropertyInfo & p_ret , const String & p_name ) ;
MethodInfo ( const PropertyInfo & p_ret , const String & p_name , const PropertyInfo & p_param1 ) ;
MethodInfo ( const PropertyInfo & p_ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 ) ;
MethodInfo ( const PropertyInfo & p_ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 ) ;
MethodInfo ( const PropertyInfo & p_ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 , const PropertyInfo & p_param4 ) ;
MethodInfo ( const PropertyInfo & p_ret , const String & p_name , const PropertyInfo & p_param1 , const PropertyInfo & p_param2 , const PropertyInfo & p_param3 , const PropertyInfo & p_param4 , const PropertyInfo & p_param5 ) ;
2014-02-10 02:10:30 +01:00
} ;
// old cast_to
2017-01-03 03:03:46 +01:00
//if ( is_type(T::get_class_static()) )
2014-02-10 02:10:30 +01:00
//return static_cast<T*>(this);
////else
2020-04-02 01:20:12 +02:00
//return nullptr;
2014-02-10 02:10:30 +01:00
/*
2017-09-22 05:58:29 +02:00
the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies 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 ; \
friend class ClassDB ; \
\
public : \
virtual String get_class ( ) const override { \
return String ( # m_class ) ; \
} \
virtual const StringName * _get_class_namev ( ) const override { \
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 ) ) ; \
} \
static String get_category_static ( ) { \
String category = m_inherits : : get_category_static ( ) ; \
if ( _get_category ! = m_inherits : : _get_category ) { \
if ( category ! = " " ) { \
category + = " / " ; \
} \
category + = _get_category ( ) ; \
} \
return category ; \
} \
static String inherits_static ( ) { \
return String ( # m_inherits ) ; \
} \
virtual bool is_class ( const String & p_class ) const override { return ( p_class = = ( # m_class ) ) ? true : m_inherits : : is_class ( p_class ) ; } \
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 ( ) ; \
ClassDB : : _add_class < m_class > ( ) ; \
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 { \
return ( bool ( Object : : * ) ( const StringName & , Variant & ) const ) & m_class : : _get ; \
} \
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 ) { \
return ( bool ( Object : : * ) ( const StringName & , const Variant & ) ) & m_class : : _set ; \
} \
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 { \
return ( void ( Object : : * ) ( List < PropertyInfo > * ) const ) & m_class : : _get_property_list ; \
} \
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 ( ) ) { \
ClassDB : : get_property_list ( # m_class , p_list , true , this ) ; \
} \
if ( m_class : : _get_get_property_list ( ) ! = m_inherits : : _get_get_property_list ( ) ) { \
_get_property_list ( p_list ) ; \
} \
if ( _is_gpl_reversed ( ) ) { \
ClassDB : : get_property_list ( # m_class , p_list , true , this ) ; \
} \
if ( p_reversed ) { \
m_inherits : : _get_property_listv ( p_list , p_reversed ) ; \
} \
} \
_FORCE_INLINE_ void ( Object : : * _get_notification ( ) const ) ( int ) { \
return ( void ( Object : : * ) ( int ) ) & m_class : : _notification ; \
} \
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 :
2017-03-05 16:44:50 +01:00
# define OBJ_CATEGORY(m_category) \
protected : \
_FORCE_INLINE_ static String _get_category ( ) { return m_category ; } \
\
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 :
2017-07-16 17:39:23 +02:00
enum {
MAX_SCRIPT_INSTANCE_BINDINGS = 8
} ;
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
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 ;
2017-03-05 16:44:50 +01:00
Set < Object * > change_receptors ;
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 ;
2017-06-25 22:30:28 +02:00
Set < 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 ;
2020-02-13 20:03:10 +01:00
Variant script ; //reference does not yet exist, store it in a
2014-02-10 02:10:30 +01:00
Dictionary metadata ;
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 ;
2020-02-19 20:27:19 +01:00
Variant _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 ;
2017-03-05 16:44:50 +01:00
Array _get_signal_connection_list ( const String & p_signal ) const ;
2017-06-15 15:31:57 +02:00
Array _get_incoming_connections ( ) const ;
2017-03-05 16:44:50 +01:00
void _set_bind ( const String & p_set , const Variant & p_value ) ;
Variant _get_bind ( const String & 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
void property_list_changed_notify ( ) ;
2020-02-13 20:03:10 +01:00
_FORCE_INLINE_ void _construct_object ( bool p_reference ) ;
2018-02-22 15:34:08 +01:00
friend class Reference ;
2020-02-13 20:03:10 +01:00
bool type_is_reference = false ;
2020-05-12 17:01:17 +02:00
uint32_t instance_binding_count = 0 ;
2018-02-22 15:34:08 +01:00
void * _script_instance_bindings [ MAX_SCRIPT_INSTANCE_BINDINGS ] ;
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 :
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 String _get_category ( ) { return " " ; }
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
2014-02-10 02:10:30 +01:00
void cancel_delete ( ) ;
2017-03-05 16:44:50 +01:00
virtual void _changed_callback ( Object * p_changed , const char * p_prop ) ;
2014-02-10 02:10:30 +01:00
//Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
//void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
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
2020-02-17 22:06:54 +01:00
Vector < String > _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
2014-02-10 02:10:30 +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 :
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void _change_notify ( const char * p_property = " " ) {
_edited = true ;
2020-05-14 16:41:43 +02:00
for ( Set < Object * > : : Element * E = change_receptors . front ( ) ; E ; E = E - > next ( ) ) {
2017-03-05 16:44:50 +01:00
( ( Object * ) ( E - > get ( ) ) ) - > _changed_callback ( this , p_property ) ;
2020-05-14 16:41:43 +02:00
}
2017-03-05 16:44:50 +01:00
}
2014-02-10 02:10:30 +01:00
# else
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void _change_notify ( const char * p_what = " " ) { }
2014-02-10 02:10:30 +01:00
# endif
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 ; }
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
2020-05-12 17:01:17 +02:00
// this is used for editors
2017-03-05 16:44:50 +01:00
void add_change_receptor ( Object * p_receptor ) ;
void remove_change_receptor ( Object * p_receptor ) ;
2015-08-30 02:09:11 +02: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
static String get_category_static ( ) { return String ( ) ; }
2017-01-03 03:03:46 +01:00
virtual String get_class ( ) const { return " Object " ; }
virtual String get_save_class ( ) const { return get_class ( ) ; } //class stored when saving
2015-06-29 05:29:49 +02:00
2017-03-05 16:44:50 +01:00
virtual bool is_class ( const String & p_class ) const { return ( p_class = = " Object " ) ; }
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 {
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 */
2017-01-14 12:26:56 +01:00
//void set(const String& p_name, const Variant& p_value);
//Variant get(const String& p_name) const;
2014-02-10 02:10:30 +01:00
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 ) ;
2020-02-19 20:27:19 +01:00
virtual Variant call ( const StringName & p_method , const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2017-03-05 16:44:50 +01:00
Variant call ( const StringName & p_name , VARIANT_ARG_LIST ) ; // C++ helper
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
//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
/* SCRIPT */
2017-03-05 16:44:50 +01:00
bool has_meta ( const String & p_name ) const ;
void set_meta ( const String & p_name , const Variant & p_value ) ;
2019-04-26 19:23:50 +02:00
void remove_meta ( const String & p_name ) ;
2017-03-05 16:44:50 +01:00
Variant get_meta ( const String & p_name ) const ;
2014-02-10 02:10:30 +01:00
void get_meta_list ( List < String > * p_list ) const ;
# ifdef TOOLS_ENABLED
void set_edited ( bool p_edited ) ;
bool is_edited ( ) const ;
2016-05-27 19:18:40 +02:00
uint32_t get_edited_version ( ) const ; //this function is used to check when something changed beyond a point, it's used mainly for generating previews
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
2020-02-13 20:03:10 +01:00
void set_script_and_instance ( const Variant & p_script , ScriptInstance * p_instance ) ; //some script languages can't control instance creation, so this function eases the process
2017-07-22 21:57:56 +02:00
2017-03-05 16:44:50 +01:00
void add_user_signal ( const MethodInfo & p_signal ) ;
2017-08-06 00:48:29 +02:00
Error emit_signal ( const StringName & p_name , VARIANT_ARG_LIST ) ;
Error emit_signal ( 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_compat ( const StringName & p_signal , Object * p_to_object , const StringName & p_to_method , const Vector < Variant > & p_binds = Vector < Variant > ( ) , uint32_t p_flags = 0 ) ;
void disconnect_compat ( const StringName & p_signal , Object * p_to_object , const StringName & p_to_method ) ;
bool is_connected_compat ( const StringName & p_signal , Object * p_to_object , const StringName & p_to_method ) const ;
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
2017-03-05 16:44:50 +01:00
void call_deferred ( const StringName & p_method , VARIANT_ARG_LIST ) ;
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
2020-08-07 13:17:12 +02:00
String tr ( const StringName & p_message , const StringName & p_context = " " ) const ; // translate message (internationalization)
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
2020-05-12 17:01:17 +02: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 ) ;
2018-10-29 20:36:31 +01:00
const Set < String > & editor_get_section_folding ( ) const { return editor_section_folding ; }
void editor_clear_section_folding ( ) { editor_section_folding . clear ( ) ; }
2017-06-25 22:30:28 +02:00
# endif
2017-07-16 17:39:23 +02:00
//used by script languages to store binding data
void * get_script_instance_binding ( int p_script_language_index ) ;
2019-02-03 06:35:22 +01:00
bool has_script_instance_binding ( int p_script_language_index ) ;
2019-02-04 20:39:02 +01:00
void set_script_instance_binding ( int p_script_language_index , void * p_data ) ;
2017-07-16 17:39:23 +02:00
2015-06-22 05:03:19 +02:00
void clear_internal_resource_paths ( ) ;
2020-02-13 20:03:10 +01:00
_ALWAYS_INLINE_ bool is_reference ( ) 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 {
2020-02-13 20:03:10 +01:00
//this needs to add up to 63, 1 bit is for reference
# 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))
struct ObjectSlot { //128 bits per slot
uint64_t validator : OBJECTDB_VALIDATOR_BITS ;
uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS ;
uint64_t is_reference : 1 ;
Object * object ;
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 ;
ERR_FAIL_COND_V ( slot > = slot_max , nullptr ) ; //this should never happen unless RID is corrupted
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