summaryrefslogtreecommitdiff
path: root/core/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/object.cpp')
-rw-r--r--core/object.cpp204
1 files changed, 121 insertions, 83 deletions
diff --git a/core/object.cpp b/core/object.cpp
index 8cd4e07097..8af088122e 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -341,15 +341,15 @@ bool Object::_predelete() {
_predelete_ok=1;
notification(NOTIFICATION_PREDELETE,true);
if (_predelete_ok) {
- _type_ptr=NULL; //must restore so destructors can access type ptr correctly
+ _class_ptr=NULL; //must restore so destructors can access class ptr correctly
}
return _predelete_ok;
}
void Object::_postinitialize() {
- _type_ptr=_get_type_namev();
- _initialize_typev();
+ _class_ptr=_get_class_namev();
+ _initialize_classv();
notification(NOTIFICATION_POSTINITIALIZE);
}
@@ -369,11 +369,13 @@ void Object::set(const String& p_name, const Variant& p_value) {
_setv(p_name,p_value);
- //if (!_use_builtin_script())
-// return;
+ /*
+ if (!_use_builtin_script())
+ return;
+ */
bool success;
- ObjectTypeDB::set_property(this,p_name,p_value,success);
+ ClassDB::set_property(this,p_name,p_value,success);
if (success) {
return;
}
@@ -409,9 +411,11 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
//try built-in setgetter
{
- if (ObjectTypeDB::set_property(this,p_name,p_value,r_valid)) {
- //if (r_valid)
- // *r_valid=true;
+ if (ClassDB::set_property(this,p_name,p_value,r_valid)) {
+ /*
+ if (r_valid)
+ *r_valid=true;
+ */
return;
}
}
@@ -460,7 +464,7 @@ Variant Object::get(const StringName& p_name, bool *r_valid) const{
//try built-in setgetter
{
- if (ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret)) {
+ if (ClassDB::get_property(const_cast<Object*>(this),p_name,ret)) {
if (r_valid)
*r_valid=true;
return ret;
@@ -504,7 +508,7 @@ Variant Object::get(const String& p_name) const {
return ret;
bool success;
- ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
+ ClassDB::get_property(const_cast<Object*>(this),p_name,ret,success);
if (success) {
return ret;
}
@@ -532,10 +536,8 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
_get_property_listv(p_list,p_reversed);
- if (!_use_builtin_script())
- return;
- if (!is_type("Script")) // can still be set, but this is for userfriendlyness
+ if (!is_class("Script")) // can still be set, but this is for userfriendlyness
p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
if (!metadata.empty())
p_list->push_back( PropertyInfo( Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_STORE_IF_NONZERO));
@@ -552,7 +554,7 @@ void Object::_validate_property(PropertyInfo& property) const {
void Object::get_method_list(List<MethodInfo> *p_list) const {
- ObjectTypeDB::get_method_list(get_type_name(),p_list);
+ ClassDB::get_method_list(get_class_name(),p_list);
if (script_instance) {
script_instance->get_method_list(p_list);
}
@@ -697,7 +699,7 @@ void Object::call_multilevel(const StringName& p_method,const Variant** p_args,i
}
- MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_method);
+ MethodBind *method=ClassDB::get_method(get_class_name(),p_method);
if (method) {
@@ -710,7 +712,7 @@ void Object::call_multilevel(const StringName& p_method,const Variant** p_args,i
void Object::call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount) {
- MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_method);
+ MethodBind *method=ClassDB::get_method(get_class_name(),p_method);
Variant::CallError error;
OBJ_DEBUG_LOCK
@@ -744,7 +746,7 @@ bool Object::has_method(const StringName& p_method) const {
return true;
}
- MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_method);
+ MethodBind *method=ClassDB::get_method(get_class_name(),p_method);
if (method) {
return true;
@@ -821,7 +823,7 @@ Variant Object::call(const StringName& p_name, VARIANT_ARG_DECLARE) {
return ret;
}
- MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_name);
+ MethodBind *method=ClassDB::get_method(get_type_name(),p_name);
if (method) {
@@ -888,7 +890,7 @@ void Object::call_multilevel(const StringName& p_name, VARIANT_ARG_DECLARE) {
}
- MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_name);
+ MethodBind *method=ClassDB::get_method(get_type_name(),p_name);
if (method) {
@@ -971,7 +973,7 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
}
}
- MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_method);
+ MethodBind *method=ClassDB::get_method(get_class_name(),p_method);
if (method) {
@@ -1112,9 +1114,9 @@ Array Object::_get_method_list_bind() const {
}
-DVector<String> Object::_get_meta_list_bind() const {
+PoolVector<String> Object::_get_meta_list_bind() const {
- DVector<String> _metaret;
+ PoolVector<String> _metaret;
List<Variant> keys;
metadata.get_key_list(&keys);
@@ -1138,7 +1140,7 @@ void Object::get_meta_list(List<String> *p_list) const {
void Object::add_user_signal(const MethodInfo& p_signal) {
ERR_FAIL_COND(p_signal.name=="");
- ERR_FAIL_COND( ObjectTypeDB::has_signal(get_type_name(),p_signal.name ) );
+ ERR_FAIL_COND( ClassDB::has_signal(get_class_name(),p_signal.name ) );
ERR_FAIL_COND(signal_map.has(p_signal.name));
Signal s;
s.user=p_signal;
@@ -1215,6 +1217,15 @@ void Object::emit_signal(const StringName& p_name,const Variant** p_args,int p_a
Signal *s = signal_map.getptr(p_name);
if (!s) {
+#ifdef DEBUG_ENABLED
+ bool signal_is_valid = ClassDB::has_signal(get_class_name(),p_name);
+ //check in script
+ if (!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name)) {
+ ERR_EXPLAIN("Can't emit non-existing signal " + String("\"")+p_name+"\".");
+ ERR_FAIL();
+ }
+#endif
+ //not connected? just return
return;
}
@@ -1272,7 +1283,7 @@ void Object::emit_signal(const StringName& p_name,const Variant** p_args,int p_a
target->call( c.method, args, argc,ce );
if (ce.error!=Variant::CallError::CALL_OK) {
- if (ce.error==Variant::CallError::CALL_ERROR_INVALID_METHOD && !ObjectTypeDB::type_exists( target->get_type_name() ) ) {
+ if (ce.error==Variant::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists( target->get_class_name() ) ) {
//most likely object is not initialized yet, do not throw error.
} else {
ERR_PRINTS("Error calling method from signal '"+String(p_name)+"': "+Variant::get_call_error_text(target,c.method,args,argc,ce));
@@ -1406,7 +1417,7 @@ void Object::get_signal_list(List<MethodInfo> *p_signals ) const {
Ref<Script>(script)->get_script_signal_list(p_signals);
}
- ObjectTypeDB::get_signal_list(get_type_name(),p_signals);
+ ClassDB::get_signal_list(get_class_name(),p_signals);
//find maybe usersignals?
const StringName *S=NULL;
@@ -1480,13 +1491,13 @@ Error Object::connect(const StringName& p_signal, Object *p_to_object, const Str
Signal *s = signal_map.getptr(p_signal);
if (!s) {
- bool signal_is_valid = ObjectTypeDB::has_signal(get_type_name(),p_signal);
+ bool signal_is_valid = ClassDB::has_signal(get_class_name(),p_signal);
//check in script
if (!signal_is_valid && !script.is_null() && Ref<Script>(script)->has_script_signal(p_signal))
signal_is_valid=true;
if (!signal_is_valid) {
- ERR_EXPLAIN("In Object of type '"+String(get_type())+"': Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_object->get_type()+"."+p_to_method+"'");
+ ERR_EXPLAIN("In Object of type '"+String(get_class())+"': Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_object->get_class()+"."+p_to_method+"'");
ERR_FAIL_COND_V(!signal_is_valid,ERR_INVALID_PARAMETER);
}
signal_map[p_signal]=Signal();
@@ -1520,7 +1531,7 @@ bool Object::is_connected(const StringName& p_signal, Object *p_to_object, const
ERR_FAIL_NULL_V(p_to_object,false);
const Signal *s = signal_map.getptr(p_signal);
if (!s) {
- bool signal_is_valid = ObjectTypeDB::has_signal(get_type_name(),p_signal);
+ bool signal_is_valid = ClassDB::has_signal(get_class_name(),p_signal);
if (signal_is_valid)
return false;
@@ -1562,7 +1573,7 @@ void Object::disconnect(const StringName& p_signal, Object *p_to_object, const S
p_to_object->connections.erase(s->slot_map[target].cE);
s->slot_map.erase(target);
- if (s->slot_map.empty() && ObjectTypeDB::has_signal(get_type_name(),p_signal )) {
+ if (s->slot_map.empty() && ClassDB::has_signal(get_class_name(),p_signal )) {
//not user signal, delete
signal_map.erase(p_signal);
}
@@ -1579,12 +1590,12 @@ Variant Object::_get_bind(const String& p_name) const {
return get(p_name);
}
-void Object::initialize_type() {
+void Object::initialize_class() {
static bool initialized=false;
if (initialized)
return;
- ObjectTypeDB::_add_type<Object>();
+ ClassDB::_add_class<Object>();
_bind_methods();
initialized=true;
}
@@ -1663,31 +1674,31 @@ void Object::clear_internal_resource_paths() {
void Object::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("get_type"),&Object::get_type);
- ObjectTypeDB::bind_method(_MD("is_type","type"),&Object::is_type);
- ObjectTypeDB::bind_method(_MD("set","property","value"),&Object::_set_bind);
- ObjectTypeDB::bind_method(_MD("get","property"),&Object::_get_bind);
- ObjectTypeDB::bind_method(_MD("get_property_list"),&Object::_get_property_list_bind);
- ObjectTypeDB::bind_method(_MD("get_method_list"),&Object::_get_method_list_bind);
- ObjectTypeDB::bind_method(_MD("notification","what","reversed"),&Object::notification,DEFVAL(false));
- ObjectTypeDB::bind_method(_MD("get_instance_ID"),&Object::get_instance_ID);
+ ClassDB::bind_method(_MD("get_class"),&Object::get_class);
+ ClassDB::bind_method(_MD("is_class","type"),&Object::is_class);
+ ClassDB::bind_method(_MD("set","property","value"),&Object::_set_bind);
+ ClassDB::bind_method(_MD("get","property"),&Object::_get_bind);
+ ClassDB::bind_method(_MD("get_property_list"),&Object::_get_property_list_bind);
+ ClassDB::bind_method(_MD("get_method_list"),&Object::_get_method_list_bind);
+ ClassDB::bind_method(_MD("notification","what","reversed"),&Object::notification,DEFVAL(false));
+ ClassDB::bind_method(_MD("get_instance_ID"),&Object::get_instance_ID);
- ObjectTypeDB::bind_method(_MD("set_script","script:Script"),&Object::set_script);
- ObjectTypeDB::bind_method(_MD("get_script:Script"),&Object::get_script);
+ ClassDB::bind_method(_MD("set_script","script:Script"),&Object::set_script);
+ ClassDB::bind_method(_MD("get_script:Script"),&Object::get_script);
- ObjectTypeDB::bind_method(_MD("set_meta","name","value"),&Object::set_meta);
- ObjectTypeDB::bind_method(_MD("get_meta","name","value"),&Object::get_meta);
- ObjectTypeDB::bind_method(_MD("has_meta","name"),&Object::has_meta);
- ObjectTypeDB::bind_method(_MD("get_meta_list"),&Object::_get_meta_list_bind);
+ ClassDB::bind_method(_MD("set_meta","name","value"),&Object::set_meta);
+ ClassDB::bind_method(_MD("get_meta","name","value"),&Object::get_meta);
+ ClassDB::bind_method(_MD("has_meta","name"),&Object::has_meta);
+ ClassDB::bind_method(_MD("get_meta_list"),&Object::_get_meta_list_bind);
//todo reimplement this per language so all 5 arguments can be called
-// ObjectTypeDB::bind_method(_MD("call","method","arg1","arg2","arg3","arg4"),&Object::_call_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()));
-// ObjectTypeDB::bind_method(_MD("call_deferred","method","arg1","arg2","arg3","arg4"),&Object::_call_deferred_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()));
+ //ClassDB::bind_method(_MD("call","method","arg1","arg2","arg3","arg4"),&Object::_call_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()));
+ //ClassDB::bind_method(_MD("call_deferred","method","arg1","arg2","arg3","arg4"),&Object::_call_deferred_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()));
- ObjectTypeDB::bind_method(_MD("add_user_signal","signal","arguments"),&Object::_add_user_signal,DEFVAL(Array()));
- ObjectTypeDB::bind_method(_MD("has_user_signal","signal"),&Object::_has_user_signal);
-// ObjectTypeDB::bind_method(_MD("emit_signal","signal","arguments"),&Object::_emit_signal,DEFVAL(Array()));
+ ClassDB::bind_method(_MD("add_user_signal","signal","arguments"),&Object::_add_user_signal,DEFVAL(Array()));
+ ClassDB::bind_method(_MD("has_user_signal","signal"),&Object::_has_user_signal);
+ //ClassDB::bind_method(_MD("emit_signal","signal","arguments"),&Object::_emit_signal,DEFVAL(Array()));
{
@@ -1695,7 +1706,7 @@ void Object::_bind_methods() {
mi.name="emit_signal";
mi.arguments.push_back( PropertyInfo( Variant::STRING, "signal"));
- ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"emit_signal",&Object::_emit_signal,mi);
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"emit_signal",&Object::_emit_signal,mi);
}
{
@@ -1705,7 +1716,7 @@ void Object::_bind_methods() {
- ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call:Variant",&Object::_call_bind,mi);
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call:Variant",&Object::_call_bind,mi);
}
{
@@ -1713,32 +1724,32 @@ void Object::_bind_methods() {
mi.name="call_deferred";
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
- ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call_deferred",&Object::_call_deferred_bind,mi);
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call_deferred",&Object::_call_deferred_bind,mi);
}
- ObjectTypeDB::bind_method(_MD("callv:Variant","method","arg_array"),&Object::callv);
+ ClassDB::bind_method(_MD("callv:Variant","method","arg_array"),&Object::callv);
- ObjectTypeDB::bind_method(_MD("has_method","method"),&Object::has_method);
+ ClassDB::bind_method(_MD("has_method","method"),&Object::has_method);
- ObjectTypeDB::bind_method(_MD("get_signal_list"),&Object::_get_signal_list);
- ObjectTypeDB::bind_method(_MD("get_signal_connection_list","signal"),&Object::_get_signal_connection_list);
+ ClassDB::bind_method(_MD("get_signal_list"),&Object::_get_signal_list);
+ ClassDB::bind_method(_MD("get_signal_connection_list","signal"),&Object::_get_signal_connection_list);
- ObjectTypeDB::bind_method(_MD("connect","signal","target:Object","method","binds","flags"),&Object::connect,DEFVAL(Array()),DEFVAL(0));
- ObjectTypeDB::bind_method(_MD("disconnect","signal","target:Object","method"),&Object::disconnect);
- ObjectTypeDB::bind_method(_MD("is_connected","signal","target:Object","method"),&Object::is_connected);
+ ClassDB::bind_method(_MD("connect","signal","target:Object","method","binds","flags"),&Object::connect,DEFVAL(Array()),DEFVAL(0));
+ ClassDB::bind_method(_MD("disconnect","signal","target:Object","method"),&Object::disconnect);
+ ClassDB::bind_method(_MD("is_connected","signal","target:Object","method"),&Object::is_connected);
- ObjectTypeDB::bind_method(_MD("set_block_signals","enable"),&Object::set_block_signals);
- ObjectTypeDB::bind_method(_MD("is_blocking_signals"),&Object::is_blocking_signals);
- ObjectTypeDB::bind_method(_MD("set_message_translation","enable"),&Object::set_message_translation);
- ObjectTypeDB::bind_method(_MD("can_translate_messages"),&Object::can_translate_messages);
- ObjectTypeDB::bind_method(_MD("property_list_changed_notify"),&Object::property_list_changed_notify);
+ ClassDB::bind_method(_MD("set_block_signals","enable"),&Object::set_block_signals);
+ ClassDB::bind_method(_MD("is_blocking_signals"),&Object::is_blocking_signals);
+ ClassDB::bind_method(_MD("set_message_translation","enable"),&Object::set_message_translation);
+ ClassDB::bind_method(_MD("can_translate_messages"),&Object::can_translate_messages);
+ ClassDB::bind_method(_MD("property_list_changed_notify"),&Object::property_list_changed_notify);
- ObjectTypeDB::bind_method(_MD("XL_MESSAGE","message"),&Object::XL_MESSAGE);
- ObjectTypeDB::bind_method(_MD("tr","message"),&Object::tr);
+ ClassDB::bind_method(_MD("XL_MESSAGE","message"),&Object::XL_MESSAGE);
+ ClassDB::bind_method(_MD("tr","message"),&Object::tr);
- ObjectTypeDB::bind_method(_MD("is_queued_for_deletion"),&Object::is_queued_for_deletion);
+ ClassDB::bind_method(_MD("is_queued_for_deletion"),&Object::is_queued_for_deletion);
- ObjectTypeDB::add_virtual_method("Object",MethodInfo("free"),false);
+ ClassDB::add_virtual_method("Object",MethodInfo("free"),false);
ADD_SIGNAL( MethodInfo("script_changed"));
@@ -1806,7 +1817,7 @@ void Object::get_translatable_strings(List<String> *p_strings) const {
Variant::Type Object::get_static_property_type(const StringName& p_property, bool *r_valid) const {
bool valid;
- Variant::Type t = ObjectTypeDB::get_property_type(get_type_name(),p_property,&valid);
+ Variant::Type t = ClassDB::get_property_type(get_class_name(),p_property,&valid);
if (valid) {
if (r_valid)
*r_valid=true;
@@ -1848,7 +1859,7 @@ uint32_t Object::get_edited_version() const {
Object::Object() {
- _type_ptr=NULL;
+ _class_ptr=NULL;
_block_signals=false;
_predelete_ok=0;
_instance_ID=0;
@@ -1933,27 +1944,37 @@ uint32_t ObjectDB::instance_counter=1;
HashMap<Object*,ObjectID,ObjectDB::ObjectPtrHash> ObjectDB::instance_checks;
uint32_t ObjectDB::add_instance(Object *p_object) {
- GLOBAL_LOCK_FUNCTION;
+
ERR_FAIL_COND_V( p_object->get_instance_ID()!=0, 0 );
+
+ rw_lock->write_lock();
instances[++instance_counter]=p_object;
#ifdef DEBUG_ENABLED
instance_checks[p_object]=instance_counter;
#endif
+ rw_lock->write_unlock();
+
return instance_counter;
}
void ObjectDB::remove_instance(Object *p_object) {
- GLOBAL_LOCK_FUNCTION;
+
+ rw_lock->write_lock();
+
instances.erase( p_object->get_instance_ID() );
#ifdef DEBUG_ENABLED
instance_checks.erase(p_object);
#endif
+
+ rw_lock->write_unlock();
}
Object *ObjectDB::get_instance(uint32_t p_instance_ID) {
- GLOBAL_LOCK_FUNCTION;
+ rw_lock->read_lock();
Object**obj=instances.getptr(p_instance_ID);
+ rw_lock->read_unlock();
+
if (!obj)
return NULL;
return *obj;
@@ -1961,13 +1982,16 @@ Object *ObjectDB::get_instance(uint32_t p_instance_ID) {
void ObjectDB::debug_objects(DebugFunc p_func) {
- GLOBAL_LOCK_FUNCTION;
+ rw_lock->read_lock();
const uint32_t *K=NULL;
while((K=instances.next(K))) {
p_func(instances[*K]);
}
+
+ rw_lock->read_unlock();
+
}
@@ -1978,15 +2002,26 @@ void Object::get_argument_options(const StringName& p_function,int p_idx,List<St
int ObjectDB::get_object_count() {
- GLOBAL_LOCK_FUNCTION;
- return instances.size();
+ rw_lock->read_lock();
+ int count =instances.size();
+ rw_lock->read_unlock();
+
+ return count;
}
+RWLock *ObjectDB::rw_lock=NULL;
+
+
+void ObjectDB::setup() {
+
+ rw_lock = RWLock::create();
+}
+
void ObjectDB::cleanup() {
- GLOBAL_LOCK_FUNCTION;
+ rw_lock->write_lock();
if (instances.size()) {
WARN_PRINT("ObjectDB Instances still exist!");
@@ -1995,14 +2030,17 @@ void ObjectDB::cleanup() {
while((K=instances.next(K))) {
String node_name;
- if (instances[*K]->is_type("Node"))
+ if (instances[*K]->is_class("Node"))
node_name=" - Node Name: "+String(instances[*K]->call("get_name"));
- if (instances[*K]->is_type("Resoucre"))
+ if (instances[*K]->is_class("Resoucre"))
node_name=" - Resource Name: "+String(instances[*K]->call("get_name"))+" Path: "+String(instances[*K]->call("get_path"));
- print_line("Leaked Instance: "+String(instances[*K]->get_type())+":"+itos(*K)+node_name);
+ print_line("Leaked Instance: "+String(instances[*K]->get_class())+":"+itos(*K)+node_name);
}
}
}
instances.clear();
instance_checks.clear();
+ rw_lock->write_unlock();
+
+ memdelete(rw_lock);
}