summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/bind/core_bind.cpp75
-rw-r--r--core/bind/core_bind.h14
-rw-r--r--core/func_ref.cpp55
-rw-r--r--core/func_ref.h23
-rw-r--r--core/globals.cpp23
-rw-r--r--core/globals.h4
-rw-r--r--core/io/file_access_pack.cpp1
-rw-r--r--core/io/http_client.cpp8
-rw-r--r--core/io/marshalls.cpp148
-rw-r--r--core/io/resource_format_binary.cpp34
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/resource_format_xml.cpp51
-rw-r--r--core/io/resource_format_xml.h5
-rw-r--r--core/io/resource_loader.cpp13
-rw-r--r--core/io/resource_loader.h1
-rw-r--r--core/io/resource_saver.h3
-rw-r--r--core/math/math_funcs.cpp11
-rw-r--r--core/message_queue.cpp3
-rw-r--r--core/object.cpp54
-rw-r--r--core/object.h8
-rw-r--r--core/os/file_access.cpp24
-rw-r--r--core/os/file_access.h3
-rw-r--r--core/os/input.cpp7
-rw-r--r--core/os/input.h2
-rw-r--r--core/os/mutex.h2
-rw-r--r--core/os/os.cpp25
-rw-r--r--core/os/os.h10
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/ustring.cpp10
-rw-r--r--core/ustring.h3
-rw-r--r--core/variant.cpp2
-rw-r--r--core/variant_call.cpp2
-rw-r--r--core/variant_op.cpp4
33 files changed, 566 insertions, 66 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 73f6f753b9..e3360a23d2 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -199,6 +199,14 @@ int _OS::get_iterations_per_second() const {
}
+void _OS::set_target_fps(int p_fps) {
+ OS::get_singleton()->set_target_fps(p_fps);
+}
+
+float _OS::get_target_fps() const {
+ return OS::get_singleton()->get_target_fps();
+}
+
void _OS::set_low_processor_usage_mode(bool p_enabled) {
OS::get_singleton()->set_low_processor_usage_mode(p_enabled);
@@ -238,6 +246,12 @@ Error _OS::kill(int p_pid) {
return OS::get_singleton()->kill(p_pid);
}
+int _OS::get_process_ID() const {
+
+ return OS::get_singleton()->get_process_ID();
+};
+
+
bool _OS::has_environment(const String& p_var) const {
return OS::get_singleton()->has_environment(p_var);
@@ -387,6 +401,12 @@ uint32_t _OS::get_ticks_msec() const {
return OS::get_singleton()->get_ticks_msec();
}
+
+bool _OS::can_use_threads() const {
+
+ return OS::get_singleton()->can_use_threads();
+}
+
bool _OS::can_draw() const {
return OS::get_singleton()->can_draw();
@@ -488,6 +508,27 @@ float _OS::get_frames_per_second() const {
return OS::get_singleton()->get_frames_per_second();
}
+Error _OS::native_video_play(String p_path) {
+
+ return OS::get_singleton()->native_video_play(p_path);
+};
+
+bool _OS::native_video_is_playing() {
+
+ return OS::get_singleton()->native_video_is_playing();
+};
+
+void _OS::native_video_pause() {
+
+ OS::get_singleton()->native_video_pause();
+};
+
+void _OS::native_video_stop() {
+
+ OS::get_singleton()->native_video_stop();
+};
+
+
String _OS::get_custom_level() const {
return OS::get_singleton()->get_custom_level();
@@ -496,7 +537,7 @@ _OS *_OS::singleton=NULL;
void _OS::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("get_mouse_pos"),&_OS::get_mouse_pos);
+ //ObjectTypeDB::bind_method(_MD("get_mouse_pos"),&_OS::get_mouse_pos);
//ObjectTypeDB::bind_method(_MD("is_mouse_grab_enabled"),&_OS::is_mouse_grab_enabled);
ObjectTypeDB::bind_method(_MD("set_clipboard","clipboard"),&_OS::set_clipboard);
@@ -510,6 +551,8 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second);
ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second);
+ ObjectTypeDB::bind_method(_MD("set_target_fps","target_fps"),&_OS::set_target_fps);
+ ObjectTypeDB::bind_method(_MD("get_target_fps"),&_OS::get_target_fps);
ObjectTypeDB::bind_method(_MD("has_touchscreen_ui_hint"),&_OS::has_touchscreen_ui_hint);
@@ -524,6 +567,7 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("execute","path","arguments","blocking"),&_OS::execute);
ObjectTypeDB::bind_method(_MD("kill","pid"),&_OS::kill);
ObjectTypeDB::bind_method(_MD("shell_open","uri"),&_OS::shell_open);
+ ObjectTypeDB::bind_method(_MD("get_process_ID"),&_OS::get_process_ID);
ObjectTypeDB::bind_method(_MD("get_environment","environment"),&_OS::get_environment);
ObjectTypeDB::bind_method(_MD("has_environment","environment"),&_OS::has_environment);
@@ -550,7 +594,9 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_frames_drawn"),&_OS::get_frames_drawn);
ObjectTypeDB::bind_method(_MD("is_stdout_verbose"),&_OS::is_stdout_verbose);
- ObjectTypeDB::bind_method(_MD("get_mouse_button_state"),&_OS::get_mouse_button_state);
+ ObjectTypeDB::bind_method(_MD("can_use_threads"),&_OS::can_use_threads);
+
+ //ObjectTypeDB::bind_method(_MD("get_mouse_button_state"),&_OS::get_mouse_button_state);
ObjectTypeDB::bind_method(_MD("dump_memory_to_file","file"),&_OS::dump_memory_to_file);
ObjectTypeDB::bind_method(_MD("dump_resources_to_file","file"),&_OS::dump_resources_to_file);
@@ -568,6 +614,12 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("print_all_textures_by_size"),&_OS::print_all_textures_by_size);
+ ObjectTypeDB::bind_method(_MD("native_video_play"),&_OS::native_video_play);
+ ObjectTypeDB::bind_method(_MD("native_video_is_playing"),&_OS::native_video_is_playing);
+ ObjectTypeDB::bind_method(_MD("native_video_stop"),&_OS::native_video_stop);
+ ObjectTypeDB::bind_method(_MD("native_video_pause"),&_OS::native_video_pause);
+
+
BIND_CONSTANT( DAY_SUNDAY );
BIND_CONSTANT( DAY_MONDAY );
BIND_CONSTANT( DAY_TUESDAY );
@@ -983,8 +1035,22 @@ void _File::store_string(const String& p_string){
f->store_string(p_string);
}
-void _File::store_line(const String& p_string){
+void _File::store_pascal_string(const String& p_string) {
+
+ ERR_FAIL_COND(!f);
+
+ f->store_pascal_string(p_string);
+};
+
+String _File::get_pascal_string() {
+
+ ERR_FAIL_COND_V(!f, "");
+
+ return f->get_pascal_string();
+};
+
+void _File::store_line(const String& p_string){
ERR_FAIL_COND(!f);
f->store_line(p_string);
@@ -1083,6 +1149,9 @@ void _File::_bind_methods() {
ObjectTypeDB::bind_method(_MD("store_string","string"),&_File::store_string);
ObjectTypeDB::bind_method(_MD("store_var","value"),&_File::store_var);
+ ObjectTypeDB::bind_method(_MD("store_pascal_string","string"),&_File::store_pascal_string);
+ ObjectTypeDB::bind_method(_MD("get_pascal_string"),&_File::get_pascal_string);
+
ObjectTypeDB::bind_method(_MD("file_exists","path"),&_File::file_exists);
BIND_CONSTANT( READ );
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 9545fc65fb..0084726547 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -98,9 +98,17 @@ public:
bool is_video_mode_resizable(int p_screen=0) const;
Array get_fullscreen_mode_list(int p_screen=0) const;
+ Error native_video_play(String p_path);
+ bool native_video_is_playing();
+ void native_video_pause();
+ void native_video_stop();
+
void set_iterations_per_second(int p_ips);
int get_iterations_per_second() const;
+ void set_target_fps(int p_fps);
+ float get_target_fps() const;
+
void set_low_processor_usage_mode(bool p_enabled);
bool is_in_low_processor_usage_mode() const;
@@ -109,6 +117,8 @@ public:
Error kill(int p_pid);
Error shell_open(String p_uri);
+ int get_process_ID() const;
+
bool has_environment(const String& p_var) const;
String get_environment(const String& p_var) const;
@@ -166,6 +176,7 @@ public:
void delay_msec(uint32_t p_msec) const;
uint32_t get_ticks_msec() const;
+ bool can_use_threads() const;
bool can_draw() const;
@@ -280,6 +291,9 @@ public:
void store_string(const String& p_string);
void store_line(const String& p_string);
+ virtual void store_pascal_string(const String& p_string);
+ virtual String get_pascal_string();
+
Vector<String> get_csv_line() const;
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
new file mode 100644
index 0000000000..0e43112de8
--- /dev/null
+++ b/core/func_ref.cpp
@@ -0,0 +1,55 @@
+#include "func_ref.h"
+
+Variant FuncRef::call_func(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
+
+ if (id==0) {
+ r_error.error=Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return Variant();
+ }
+ Object* obj = ObjectDB::get_instance(id);
+
+ if (!obj) {
+ r_error.error=Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return Variant();
+ }
+
+ return obj->call(function,p_args,p_argcount,r_error);
+
+}
+
+void FuncRef::set_instance(Object *p_obj){
+
+ ERR_FAIL_NULL(p_obj);
+ id=p_obj->get_instance_ID();
+}
+void FuncRef::set_function(const StringName& p_func){
+
+ function=p_func;
+}
+
+void FuncRef::_bind_methods() {
+
+ {
+ MethodInfo mi;
+ mi.name="call";
+ mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
+ Vector<Variant> defargs;
+ for(int i=0;i<10;i++) {
+ mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
+ defargs.push_back(Variant());
+ }
+ ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func",&FuncRef::call_func,mi,defargs);
+
+ }
+
+ ObjectTypeDB::bind_method(_MD("set_instance","instance"),&FuncRef::set_instance);
+ ObjectTypeDB::bind_method(_MD("set_function","name"),&FuncRef::set_function);
+
+}
+
+
+FuncRef::FuncRef(){
+
+ id=0;
+}
+
diff --git a/core/func_ref.h b/core/func_ref.h
new file mode 100644
index 0000000000..28d0e737be
--- /dev/null
+++ b/core/func_ref.h
@@ -0,0 +1,23 @@
+#ifndef FUNC_REF_H
+#define FUNC_REF_H
+
+#include "reference.h"
+
+class FuncRef : public Reference{
+
+ OBJ_TYPE(FuncRef,Reference);
+ ObjectID id;
+ StringName function;
+
+protected:
+
+ static void _bind_methods();
+public:
+
+ Variant call_func(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
+ void set_instance(Object *p_obj);
+ void set_function(const StringName& p_func);
+ FuncRef();
+};
+
+#endif // FUNC_REF_H
diff --git a/core/globals.cpp b/core/globals.cpp
index 997e2a2d85..7df7680827 100644
--- a/core/globals.cpp
+++ b/core/globals.cpp
@@ -166,10 +166,9 @@ bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
_THREAD_SAFE_METHOD_
- const VariantContainer *v=props.getptr(p_name);
- if (!v)
+ if (!props.has(p_name))
return false;
- r_ret=v->variant;
+ r_ret=props[p_name].variant;
return true;
}
@@ -188,18 +187,17 @@ void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
_THREAD_SAFE_METHOD_
- const String *k=NULL;
Set<_VCSort> vclist;
- while ((k=props.next(k))) {
+ for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
- const VariantContainer *v=props.getptr(*k);
+ const VariantContainer *v=&E->get();
if (v->hide_from_editor)
continue;
_VCSort vc;
- vc.name=*k;
+ vc.name=E->key();
vc.order=v->order;
vc.type=v->variant.get_type();
if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload"))
@@ -1138,24 +1136,23 @@ Error Globals::save_custom(const String& p_path,const CustomMap& p_custom,const
ERR_FAIL_COND_V(p_path=="",ERR_INVALID_PARAMETER);
- const String *k=NULL;
Set<_VCSort> vclist;
- while ((k=props.next(k))) {
+ for(Map<StringName,VariantContainer>::Element *G=props.front();G;G=G->next()) {
- const VariantContainer *v=props.getptr(*k);
+ const VariantContainer *v=&G->get();
if (v->hide_from_editor)
continue;
- if (p_custom.has(*k))
+ if (p_custom.has(G->key()))
continue;
bool discard=false;
for(const Set<String>::Element *E=p_ignore_masks.front();E;E=E->next()) {
- if ( (*k).match(E->get())) {
+ if ( String(G->key()).match(E->get())) {
discard=true;
break;
}
@@ -1165,7 +1162,7 @@ Error Globals::save_custom(const String& p_path,const CustomMap& p_custom,const
continue;
_VCSort vc;
- vc.name=*k;
+ vc.name=G->key();//*k;
vc.order=v->order;
vc.type=v->variant.get_type();
vc.flags=PROPERTY_USAGE_CHECKABLE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_STORAGE;
diff --git a/core/globals.h b/core/globals.h
index 08d9f08088..b8dc3f9367 100644
--- a/core/globals.h
+++ b/core/globals.h
@@ -65,9 +65,9 @@ protected:
};
int last_order;
- HashMap<String,VariantContainer> props;
+ Map<StringName,VariantContainer> props;
String resource_path;
- HashMap<String,PropertyInfo> custom_prop_info;
+ Map<StringName,PropertyInfo> custom_prop_info;
bool disable_platform_override;
bool using_datapack;
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index edecbb6a3e..45e6990ad2 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -172,7 +172,6 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5,16);
-
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5,this);
};
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 1b53ee6104..f9da846844 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -97,8 +97,16 @@ Error HTTPClient::request( Method p_method, const String& p_url, const Vector<St
String request=String(_methods[p_method])+" "+p_url+" HTTP/1.1\r\n";
request+="Host: "+conn_host+":"+itos(conn_port)+"\r\n";
+ bool add_clen=p_body.length()>0;
for(int i=0;i<p_headers.size();i++) {
request+=p_headers[i]+"\r\n";
+ if (add_clen && p_headers[i].find("Content-Length:")==0) {
+ add_clen=false;
+ }
+ }
+ if (add_clen) {
+ request+="Content-Length: "+itos(p_body.utf8().length())+"\r\n";
+ //should it add utf8 encoding? not sure
}
request+="\r\n";
request+=p_body;
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index f5f9d34439..df951c759a 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -264,26 +264,94 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
}
r_variant=img;
- if (r_len)
+ if (r_len) {
+ if (datalen%4)
+ (*r_len)+=4-datalen%4;
+
(*r_len)+=4*5+datalen;
+ }
} break;
case Variant::NODE_PATH: {
- ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
uint32_t strlen = decode_uint32(buf);
- buf+=4;
- len-=4;
- ERR_FAIL_COND_V((int)strlen>len,ERR_INVALID_DATA);
+ if (strlen&0x80000000) {
+ //new format
+ ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA);
+ Vector<StringName> names;
+ Vector<StringName> subnames;
+ bool absolute;
+ StringName prop;
- String str;
- str.parse_utf8((const char*)buf,strlen);
+ int i=0;
+ uint32_t namecount=strlen&=0x7FFFFFFF;
+ uint32_t subnamecount = decode_uint32(buf+4);
+ uint32_t flags = decode_uint32(buf+8);
- r_variant=NodePath(str);
+ len-=12;
+ buf+=12;
- if (r_len)
- (*r_len)+=4+strlen;
+ int total=namecount+subnamecount;
+ if (flags&2)
+ total++;
+
+ if (r_len)
+ (*r_len)+=12;
+
+
+ for(int i=0;i<total;i++) {
+
+ ERR_FAIL_COND_V((int)len<4,ERR_INVALID_DATA);
+ strlen = decode_uint32(buf);
+
+ int pad=0;
+
+ if (strlen%4)
+ pad+=4-strlen%4;
+
+ buf+=4;
+ len-=4;
+ ERR_FAIL_COND_V((int)strlen+pad>len,ERR_INVALID_DATA);
+
+ String str;
+ str.parse_utf8((const char*)buf,strlen);
+
+
+ if (i<namecount)
+ names.push_back(str);
+ else if (i<namecount+subnamecount)
+ subnames.push_back(str);
+ else
+ prop=str;
+
+ buf+=strlen+pad;
+ len-=strlen+pad;
+
+ if (r_len)
+ (*r_len)+=4+strlen+pad;
+
+ }
+
+ r_variant=NodePath(names,subnames,flags&1,prop);
+
+ } else {
+ //old format, just a string
+
+ buf+=4;
+ len-=4;
+ ERR_FAIL_COND_V((int)strlen>len,ERR_INVALID_DATA);
+
+
+ String str;
+ str.parse_utf8((const char*)buf,strlen);
+
+ r_variant=NodePath(str);
+
+ if (r_len)
+ (*r_len)+=4+strlen;
+ }
} break;
/*case Variant::RESOURCE: {
@@ -713,7 +781,59 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
r_len+=4;
} break;
- case Variant::NODE_PATH:
+ case Variant::NODE_PATH: {
+
+ NodePath np=p_variant;
+ if (buf) {
+ encode_uint32(uint32_t(np.get_name_count())|0x80000000,buf); //for compatibility with the old format
+ encode_uint32(np.get_subname_count(),buf+4);
+ uint32_t flags=0;
+ if (np.is_absolute())
+ flags|=1;
+ if (np.get_property()!=StringName())
+ flags|=2;
+
+ encode_uint32(flags,buf+8);
+
+ buf+=12;
+ }
+
+ r_len+=12;
+
+ int total = np.get_name_count()+np.get_subname_count();
+ if (np.get_property()!=StringName())
+ total++;
+
+ for(int i=0;i<total;i++) {
+
+ String str;
+
+ if (i<np.get_name_count())
+ str=np.get_name(i);
+ else if (i<np.get_name_count()+np.get_subname_count())
+ str=np.get_subname(i-np.get_subname_count());
+ else
+ str=np.get_property();
+
+ CharString utf8 = str.utf8();
+
+ int pad = 0;
+
+ if (utf8.length()%4)
+ pad=4-utf8.length()%4;
+
+ if (buf) {
+ encode_uint32(utf8.length(),buf);
+ buf+=4;
+ copymem(buf,utf8.get_data(),utf8.length());
+ buf+=pad+utf8.length();
+ }
+
+
+ r_len+=4+utf8.length()+pad;
+ }
+
+ } break;
case Variant::STRING: {
@@ -879,7 +999,11 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
copymem(&buf[20],&r[0],ds);
}
- r_len+=data.size()+5*4;
+ int pad=0;
+ if (data.size()%4)
+ pad=4-data.size()%4;
+
+ r_len+=data.size()+5*4+pad;
} break;
/*case Variant::RESOURCE: {
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index c54398935e..33f4cafedd 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -647,7 +647,7 @@ Error ResourceInteractiveLoaderBinary::poll(){
}
stage++;
- return OK;
+ return error;
}
s-=external_resources.size();
@@ -804,7 +804,12 @@ void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<Stri
for(int i=0;i<external_resources.size();i++) {
- p_dependencies->push_back(external_resources[i].path);
+ String dep=external_resources[i].path;
+ if (dep.ends_with("*")) {
+ dep=ResourceLoader::guess_full_filename(dep,external_resources[i].type);
+ }
+
+ p_dependencies->push_back(dep);
}
}
@@ -892,6 +897,19 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
}
+ //see if the exporter has different set of external resources for more efficient loading
+ String preload_depts = "deps/"+res_path.md5_text();
+ if (Globals::get_singleton()->has(preload_depts)) {
+ external_resources.clear();
+ //ignore external resources and use these
+ NodePath depts=Globals::get_singleton()->get(preload_depts);
+ external_resources.resize(depts.get_name_count());
+ for(int i=0;i<depts.get_name_count();i++) {
+ external_resources[i].path=depts.get_name(i);
+ }
+ print_line(res_path+" - EXTERNAL RESOURCES: "+itos(external_resources.size()));
+ }
+
print_bl("ext resources: "+itos(ext_resources_size));
uint32_t int_resources_size=f->get_32();
@@ -931,6 +949,7 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
} else if (header[0]!='R' || header[1]!='S' || header[2]!='R' || header[3]!='C') {
//not normal
+ error=ERR_FILE_UNRECOGNIZED;
return "";
}
@@ -1412,8 +1431,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
f->store_32(OBJECT_EXTERNAL_RESOURCE);
save_unicode_string(res->get_save_type());
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
- if (no_extensions)
- path=path.basename()+".*";
save_unicode_string(path);
} else {
@@ -1439,7 +1456,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
f->store_32(VARIANT_DICTIONARY);
Dictionary d = p_property;
- f->store_32(uint32_t(d.size())|(d.is_shared()?0x80000000:0));
+ f->store_32(uint32_t(d.size())|(d.is_shared()?0x80000000:0));
List<Variant> keys;
d.get_key_list(&keys);
@@ -1734,7 +1751,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES;
bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES;
big_endian=p_flags&ResourceSaver::FLAG_SAVE_BIG_ENDIAN;
- no_extensions=p_flags&ResourceSaver::FLAG_NO_EXTENSION;
+
local_path=p_path.get_base_dir();
//bin_meta_idx = get_string_index("__bin_meta__"); //is often used, so create
@@ -1816,8 +1833,6 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
save_unicode_string(E->get()->get_save_type());
String path = E->get()->get_path();
- if (no_extensions)
- path=path.basename()+".*";
save_unicode_string(path);
}
// save internal resource table
@@ -1861,6 +1876,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
}
f->seek_end();
+ print_line("SAVING: "+p_path);
if (p_resource->get_import_metadata().is_valid()) {
uint64_t md_pos = f->get_pos();
Ref<ResourceImportMetadata> imd=p_resource->get_import_metadata();
@@ -1869,6 +1885,8 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
for(int i=0;i<imd->get_source_count();i++) {
save_unicode_string(imd->get_source_path(i));
save_unicode_string(imd->get_source_md5(i));
+ print_line("SAVE PATH: "+imd->get_source_path(i));
+ print_line("SAVE MD5: "+imd->get_source_md5(i));
}
List<String> options;
imd->get_options(&options);
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 006148f5a8..bd33fee82c 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -120,7 +120,7 @@ class ResourceFormatSaverBinaryInstance {
String local_path;
- bool no_extensions;
+
bool relative_paths;
bool bundle_resources;
bool skip_editor;
diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp
index fc5aecfd99..f3c0f1cb8b 100644
--- a/core/io/resource_format_xml.cpp
+++ b/core/io/resource_format_xml.cpp
@@ -1357,6 +1357,31 @@ Error ResourceInteractiveLoaderXML::poll() {
if (error!=OK)
return error;
+ if (ext_resources.size()) {
+
+ error=ERR_FILE_CORRUPT;
+ String path=ext_resources.front()->get();
+
+ RES res = ResourceLoader::load(path);
+
+ if (res.is_null()) {
+
+ if (ResourceLoader::get_abort_on_missing_resources()) {
+ ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": editor exported unexisting resource at: "+path);
+ ERR_FAIL_V(error);
+ } else {
+ ResourceLoader::notify_load_error("Resource Not Found: "+path);
+ }
+ } else {
+
+ resource_cache.push_back(res);
+ }
+
+ error=OK;
+ ext_resources.pop_front();
+ resource_current++;
+ return error;
+ }
bool exit;
Tag *tag = parse_tag(&exit);
@@ -1528,7 +1553,7 @@ int ResourceInteractiveLoaderXML::get_stage() const {
}
int ResourceInteractiveLoaderXML::get_stage_count() const {
- return resources_total;
+ return resources_total+ext_resources.size();
}
ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
@@ -1573,6 +1598,12 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path);
}
+ if (path.ends_with("*")) {
+ ERR_FAIL_COND(!tag->args.has("type"));
+ String type = tag->args["type"];
+ path = ResourceLoader::guess_full_filename(path,type);
+ }
+
p_dependencies->push_back(path);
Error err = close_tag("ext_resource");
@@ -1642,6 +1673,19 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
}
+ String preload_depts = "deps/"+local_path.md5_text();
+ if (Globals::get_singleton()->has(preload_depts)) {
+ ext_resources.clear();
+ //ignore external resources and use these
+ NodePath depts=Globals::get_singleton()->get(preload_depts);
+
+ for(int i=0;i<depts.get_name_count();i++) {
+ ext_resources.push_back(depts.get_name(i));
+ }
+ print_line(local_path+" - EXTERNAL RESOURCES: "+itos(ext_resources.size()));
+ }
+
+
}
String ResourceInteractiveLoaderXML::recognize(FileAccess *p_f) {
@@ -1969,8 +2013,6 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
if (res->get_path().length() && res->get_path().find("::")==-1) {
//external resource
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
- if (no_extension)
- path=path.basename()+".*";
escape(path);
params+=" path=\""+path+"\"";
} else {
@@ -2458,7 +2500,6 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
relative_paths=p_flags&ResourceSaver::FLAG_RELATIVE_PATHS;
skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES;
bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES;
- no_extension=p_flags&ResourceSaver::FLAG_NO_EXTENSION;
depth=0;
// save resources
@@ -2475,8 +2516,6 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
write_tabs();
String p = E->get()->get_path();
- if (no_extension)
- p=p.basename()+".*";
enter_tag("ext_resource","path=\""+p+"\" type=\""+E->get()->get_save_type()+"\""); //bundled
exit_tag("ext_resource"); //bundled
diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h
index 05313ffbd7..7874431a38 100644
--- a/core/io/resource_format_xml.h
+++ b/core/io/resource_format_xml.h
@@ -50,6 +50,10 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end);
+
+
+ List<StringName> ext_resources;
+
int resources_total;
int resource_current;
String resource_type;
@@ -113,7 +117,6 @@ class ResourceFormatSaverXMLInstance {
- bool no_extension;
bool relative_paths;
bool bundle_resources;
bool skip_editor;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 5ee48bae25..d2610d5d4f 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -166,7 +166,7 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
if (OS::get_singleton()->is_stdout_verbose())
- print_line("load resource: ");
+ print_line("load resource: "+remapped_path);
String extension=remapped_path.extension();
bool found=false;
@@ -233,6 +233,10 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p
String ResourceLoader::find_complete_path(const String& p_path,const String& p_type) {
+ //this is an old vestige when the engine saved files without extension.
+ //remains here for compatibility with old projects and only because it
+ //can be sometimes nice to open files using .* from a script and have it guess
+ //the right extension.
String local_path = p_path;
if (local_path.ends_with("*")) {
@@ -353,6 +357,13 @@ void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_depen
}
}
+String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {
+
+ String local_path = Globals::get_singleton()->localize_path(p_path);
+
+ return find_complete_path(local_path,p_type);
+
+}
String ResourceLoader::get_resource_type(const String &p_path) {
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 70b1a79582..ab23158785 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -102,6 +102,7 @@ public:
static String get_resource_type(const String &p_path);
static void get_dependencies(const String& p_path,List<String> *p_dependencies);
+ static String guess_full_filename(const String &p_path,const String& p_type);
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load=p_timestamp; }
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 4b794247e0..fd4575c872 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -74,9 +74,6 @@ public:
FLAG_OMIT_EDITOR_PROPERTIES=8,
FLAG_SAVE_BIG_ENDIAN=16,
FLAG_COMPRESS=32,
- FLAG_NO_EXTENSION=64,
-
-
};
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 5d3887d72c..92236a374f 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -220,9 +220,16 @@ int Math::decimals(double p_step) {
double Math::ease(double p_x, double p_c) {
+ if (p_x<0)
+ p_x=0;
+ else if (p_x>1.0)
+ p_x=1.0;
if (p_c>0) {
-
- return Math::pow(p_x,p_c);
+ if (p_c<1.0) {
+ return 1.0-Math::pow(1.0-p_x,1.0/p_c);
+ } else {
+ return Math::pow(p_x,p_c);
+ }
} else if (p_c<0) {
//inout ease
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index a9c49fbef2..dbf6217dc2 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -378,11 +378,12 @@ void MessageQueue::flush() {
}
}
- message->~Message();
read_pos+=sizeof(Message);
if (message->type!=TYPE_NOTIFICATION)
read_pos+=sizeof(Variant)*message->args;
+ message->~Message();
+
_THREAD_SAFE_UNLOCK_
}
diff --git a/core/object.cpp b/core/object.cpp
index 692010b1b7..b40f4ec151 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -33,6 +33,30 @@
#include "message_queue.h"
#include "core_string_names.h"
#include "translation.h"
+
+#ifdef DEBUG_ENABLED
+
+struct _ObjectDebugLock {
+
+ Object *obj;
+
+ _ObjectDebugLock(Object *p_obj) {
+ obj=p_obj;
+ obj->_lock_index.ref();
+ }
+ ~_ObjectDebugLock() {
+ obj->_lock_index.unref();
+ }
+};
+
+#define OBJ_DEBUG_LOCK _ObjectDebugLock _debug_lock(this);
+
+#else
+
+#define OBJ_DEBUG_LOCK
+
+#endif
+
Array convert_property_list(const List<PropertyInfo> * p_list) {
Array va;
@@ -562,13 +586,22 @@ void Object::call_multilevel(const StringName& p_method,const Variant** p_args,i
ERR_FAIL();
return;
}
+
+
+ if (_lock_index.get()>1) {
+ ERR_EXPLAIN("Object is locked and can't be freed.");
+ ERR_FAIL();
+ return;
+ }
#endif
+
//must be here, must be before everything,
memdelete(this);
return;
}
//Variant ret;
+ OBJ_DEBUG_LOCK
Variant::CallError error;
@@ -594,6 +627,7 @@ void Object::call_multilevel_reversed(const StringName& p_method,const Variant**
MethodBind *method=ObjectTypeDB::get_method(get_type_name(),p_method);
Variant::CallError error;
+ OBJ_DEBUG_LOCK
if (method) {
@@ -813,6 +847,15 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
ERR_EXPLAIN("Can't 'free' a reference.");
ERR_FAIL_V(Variant());
}
+
+ if (_lock_index.get()>1) {
+ r_error.argument=0;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ ERR_EXPLAIN("Object is locked and can't be freed.");
+ ERR_FAIL_V(Variant());
+
+ }
+
#endif
//must be here, must be before everything,
memdelete(this);
@@ -821,7 +864,7 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
}
Variant ret;
-
+ OBJ_DEBUG_LOCK
if (script_instance) {
ret = script_instance->call(p_method,p_args,p_argcount,r_error);
//force jumptable
@@ -902,7 +945,7 @@ void Object::set_script(const RefPtr& p_script) {
Ref<Script> s(script);
if (!s.is_null() && s->can_instance() ) {
-
+ OBJ_DEBUG_LOCK
script_instance = s->instance_create(this);
}
@@ -1066,6 +1109,8 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
int ssize = slot_map.size();
+ OBJ_DEBUG_LOCK
+
for(int i=0;i<ssize;i++) {
const Connection &c = slot_map.getv(i).conn;
@@ -1536,6 +1581,11 @@ Object::Object() {
_edited=false;
#endif
+#ifdef DEBUG_ENABLED
+ _lock_index.init(1);
+#endif
+
+
}
diff --git a/core/object.h b/core/object.h
index 913d837172..6290f9d64b 100644
--- a/core/object.h
+++ b/core/object.h
@@ -331,7 +331,9 @@ public:
Connection(const Variant& p_variant);
};
private:
-
+#ifdef DEBUG_ENABLED
+friend class _ObjectDebugLock;
+#endif
friend bool predelete_handler(Object*);
friend void postinitialize_handler(Object*);
@@ -365,7 +367,9 @@ friend void postinitialize_handler(Object*);
HashMap< StringName, Signal, StringNameHasher> signal_map;
List<Connection> connections;
-
+#ifdef DEBUG_ENABLED
+ SafeRefCount _lock_index;
+#endif
bool _block_signals;
int _predelete_ok;
Set<Object*> change_receptors;
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 23250a7345..31e7d19bae 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -428,8 +428,30 @@ void FileAccess::store_string(const String& p_string) {
CharString cs=p_string.utf8();
store_buffer((uint8_t*)&cs[0],cs.length());
-
}
+
+void FileAccess::store_pascal_string(const String& p_string) {
+
+ CharString cs = p_string.utf8();
+ store_32(cs.length());
+ store_buffer((uint8_t*)&cs[0], cs.length());
+};
+
+String FileAccess::get_pascal_string() {
+
+ uint32_t sl = get_32();
+ CharString cs;
+ cs.resize(sl+1);
+ get_buffer((uint8_t*)cs.ptr(),sl);
+ cs[sl]=0;
+
+ String ret;
+ ret.parse_utf8(cs.ptr());
+
+ return ret;
+};
+
+
void FileAccess::store_line(const String& p_line) {
store_string(p_line);
diff --git a/core/os/file_access.h b/core/os/file_access.h
index bcdae61487..793e971a4c 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -125,6 +125,9 @@ public:
virtual void store_string(const String& p_string);
virtual void store_line(const String& p_string);
+ virtual void store_pascal_string(const String& p_string);
+ virtual String get_pascal_string();
+
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
virtual bool file_exists(const String& p_name)=0; ///< return true if a file exists
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 3266e4cc10..d7c0d86d64 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -56,6 +56,7 @@ void Input::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_accelerometer"),&Input::get_accelerometer);
ObjectTypeDB::bind_method(_MD("get_mouse_pos"),&Input::get_mouse_pos);
ObjectTypeDB::bind_method(_MD("get_mouse_speed"),&Input::get_mouse_speed);
+ ObjectTypeDB::bind_method(_MD("get_mouse_button_mask"),&Input::get_mouse_button_mask);
ObjectTypeDB::bind_method(_MD("set_mouse_mode","mode"),&Input::set_mouse_mode);
ObjectTypeDB::bind_method(_MD("get_mouse_mode"),&Input::get_mouse_mode);
@@ -280,6 +281,12 @@ Point2 InputDefault::get_mouse_speed() const {
return mouse_speed_track.speed;
}
+int InputDefault::get_mouse_button_mask() const {
+
+ return OS::get_singleton()->get_mouse_button_state();
+}
+
+
void InputDefault::iteration(float p_step) {
diff --git a/core/os/input.h b/core/os/input.h
index 5987d6ef6c..cc51dbf42f 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -64,6 +64,7 @@ public:
virtual Point2 get_mouse_pos() const=0;
virtual Point2 get_mouse_speed() const=0;
+ virtual int get_mouse_button_mask() const=0;
virtual Vector3 get_accelerometer()=0;
@@ -120,6 +121,7 @@ public:
virtual Point2 get_mouse_pos() const;
virtual Point2 get_mouse_speed() const;
+ virtual int get_mouse_button_mask() const;
void parse_input_event(const InputEvent& p_event);
void set_accelerometer(const Vector3& p_accel);
diff --git a/core/os/mutex.h b/core/os/mutex.h
index 512180d6c7..241d70e232 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -50,7 +50,7 @@ public:
virtual void lock()=0; ///< Lock the mutex, block if locked by someone else
virtual void unlock()=0; ///< Unlock the mutex, let other threads continue
- virtual Error try_lock()=0; ///< Attempt to lock the mutex, true on success, false means it can't lock.
+ virtual Error try_lock()=0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock.
static Mutex * create(bool p_recursive=true); ///< Create a mutex
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 141d5f2b58..65d6ed50b2 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -92,6 +92,14 @@ int OS::get_iterations_per_second() const {
return ips;
}
+void OS::set_target_fps(int p_fps) {
+ _target_fps=p_fps>0? p_fps : 0;
+}
+
+float OS::get_target_fps() const {
+ return _target_fps;
+}
+
void OS::set_low_processor_usage_mode(bool p_enabled) {
low_processor_usage_mode=p_enabled;
@@ -116,6 +124,11 @@ String OS::get_executable_path() const {
return _execpath;
}
+int OS::get_process_ID() const {
+
+ return -1;
+};
+
uint64_t OS::get_frames_drawn() {
return frames_drawn;
@@ -430,7 +443,7 @@ Error OS::native_video_play(String p_path) {
return FAILED;
};
-bool OS::native_video_is_playing() {
+bool OS::native_video_is_playing() const {
return false;
};
@@ -447,6 +460,15 @@ void OS::set_mouse_mode(MouseMode p_mode) {
}
+bool OS::can_use_threads() const {
+
+#ifdef NO_THREADS
+ return false;
+#else
+ return true;
+#endif
+}
+
OS::MouseMode OS::get_mouse_mode() const{
return MOUSE_MODE_VISIBLE;
@@ -465,6 +487,7 @@ OS::OS() {
_exit_code=0;
_orientation=SCREEN_LANDSCAPE;
_fps=1;
+ _target_fps=0;
_render_thread_mode=RENDER_THREAD_SAFE;
Math::seed(1234567);
}
diff --git a/core/os/os.h b/core/os/os.h
index d77d9bee7f..e7fe0cb09e 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -54,6 +54,7 @@ class OS {
int _exit_code;
int _orientation;
float _fps;
+ int _target_fps;
char *last_error;
@@ -149,14 +150,19 @@ public:
virtual void set_iterations_per_second(int p_ips);
virtual int get_iterations_per_second() const;
+ virtual void set_target_fps(int p_fps);
+ virtual float get_target_fps() const;
+
virtual float get_frames_per_second() const { return _fps; };
+
virtual void set_low_processor_usage_mode(bool p_enabled);
virtual bool is_in_low_processor_usage_mode() const;
virtual String get_executable_path() const;
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL)=0;
virtual Error kill(const ProcessID& p_pid)=0;
+ virtual int get_process_ID() const;
virtual Error shell_open(String p_uri);
virtual Error set_cwd(const String& p_cwd);
@@ -316,10 +322,12 @@ public:
virtual String get_unique_ID() const;
virtual Error native_video_play(String p_path);
- virtual bool native_video_is_playing();
+ virtual bool native_video_is_playing() const;
virtual void native_video_pause();
virtual void native_video_stop();
+ virtual bool can_use_threads() const;
+
virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, Object* p_obj, String p_callback);
virtual Error dialog_input_text(String p_title, String p_description, String p_partial, Object* p_obj, String p_callback);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 6d107f97e7..7e7ce3479f 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -49,6 +49,7 @@
#include "core/io/xml_parser.h"
#include "io/http_client.h"
#include "packed_data_container.h"
+#include "func_ref.h"
#ifdef XML_ENABLED
static ResourceFormatSaverXML *resource_saver_xml=NULL;
@@ -135,6 +136,7 @@ void register_core_types() {
ObjectTypeDB::register_type<Reference>();
ObjectTypeDB::register_type<ResourceImportMetadata>();
ObjectTypeDB::register_type<Resource>();
+ ObjectTypeDB::register_type<FuncRef>();
ObjectTypeDB::register_virtual_type<StreamPeer>();
ObjectTypeDB::register_create_type<StreamPeerTCP>();
ObjectTypeDB::register_create_type<TCP_Server>();
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 2384ce5bd6..d119e341c3 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -31,6 +31,7 @@
#include "os/memory.h"
#include "print_string.h"
#include "math_funcs.h"
+#include "io/md5.h"
#include "ucaps.h"
#include "color.h"
#define MAX_DIGITS 6
@@ -2264,6 +2265,15 @@ uint64_t String::hash64() const {
}
+String String::md5_text() const {
+
+ CharString cs=utf8();
+ MD5_CTX ctx;
+ MD5Init(&ctx);
+ MD5Update(&ctx,(unsigned char*)cs.ptr(),cs.length());
+ MD5Final(&ctx);
+ return String::md5(ctx.digest);
+}
String String::insert(int p_at_pos,String p_string) const {
diff --git a/core/ustring.h b/core/ustring.h
index 007565c825..13db00f07f 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -181,7 +181,8 @@ public:
static uint32_t hash(const char* p_cstr,int p_len); /* hash the string */
static uint32_t hash(const char* p_cstr); /* hash the string */
uint32_t hash() const; /* hash the string */
- uint64_t hash64() const; /* hash the string */
+ uint64_t hash64() const; /* hash the string */
+ String md5_text() const;
inline bool empty() const { return length() == 0; }
diff --git a/core/variant.cpp b/core/variant.cpp
index efb6b8296b..e02c9c33a1 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -56,7 +56,7 @@ String Variant::get_type_name(Variant::Type p_type) {
} break;
case REAL: {
- return "real";
+ return "float";
} break;
case STRING: {
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index be1b0eb3d3..6ab33b7bcc 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -600,6 +600,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_PTR0R( Matrix3, determinant );
VCALL_PTR2R( Matrix3, rotated );
VCALL_PTR1R( Matrix3, scaled );
+ VCALL_PTR0R( Matrix3, get_scale );
VCALL_PTR0R( Matrix3, get_euler );
VCALL_PTR1R( Matrix3, tdotx );
VCALL_PTR1R( Matrix3, tdoty );
@@ -1390,6 +1391,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC0(MATRIX3,REAL,Matrix3,determinant,varray());
ADDFUNC2(MATRIX3,MATRIX3,Matrix3,rotated,VECTOR3,"axis",REAL,"phi",varray());
ADDFUNC1(MATRIX3,MATRIX3,Matrix3,scaled,VECTOR3,"scale",varray());
+ ADDFUNC0(MATRIX3,VECTOR3,Matrix3,get_scale,varray());
ADDFUNC0(MATRIX3,VECTOR3,Matrix3,get_euler,varray());
ADDFUNC1(MATRIX3,REAL,Matrix3,tdotx,VECTOR3,"with",varray());
ADDFUNC1(MATRIX3,REAL,Matrix3,tdoty,VECTOR3,"with",varray());
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 50908bbf94..7f46f4c322 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -103,8 +103,8 @@ case m_name: {\
case BOOL: _RETURN( p_a._data.m_type m_op p_b._data._bool);\
case INT: _RETURN( p_a._data.m_type m_op p_b._data._int);\
case REAL: _RETURN( p_a._data.m_type m_op p_b._data._real);\
- case VECTOR2: _RETURN( p_a._data.m_type m_op *reinterpret_cast<const Vector2*>(p_a._data._mem));\
- case VECTOR3: _RETURN( p_a._data.m_type m_op *reinterpret_cast<const Vector3*>(p_a._data._mem));\
+ case VECTOR2: _RETURN( p_a._data.m_type m_op *reinterpret_cast<const Vector2*>(p_b._data._mem));\
+ case VECTOR3: _RETURN( p_a._data.m_type m_op *reinterpret_cast<const Vector3*>(p_b._data._mem));\
default: {}\
}\
r_valid=false;\