summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct9
-rw-r--r--core/color.cpp2
-rw-r--r--core/color.h2
-rw-r--r--core/io/resource_loader.cpp10
-rw-r--r--core/io/resource_loader.h4
-rw-r--r--core/io/resource_saver.cpp2
-rw-r--r--core/io/resource_saver.h2
-rw-r--r--core/object.cpp26
-rw-r--r--core/object.h3
-rw-r--r--core/set.h1
-rw-r--r--doc/tools/doc_merge.py2
-rwxr-xr-xdoc/tools/makerst.py8
-rw-r--r--drivers/gles2/shaders/canvas.glsl3
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp21
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp96
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/unix/net_socket_posix.cpp2
-rw-r--r--drivers/unix/os_unix.cpp6
-rw-r--r--editor/editor_export.cpp14
-rw-r--r--editor/editor_export.h4
-rw-r--r--editor/editor_file_system.cpp6
-rw-r--r--editor/editor_file_system.h2
-rw-r--r--editor/editor_folding.cpp175
-rw-r--r--editor/editor_folding.h25
-rw-r--r--editor/editor_inspector.cpp102
-rw-r--r--editor/editor_inspector.h18
-rw-r--r--editor/editor_node.cpp25
-rw-r--r--editor/editor_node.h7
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/import_dock.cpp51
-rw-r--r--editor/import_dock.h1
-rw-r--r--editor/inspector_dock.cpp1
-rw-r--r--editor/plugins/script_editor_plugin.cpp8
-rw-r--r--editor/project_export.cpp79
-rw-r--r--editor/project_export.h2
-rw-r--r--editor/scene_tree_dock.cpp27
-rw-r--r--editor/scene_tree_editor.cpp7
-rw-r--r--gles_builders.py4
-rw-r--r--methods.py2
-rw-r--r--modules/gdnative/gdnative.cpp7
-rw-r--r--modules/gdnative/gdnative/array.cpp32
-rw-r--r--modules/gdnative/gdnative/basis.cpp9
-rw-r--r--modules/gdnative/gdnative/color.cpp41
-rw-r--r--modules/gdnative/gdnative/node_path.cpp9
-rw-r--r--modules/gdnative/gdnative/quat.cpp6
-rw-r--r--modules/gdnative/gdnative/rect2.cpp21
-rw-r--r--modules/gdnative/gdnative/string.cpp58
-rw-r--r--modules/gdnative/gdnative_api.json177
-rw-r--r--modules/gdnative/include/gdnative/array.h8
-rw-r--r--modules/gdnative/include/gdnative/basis.h2
-rw-r--r--modules/gdnative/include/gdnative/color.h14
-rw-r--r--modules/gdnative/include/gdnative/node_path.h2
-rw-r--r--modules/gdnative/include/gdnative/quat.h2
-rw-r--r--modules/gdnative/include/gdnative/rect2.h6
-rw-r--r--modules/gdnative/include/gdnative/string.h6
-rw-r--r--modules/mono/glue/Managed/Files/GD.cs16
-rw-r--r--modules/mono/glue/gd_glue.cpp10
-rw-r--r--modules/visual_script/visual_script_editor.cpp18
-rw-r--r--platform/android/build.gradle.template2
-rw-r--r--platform/android/detect.py4
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java188
-rw-r--r--platform/iphone/detect.py2
-rw-r--r--platform/javascript/detect.py4
-rw-r--r--platform/javascript/os_javascript.cpp18
-rw-r--r--platform/javascript/os_javascript.h4
-rw-r--r--platform/osx/detect.py2
-rw-r--r--platform/osx/os_osx.h4
-rw-r--r--platform/osx/os_osx.mm7
-rw-r--r--platform/server/SCsub15
-rw-r--r--platform/server/detect.py12
-rw-r--r--platform/server/os_server.cpp8
-rw-r--r--platform/server/os_server.h10
-rw-r--r--platform/server/platform_config.h5
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--scene/gui/text_edit.cpp16
-rw-r--r--scene/gui/text_edit.h2
-rw-r--r--scene/main/node.cpp2
-rw-r--r--scene/main/node.h2
-rw-r--r--scene/resources/material.cpp2
-rw-r--r--thirdparty/libwebsockets/lws_config.h2
-rw-r--r--thirdparty/libwebsockets/lws_config_private.h2
82 files changed, 1306 insertions, 222 deletions
diff --git a/SConstruct b/SConstruct
index f8c1c82961..628aac42af 100644
--- a/SConstruct
+++ b/SConstruct
@@ -349,7 +349,10 @@ if selected_platform in platform_list:
else: # always enable those errors
env.Append(CCFLAGS=['-Werror=return-type'])
- suffix = "." + selected_platform
+ if (hasattr(detect, 'get_program_suffix')):
+ suffix = "." + detect.get_program_suffix()
+ else:
+ suffix = "." + selected_platform
if (env["target"] == "release"):
if env["tools"]:
@@ -544,7 +547,7 @@ if 'env' in locals():
[os.remove(f) for f in files]
def file_list(self):
- if self.path == None:
+ if self.path is None:
# Nothing to do
return []
# Gather a list of (filename, (size, atime)) within the
@@ -569,7 +572,7 @@ if 'env' in locals():
if sum > self.limit:
mark = i
break
- if mark == None:
+ if mark is None:
return []
else:
return [x[0] for x in file_stat[mark:]]
diff --git a/core/color.cpp b/core/color.cpp
index 55dd1ec6b9..ac314417ec 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -468,7 +468,7 @@ String Color::to_html(bool p_alpha) const {
return txt;
}
-Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) {
+Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
p_h = Math::fmod(p_h * 360.0f, 360.0f);
if (p_h < 0.0)
diff --git a/core/color.h b/core/color.h
index add61343ff..d6ad5f91c5 100644
--- a/core/color.h
+++ b/core/color.h
@@ -194,7 +194,7 @@ struct Color {
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
- Color from_hsv(float p_h, float p_s, float p_v, float p_a);
+ Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
static Color from_rgbe9995(uint32_t p_color);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index d156a9f4bd..71b01aa94a 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -259,6 +259,10 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
}
#endif
+ if (_loaded_callback) {
+ _loaded_callback(res, p_path);
+ }
+
return res;
}
@@ -635,6 +639,12 @@ void ResourceLoader::clear_path_remaps() {
path_remaps.clear();
}
+void ResourceLoader::set_load_callback(ResourceLoadedCallback p_callback) {
+ _loaded_callback = p_callback;
+}
+
+ResourceLoadedCallback ResourceLoader::_loaded_callback = NULL;
+
ResourceLoadErrorNotify ResourceLoader::err_notify = NULL;
void *ResourceLoader::err_notify_ud = NULL;
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 96bc6fa8dd..7ade4a2dfc 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -78,6 +78,7 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text);
typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type);
typedef Error (*ResourceLoaderImport)(const String &p_path);
+typedef void (*ResourceLoadedCallback)(RES p_resource, const String &p_path);
class ResourceLoader {
@@ -106,6 +107,8 @@ class ResourceLoader {
//internal load function
static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error);
+ static ResourceLoadedCallback _loaded_callback;
+
public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
@@ -150,6 +153,7 @@ public:
static void load_translation_remaps();
static void clear_translation_remaps();
+ static void set_load_callback(ResourceLoadedCallback p_callback);
static ResourceLoaderImport import;
};
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 5c8188f735..097e81e308 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -90,7 +90,7 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
rwcopy->set_path(old_path);
if (save_callback && p_path.begins_with("res://"))
- save_callback(p_path);
+ save_callback(p_resource, p_path);
return OK;
} else {
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 7ed580f2d6..6134d9db57 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -46,7 +46,7 @@ public:
virtual ~ResourceFormatSaver() {}
};
-typedef void (*ResourceSavedCallback)(const String &p_path);
+typedef void (*ResourceSavedCallback)(Ref<Resource> p_resource, const String &p_path);
class ResourceSaver {
diff --git a/core/object.cpp b/core/object.cpp
index 946040ba34..374e10726a 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -440,16 +440,6 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
if (r_valid)
*r_valid = true;
return;
-#ifdef TOOLS_ENABLED
- } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) {
- Array arr = p_value;
- for (int i = 0; i < arr.size(); i++) {
- editor_section_folding.insert(arr[i]);
- }
- if (r_valid)
- *r_valid = true;
- return;
-#endif
}
//something inside the object... :|
@@ -520,16 +510,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
if (r_valid)
*r_valid = true;
return ret;
-#ifdef TOOLS_ENABLED
- } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) {
- Array array;
- for (Set<String>::Element *E = editor_section_folding.front(); E; E = E->next()) {
- array.push_back(E->get());
- }
- if (r_valid)
- *r_valid = true;
- return array;
-#endif
+
} else {
//something inside the object... :|
bool success = _getv(p_name, ret);
@@ -657,11 +638,6 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
#endif
p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NONZERO));
}
-#ifdef TOOLS_ENABLED
- if (editor_section_folding.size()) {
- p_list->push_back(PropertyInfo(Variant::ARRAY, CoreStringNames::get_singleton()->_sections_unfolded, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
- }
-#endif
if (!metadata.empty())
p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_STORE_IF_NONZERO));
if (script_instance && !p_reversed) {
diff --git a/core/object.h b/core/object.h
index b23160c1df..0fee7c2157 100644
--- a/core/object.h
+++ b/core/object.h
@@ -723,6 +723,9 @@ public:
#ifdef TOOLS_ENABLED
void editor_set_section_unfold(const String &p_section, bool p_unfolded);
bool editor_is_section_unfolded(const String &p_section);
+ const Set<String> &editor_get_section_folding() const { return editor_section_folding; }
+ void editor_clear_section_folding() { editor_section_folding.clear(); }
+
#endif
//used by script languages to store binding data
diff --git a/core/set.h b/core/set.h
index 744019d5b4..59aa54128e 100644
--- a/core/set.h
+++ b/core/set.h
@@ -595,6 +595,7 @@ public:
return e;
}
+ inline bool empty() const { return _data.size_cache == 0; }
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
diff --git a/doc/tools/doc_merge.py b/doc/tools/doc_merge.py
index 57ac4bdcdd..496d5dcb74 100644
--- a/doc/tools/doc_merge.py
+++ b/doc/tools/doc_merge.py
@@ -82,7 +82,7 @@ def find_signal_descr(old_class, name):
def find_constant_descr(old_class, name):
- if (old_class == None):
+ if (old_class is None):
return None
constants = old_class.find("constants")
if(constants != None and len(list(constants)) > 0):
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index b3d6d32c26..7b7cc52547 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -375,7 +375,7 @@ def make_method(
event=False,
pp=None
):
- if (declare or pp == None):
+ if (declare or pp is None):
t = '- '
else:
t = ""
@@ -405,7 +405,7 @@ def make_method(
t += 'void'
t += ' '
- if declare or pp == None:
+ if declare or pp is None:
s = '**' + method_data.attrib['name'] + '** '
else:
@@ -577,7 +577,7 @@ def make_rst_class(node):
make_method(f, name, m, True, True)
f.write('\n')
d = m.find('description')
- if d == None or d.text.strip() == '':
+ if d is None or d.text.strip() == '':
continue
f.write(rstize_text(d.text.strip(), name))
f.write("\n\n")
@@ -676,7 +676,7 @@ def make_rst_class(node):
make_method(f, name, m, True)
f.write('\n')
d = m.find('description')
- if d == None or d.text.strip() == '':
+ if d is None or d.text.strip() == '':
continue
f.write(rstize_text(d.text.strip(), name))
f.write("\n\n")
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index b990384949..79d4eb2243 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -148,7 +148,10 @@ void main() {
vec4 color = color_interp;
+#if !defined(COLOR_USED)
+ //default behavior, texture by color
color *= texture2D(color_texture, uv_interp);
+#endif
#ifdef SCREEN_UV_USED
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 0d4c83e0db..792e9eb238 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1428,7 +1428,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->particle_valid_histories[1]) {
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer, this was used 2 frames ago so it should be good enough for flushing
- RasterizerGLES3Particle *particle_array = (RasterizerGLES3Particle *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+ RasterizerGLES3Particle *particle_array;
+#ifndef __EMSCRIPTEN__
+ particle_array = static_cast<RasterizerGLES3Particle *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
+#else
+ PoolVector<RasterizerGLES3Particle> particle_vector;
+ particle_vector.resize(particles->amount);
+ PoolVector<RasterizerGLES3Particle>::Write w = particle_vector.write();
+ particle_array = w.ptr();
+ glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), particle_array);
+#endif
SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter;
@@ -1440,7 +1449,17 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
sorter.sort(particle_array, particles->amount);
+#ifndef __EMSCRIPTEN__
glUnmapBuffer(GL_ARRAY_BUFFER);
+#else
+ w = PoolVector<RasterizerGLES3Particle>::Write();
+ particle_array = NULL;
+ {
+ PoolVector<RasterizerGLES3Particle>::Read r = particle_vector.read();
+ glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), r.ptr());
+ }
+ particle_vector = PoolVector<RasterizerGLES3Particle>();
+#endif
#ifdef DEBUG_ENABLED
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 406ef6af78..8a73804eec 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -101,6 +101,28 @@
#define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
#define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#ifdef __EMSCRIPTEN__
+#include <emscripten/emscripten.h>
+
+void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) {
+
+ /* clang-format off */
+ EM_ASM({
+ GLctx.getBufferSubData($0, $1, HEAPU8, $2, $3);
+ }, target, offset, data, size);
+ /* clang-format on */
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {
+
+ /* clang-format off */
+ EM_ASM({
+ GLctx.bufferSubData($0, $1, HEAPU8, $2, $3);
+ }, target, offset, data, size);
+ /* clang-format on */
+}
+#endif
+
void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) {
#ifdef GLES_OVER_GL
@@ -3494,21 +3516,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_array(RID p_mesh, i
Surface *surface = mesh->surfaces[p_surface];
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
-
- ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
-
PoolVector<uint8_t> ret;
ret.resize(surface->array_byte_size);
+ glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ glGetBufferSubData(GL_ARRAY_BUFFER, 0, surface->array_byte_size, w.ptr());
+ }
+#else
+ void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
+ ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
{
-
PoolVector<uint8_t>::Write w = ret.write();
copymem(w.ptr(), data, surface->array_byte_size);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
+#endif
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
return ret;
}
@@ -3521,22 +3548,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_index_array(RID p_m
ERR_FAIL_COND_V(surface->index_array_len == 0, PoolVector<uint8_t>());
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
- void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
-
- ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
-
PoolVector<uint8_t> ret;
ret.resize(surface->index_array_byte_size);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr());
+ }
+#else
+ void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
+ ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
{
-
PoolVector<uint8_t>::Write w = ret.write();
copymem(w.ptr(), data, surface->index_array_byte_size);
}
-
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+#endif
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return ret;
}
@@ -3577,23 +3608,26 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap
for (int i = 0; i < mesh->surfaces[p_surface]->blend_shapes.size(); i++) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
- void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
-
- ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
-
PoolVector<uint8_t> ret;
ret.resize(mesh->surfaces[p_surface]->array_byte_size);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, w.ptr());
+ }
+#else
+ void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
+ ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
{
-
PoolVector<uint8_t>::Write w = ret.write();
copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size);
}
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+#endif
bsarr.push_back(ret);
-
- glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
}
return bsarr;
@@ -6001,9 +6035,21 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, AABB());
+ const float *data;
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
- float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ PoolVector<uint8_t> vector;
+ vector.resize(particles->amount * 16 * 6);
+ {
+ PoolVector<uint8_t>::Write w = vector.write();
+ glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, w.ptr());
+ }
+ PoolVector<uint8_t>::Read r = vector.read();
+ data = reinterpret_cast<const float *>(r.ptr());
+#else
+ data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
+#endif
AABB aabb;
Transform inv = particles->emission_transform.affine_inverse();
@@ -6020,7 +6066,13 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
aabb.expand_to(pos);
}
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ r = PoolVector<uint8_t>::Read();
+ vector = PoolVector<uint8_t>();
+#else
glUnmapBuffer(GL_ARRAY_BUFFER);
+#endif
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
float longest_axis = 0;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 9a4798ac2a..8c26e09037 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -43,6 +43,12 @@
#include "shaders/cubemap_filter.glsl.gen.h"
#include "shaders/particles.glsl.gen.h"
+// WebGL 2.0 has no MapBufferRange/UnmapBuffer, but offers a non-ES style BufferSubData API instead.
+#ifdef __EMSCRIPTEN__
+void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+#endif
+
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 2cc2032cbb..f981be66ce 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -55,7 +55,7 @@
#include <netinet/tcp.h>
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(__APPLE__)
#define MSG_NOSIGNAL SO_NOSIGPIPE
#endif
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 7ff27be501..279274734f 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -288,6 +288,11 @@ uint64_t OS_Unix::get_ticks_usec() const {
Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) {
+#ifdef __EMSCRIPTEN__
+ // Don't compile this code at all to avoid undefined references.
+ // Actual virtual call goes to OS_JavaScript.
+ ERR_FAIL_V(ERR_BUG);
+#else
if (p_blocking && r_pipe) {
String argss;
@@ -354,6 +359,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
return OK;
+#endif
}
Error OS_Unix::kill(const ProcessID &p_pid) {
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 1a6188862f..218063566a 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -144,6 +144,17 @@ String EditorExportPreset::get_include_filter() const {
return include_filter;
}
+void EditorExportPreset::set_export_path(const String &p_path) {
+
+ export_path = p_path;
+ EditorExport::singleton->save_presets();
+}
+
+String EditorExportPreset::get_export_path() const {
+
+ return export_path;
+}
+
void EditorExportPreset::set_exclude_filter(const String &p_exclude) {
exclude_filter = p_exclude;
@@ -213,6 +224,7 @@ String EditorExportPreset::get_custom_features() const {
EditorExportPreset::EditorExportPreset() {
+ export_path = "";
export_filter = EXPORT_ALL_RESOURCES;
runnable = false;
}
@@ -1034,6 +1046,7 @@ void EditorExport::_save() {
}
config->set_value(section, "include_filter", preset->get_include_filter());
config->set_value(section, "exclude_filter", preset->get_exclude_filter());
+ config->set_value(section, "export_path", preset->get_export_path());
config->set_value(section, "patch_list", preset->get_patches());
String option_section = "preset." + itos(i) + ".options";
@@ -1189,6 +1202,7 @@ void EditorExport::load_config() {
preset->set_include_filter(config->get_value(section, "include_filter"));
preset->set_exclude_filter(config->get_value(section, "exclude_filter"));
+ preset->set_export_path(config->get_value(section, "export_path", ""));
Vector<String> patch_list = config->get_value(section, "patch_list");
diff --git a/editor/editor_export.h b/editor/editor_export.h
index b4ee5b89e7..d1165fd042 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -57,6 +57,7 @@ private:
ExportFilter export_filter;
String include_filter;
String exclude_filter;
+ String export_path;
String exporter;
Set<String> selected_files;
@@ -114,6 +115,9 @@ public:
void set_custom_features(const String &p_custom_features);
String get_custom_features() const;
+ void set_export_path(const String &p_path);
+ String get_export_path() const;
+
const List<PropertyInfo> &get_properties() const { return properties; }
EditorExportPreset();
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index d73bf86f64..a99c9656ba 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1305,11 +1305,6 @@ void EditorFileSystem::_save_late_updated_files() {
}
}
-void EditorFileSystem::_resource_saved(const String &p_path) {
-
- EditorFileSystem::get_singleton()->update_file(p_path);
-}
-
Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) {
List<String> deps;
@@ -1772,7 +1767,6 @@ EditorFileSystem::EditorFileSystem() {
abort_scan = false;
scanning_changes = false;
scanning_changes_done = false;
- ResourceSaver::set_save_callback(_resource_saved);
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (da->change_dir("res://.import") != OK) {
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index 47077425a1..f6eef2a152 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -204,8 +204,6 @@ class EditorFileSystem : public Node {
bool _update_scan_actions();
- static void _resource_saved(const String &p_path);
-
void _update_extensions();
void _reimport_file(const String &p_file);
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
new file mode 100644
index 0000000000..eec4438f96
--- /dev/null
+++ b/editor/editor_folding.cpp
@@ -0,0 +1,175 @@
+#include "editor_folding.h"
+
+#include "core/os/file_access.h"
+#include "editor_settings.h"
+
+PoolVector<String> EditorFolding::_get_unfolds(const Object *p_object) {
+
+ PoolVector<String> sections;
+ sections.resize(p_object->editor_get_section_folding().size());
+ if (sections.size()) {
+ PoolVector<String>::Write w = sections.write();
+ int idx = 0;
+ for (const Set<String>::Element *E = p_object->editor_get_section_folding().front(); E; E = E->next()) {
+ w[idx++] = E->get();
+ }
+ }
+
+ return sections;
+}
+
+void EditorFolding::save_resource_folding(const RES &p_resource, const String &p_path) {
+ Ref<ConfigFile> config;
+ config.instance();
+ PoolVector<String> unfolds = _get_unfolds(p_resource.ptr());
+ config->set_value("folding", "sections_unfolded", unfolds);
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+ config->save(file);
+}
+
+void EditorFolding::_set_unfolds(Object *p_object, const PoolVector<String> &p_unfolds) {
+
+ int uc = p_unfolds.size();
+ PoolVector<String>::Read r = p_unfolds.read();
+ p_object->editor_clear_section_folding();
+ for (int i = 0; i < uc; i++) {
+ p_object->editor_set_section_unfold(r[i], true);
+ }
+}
+
+void EditorFolding::load_resource_folding(RES p_resource, const String &p_path) {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+
+ if (config->load(file) != OK) {
+ return;
+ }
+
+ PoolVector<String> unfolds;
+
+ if (config->has_section_key("folding", "sections_unfolded")) {
+ unfolds = config->get_value("folding", "sections_unfolded");
+ }
+ _set_unfolds(p_resource.ptr(), unfolds);
+}
+
+void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set<RES> &resources) {
+ if (p_root != p_node) {
+ if (!p_node->get_owner()) {
+ return; //not owned, bye
+ }
+ if (p_node->get_owner() != p_root && !p_root->is_editable_instance(p_node)) {
+ return;
+ }
+ }
+
+ PoolVector<String> unfolds = _get_unfolds(p_node);
+
+ if (unfolds.size()) {
+ p_folds.push_back(p_root->get_path_to(p_node));
+ p_folds.push_back(unfolds);
+ }
+
+ List<PropertyInfo> plist;
+ p_node->get_property_list(&plist);
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ if (E->get().type == Variant::OBJECT) {
+ RES res = p_node->get(E->get().name);
+ if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
+
+ PoolVector<String> res_unfolds = _get_unfolds(res.ptr());
+ resource_folds.push_back(res->get_path());
+ resource_folds.push_back(res_unfolds);
+ resources.insert(res);
+ }
+ }
+ }
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _fill_folds(p_root, p_node->get_child(i), p_folds, resource_folds, resources);
+ }
+}
+void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path) {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ Array unfolds, res_unfolds;
+ Set<RES> resources;
+ _fill_folds(p_scene, p_scene, unfolds, res_unfolds, resources);
+
+ config->set_value("folding", "node_unfolds", unfolds);
+ config->set_value("folding", "resource_unfolds", res_unfolds);
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+ config->save(file);
+}
+void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+
+ if (config->load(file) != OK) {
+ return;
+ }
+
+ Array unfolds;
+ if (config->has_section_key("folding", "node_unfolds")) {
+ unfolds = config->get_value("folding", "node_unfolds");
+ }
+ Array res_unfolds;
+ if (config->has_section_key("folding", "resource_unfolds")) {
+ res_unfolds = config->get_value("folding", "resource_unfolds");
+ }
+
+ ERR_FAIL_COND(unfolds.size() & 1);
+ ERR_FAIL_COND(res_unfolds.size() & 1);
+
+ for (int i = 0; i < unfolds.size(); i += 2) {
+ NodePath path = unfolds[i];
+ PoolVector<String> un = unfolds[i + 1];
+ Node *node = p_scene->get_node(path);
+ if (!node) {
+ continue;
+ }
+ _set_unfolds(node, un);
+ }
+
+ for (int i = 0; i < res_unfolds.size(); i += 2) {
+ String path = res_unfolds[i];
+ RES res;
+ if (ResourceCache::has(path)) {
+ res = RES(ResourceCache::get(path));
+ }
+ if (res.is_null()) {
+ continue;
+ }
+
+ PoolVector<String> unfolds = res_unfolds[i + 1];
+ _set_unfolds(res.ptr(), unfolds);
+ }
+}
+
+bool EditorFolding::has_folding_data(const String &p_path) {
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+ return FileAccess::exists(file);
+}
+
+EditorFolding::EditorFolding() {
+}
diff --git a/editor/editor_folding.h b/editor/editor_folding.h
new file mode 100644
index 0000000000..cfd4b5466d
--- /dev/null
+++ b/editor/editor_folding.h
@@ -0,0 +1,25 @@
+#ifndef EDITOR_FOLDING_H
+#define EDITOR_FOLDING_H
+
+#include "scene/main/node.h"
+
+class EditorFolding {
+
+ PoolVector<String> _get_unfolds(const Object *p_object);
+ void _set_unfolds(Object *p_object, const PoolVector<String> &p_unfolds);
+
+ void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set<RES> &resources);
+
+public:
+ void save_resource_folding(const RES &p_resource, const String &p_path);
+ void load_resource_folding(RES p_resource, const String &p_path);
+
+ void save_scene_folding(const Node *p_scene, const String &p_path);
+ void load_scene_folding(Node *p_scene, const String &p_path);
+
+ bool has_folding_data(const String &p_path);
+
+ EditorFolding();
+};
+
+#endif // EDITOR_FOLDING_H
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 3ecaa2b136..1230588016 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -36,6 +36,50 @@
#include "multi_node_edit.h"
#include "scene/resources/packed_scene.h"
+EditorDefaultClassValueCache *EditorDefaultClassValueCache::singleton = NULL;
+
+EditorDefaultClassValueCache *EditorDefaultClassValueCache::get_singleton() {
+ return singleton;
+}
+
+Variant EditorDefaultClassValueCache::get_default_value(const StringName &p_class, const StringName &p_property) {
+
+ if (!default_values.has(p_class)) {
+
+ default_values[p_class] = Map<StringName, Variant>();
+
+ if (ClassDB::can_instance(p_class)) {
+
+ Object *c = ClassDB::instance(p_class);
+ List<PropertyInfo> plist;
+ c->get_property_list(&plist);
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ if (E->get().usage & PROPERTY_USAGE_EDITOR) {
+
+ Variant v = c->get(E->get().name);
+ default_values[p_class][E->get().name] = v;
+ }
+ }
+ memdelete(c);
+ }
+ }
+
+ if (!default_values.has(p_class)) {
+ return Variant();
+ }
+
+ if (!default_values[p_class].has(p_property)) {
+ return Variant();
+ }
+
+ return default_values[p_class][p_property];
+}
+
+EditorDefaultClassValueCache::EditorDefaultClassValueCache() {
+ ERR_FAIL_COND(singleton != NULL);
+ singleton = this;
+}
+
Size2 EditorProperty::get_minimum_size() const {
Size2 ms;
@@ -458,6 +502,12 @@ void EditorProperty::update_reload_status() {
bool has_reload = false;
+ if (EditorDefaultClassValueCache::get_singleton()) {
+ Variant default_value = EditorDefaultClassValueCache::get_singleton()->get_default_value(object->get_class_name(), property);
+ if (default_value != Variant() && default_value != object->get(property)) {
+ has_reload = true;
+ }
+ }
if (_is_instanced_node_with_original_property_different()) {
has_reload = true;
}
@@ -651,6 +701,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
Variant rev = object->call("property_get_revert", property);
emit_signal("property_changed", property, rev);
update_property();
+ return;
}
if (!object->get_script().is_null()) {
@@ -659,6 +710,16 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
if (scr->get_property_default_value(property, orig_value)) {
emit_signal("property_changed", property, orig_value);
update_property();
+ return;
+ }
+ }
+
+ if (EditorDefaultClassValueCache::get_singleton()) {
+ Variant default_value = EditorDefaultClassValueCache::get_singleton()->get_default_value(object->get_class_name(), property);
+ if (default_value != Variant()) {
+ emit_signal("property_changed", property, default_value);
+ update_property();
+ return;
}
}
}
@@ -1370,6 +1431,28 @@ void EditorInspector::update_tree() {
// TreeItem *current_category = NULL;
+ bool unfold_if_edited = false;
+
+ if (use_folding && auto_unfold_edited && get_tree()->get_edited_scene_root()) {
+ String path;
+ Node *node = Object::cast_to<Node>(object);
+ if (node) {
+ path = get_tree()->get_edited_scene_root()->get_filename();
+ }
+ Resource *res = Object::cast_to<Resource>(object);
+ if (res) {
+ if (res->get_path().is_resource_file()) {
+ path = res->get_path();
+ } else if (res->get_path().begins_with("res://")) { //internal resource
+ path = get_tree()->get_edited_scene_root()->get_filename();
+ }
+ }
+
+ if (!EditorNode::get_singleton()->get_editor_folding().has_folding_data(path)) {
+ unfold_if_edited = true;
+ }
+ }
+
String filter = search_box ? search_box->get_text() : "";
String group;
String group_base;
@@ -1380,6 +1463,8 @@ void EditorInspector::update_tree() {
object->get_property_list(&plist, true);
HashMap<String, VBoxContainer *> item_path;
+ Map<VBoxContainer *, EditorInspectorSection *> section_map;
+
item_path[""] = main_vbox;
Color sscolor = get_color("prop_subsection", "Editor");
@@ -1542,7 +1627,9 @@ void EditorInspector::update_tree() {
c.a /= level;
section->setup(acc_path, path_name, object, c, use_folding);
- item_path[acc_path] = section->get_vbox();
+ VBoxContainer *vb = section->get_vbox();
+ item_path[acc_path] = vb;
+ section_map[vb] = section;
}
current_vbox = item_path[acc_path];
level = (MIN(level + 1, 4));
@@ -1685,6 +1772,13 @@ void EditorInspector::update_tree() {
if (current_selected && ep->property == current_selected) {
ep->select(current_focusable);
}
+
+ if (unfold_if_edited && ep->can_revert_to_default()) {
+ //if edited and there is a parent section, unfold it.
+ if (current_vbox && section_map.has(current_vbox)) {
+ section_map[current_vbox]->unfold();
+ }
+ }
}
}
@@ -2181,6 +2275,10 @@ String EditorInspector::get_object_class() const {
return object_class;
}
+void EditorInspector::set_auto_unfold_edited(bool p_enable) {
+ auto_unfold_edited = p_enable;
+}
+
void EditorInspector::_bind_methods() {
ClassDB::bind_method("_property_changed", &EditorInspector::_property_changed, DEFVAL(false));
@@ -2205,6 +2303,7 @@ void EditorInspector::_bind_methods() {
ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop")));
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property")));
+ ADD_SIGNAL(MethodInfo("property_toggled", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "checked")));
ADD_SIGNAL(MethodInfo("restart_requested"));
}
@@ -2236,6 +2335,7 @@ EditorInspector::EditorInspector() {
set_process(true);
property_focusable = -1;
use_sub_inspector_bg = false;
+ auto_unfold_edited = false;
get_v_scrollbar()->connect("value_changed", this, "_vscroll_changed");
update_scroll_request = -1;
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index dccbdb9a73..350debcb7b 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -37,6 +37,20 @@
class UndoRedo;
+class EditorDefaultClassValueCache : public Object {
+ GDCLASS(EditorDefaultClassValueCache, Object)
+
+ Map<StringName, Map<StringName, Variant> > default_values;
+
+ static EditorDefaultClassValueCache *singleton;
+
+public:
+ static EditorDefaultClassValueCache *get_singleton();
+
+ Variant get_default_value(const StringName &p_class, const StringName &p_property);
+ EditorDefaultClassValueCache();
+};
+
class EditorProperty : public Container {
GDCLASS(EditorProperty, Container)
@@ -152,6 +166,8 @@ public:
void set_draw_top_bg(bool p_draw) { draw_top_bg = p_draw; }
+ bool can_revert_to_default() const { return can_revert; }
+
EditorProperty();
};
@@ -271,6 +287,7 @@ class EditorInspector : public ScrollContainer {
bool read_only;
bool keying;
bool use_sub_inspector_bg;
+ bool auto_unfold_edited;
float refresh_countdown;
bool update_tree_pending;
@@ -365,6 +382,7 @@ public:
String get_object_class() const;
void set_use_sub_inspector_bg(bool p_enable);
+ void set_auto_unfold_edited(bool p_enable);
EditorInspector();
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 7155905472..e9ce2cb8ae 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1061,6 +1061,9 @@ void EditorNode::_save_scene(String p_file, int idx) {
set_current_version(editor_data.get_undo_redo().get_version());
else
editor_data.set_edited_scene_version(0, idx);
+
+ editor_folding.save_scene_folding(scene, p_file);
+
_update_title();
_update_scene_tabs();
} else {
@@ -2907,6 +2910,8 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
_update_scene_tabs();
_add_to_recent_scenes(lpath);
+ editor_folding.load_scene_folding(new_scene, lpath);
+
prev_scene->set_disabled(previous_scenes.size() == 0);
opening_prev = false;
@@ -4544,6 +4549,19 @@ void EditorNode::_video_driver_selected(int p_which) {
_update_video_driver_color();
}
+void EditorNode::_resource_saved(RES p_resource, const String &p_path) {
+ if (EditorFileSystem::get_singleton()) {
+ EditorFileSystem::get_singleton()->update_file(p_path);
+ }
+
+ singleton->editor_folding.save_resource_folding(p_resource, p_path);
+}
+
+void EditorNode::_resource_loaded(RES p_resource, const String &p_path) {
+
+ singleton->editor_folding.load_resource_folding(p_resource, p_path);
+}
+
void EditorNode::_bind_methods() {
ClassDB::bind_method("_menu_option", &EditorNode::_menu_option);
@@ -4733,6 +4751,8 @@ EditorNode::EditorNode() {
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
+ default_value_cache = memnew(EditorDefaultClassValueCache);
+
{ //register importers at the beginning, so dialogs are created with the right extensions
Ref<ResourceImporterTexture> import_texture;
import_texture.instance();
@@ -4844,6 +4864,7 @@ EditorNode::EditorNode() {
EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
EDITOR_DEF_RST("interface/inspector/disable_folding", false);
+ EDITOR_DEF_RST("interface/inspector/auto_unfold_edited", true);
EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
@@ -5829,6 +5850,9 @@ EditorNode::EditorNode() {
print_handler.userdata = this;
add_print_handler(&print_handler);
+ ResourceSaver::set_save_callback(_resource_saved);
+ ResourceLoader::set_load_callback(_resource_loaded);
+
#ifdef OSX_ENABLED
ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_ALT | KEY_1);
ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2);
@@ -5857,6 +5881,7 @@ EditorNode::~EditorNode() {
memdelete(editor_plugins_force_input_forwarding);
memdelete(file_server);
memdelete(progress_hb);
+ memdelete(default_value_cache);
EditorSettings::destroy();
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 0096748ed1..33af473de3 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -38,6 +38,7 @@
#include "editor/editor_about.h"
#include "editor/editor_data.h"
#include "editor/editor_export.h"
+#include "editor/editor_folding.h"
#include "editor/editor_inspector.h"
#include "editor/editor_log.h"
#include "editor/editor_name_dialog.h"
@@ -271,6 +272,7 @@ private:
Ref<Theme> theme;
+ EditorDefaultClassValueCache *default_value_cache;
PopupMenu *recent_scenes;
SceneTreeDock *scene_tree_dock;
InspectorDock *inspector_dock;
@@ -385,6 +387,7 @@ private:
EditorSelection *editor_selection;
ProjectExportDialog *project_export;
EditorResourcePreview *resource_preview;
+ EditorFolding editor_folding;
EditorFileServer *file_server;
@@ -600,6 +603,9 @@ private:
PrintHandlerList print_handler;
static void _print_handler(void *p_this, const String &p_string, bool p_error);
+ static void _resource_saved(RES p_resource, const String &p_path);
+ static void _resource_loaded(RES p_resource, const String &p_path);
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -690,6 +696,7 @@ public:
void set_current_scene(int p_idx);
static EditorData &get_editor_data() { return singleton->editor_data; }
+ static EditorFolding &get_editor_folding() { return singleton->editor_folding; }
EditorHistory *get_editor_history() { return &editor_history; }
static VSplitContainer *get_top_split() { return singleton->top_split; }
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index ef960f74ea..2136211faa 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -353,7 +353,7 @@ void FileSystemDock::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- if (tree->is_visible_in_tree()) {
+ if (is_visible_in_tree()) {
_update_display_mode(true);
}
} break;
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 31eb193461..2e68609a56 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -38,11 +38,17 @@ public:
List<PropertyInfo> properties;
Ref<ResourceImporter> importer;
Vector<String> paths;
+ Set<StringName> checked;
+ bool checking;
bool _set(const StringName &p_name, const Variant &p_value) {
if (values.has(p_name)) {
values[p_name] = p_value;
+ if (checking) {
+ checked.insert(p_name);
+ _change_notify(String(p_name).utf8().get_data());
+ }
return true;
}
@@ -63,13 +69,24 @@ public:
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
if (!importer->get_option_visibility(E->get().name, values))
continue;
- p_list->push_back(E->get());
+ PropertyInfo pi = E->get();
+ if (checking) {
+ pi.usage |= PROPERTY_USAGE_CHECKABLE;
+ if (checked.has(E->get().name)) {
+ pi.usage |= PROPERTY_USAGE_CHECKED;
+ }
+ }
+ p_list->push_back(pi);
}
}
void update() {
_change_notify();
}
+
+ ImportDockParameters() {
+ checking = false;
+ }
};
void ImportDock::set_edit_path(const String &p_path) {
@@ -125,6 +142,8 @@ void ImportDock::_update_options(const Ref<ConfigFile> &p_config) {
params->properties.clear();
params->values.clear();
+ params->checking = false;
+ params->checked.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
@@ -205,6 +224,8 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
params->properties.clear();
params->values.clear();
+ params->checking = true;
+ params->checked.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
@@ -360,11 +381,21 @@ void ImportDock::_reimport() {
Error err = config->load(params->paths[i] + ".import");
ERR_CONTINUE(err != OK);
- config->set_value("remap", "importer", params->importer->get_importer_name());
- config->erase_section("params");
+ if (params->checking) {
+ //update only what edited (checkboxes)
+ for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
+ if (params->checked.has(E->get().name)) {
+ config->set_value("params", E->get().name, params->values[E->get().name]);
+ }
+ }
+ } else {
+ //override entirely
+ config->set_value("remap", "importer", params->importer->get_importer_name());
+ config->erase_section("params");
- for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
- config->set_value("params", E->get().name, params->values[E->get().name]);
+ for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
+ config->set_value("params", E->get().name, params->values[E->get().name]);
+ }
}
config->save(params->paths[i] + ".import");
@@ -388,11 +419,20 @@ void ImportDock::_notification(int p_what) {
} break;
}
}
+
+void ImportDock::_property_toggled(const StringName &p_prop, bool p_checked) {
+ if (p_checked) {
+ params->checked.insert(p_prop);
+ } else {
+ params->checked.erase(p_prop);
+ }
+}
void ImportDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_reimport"), &ImportDock::_reimport);
ClassDB::bind_method(D_METHOD("_preset_selected"), &ImportDock::_preset_selected);
ClassDB::bind_method(D_METHOD("_importer_selected"), &ImportDock::_importer_selected);
+ ClassDB::bind_method(D_METHOD("_property_toggled"), &ImportDock::_property_toggled);
}
void ImportDock::initialize_import_options() const {
@@ -423,6 +463,7 @@ ImportDock::ImportDock() {
import_opts = memnew(EditorInspector);
add_child(import_opts);
import_opts->set_v_size_flags(SIZE_EXPAND_FILL);
+ import_opts->connect("property_toggled", this, "_property_toggled");
hb = memnew(HBoxContainer);
add_child(hb);
diff --git a/editor/import_dock.h b/editor/import_dock.h
index 41c7298d9a..632fd39700 100644
--- a/editor/import_dock.h
+++ b/editor/import_dock.h
@@ -60,6 +60,7 @@ class ImportDock : public VBoxContainer {
void _importer_selected(int i_idx);
void _update_options(const Ref<ConfigFile> &p_config = Ref<ConfigFile>());
+ void _property_toggled(const StringName &p_prop, bool p_checked);
void _reimport();
enum {
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 750fca2852..2a8885c0a4 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -593,6 +593,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
inspector->set_undo_redo(&editor_data->get_undo_redo());
inspector->set_use_filter(true); // TODO: check me
+ inspector->set_auto_unfold_edited(bool(EDITOR_GET("interface/inspector/auto_unfold_edited")));
inspector->connect("resource_selected", this, "_resource_selected");
inspector->connect("property_keyed", this, "_property_keyed");
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 07a7e7952a..ac69cc0df1 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1363,7 +1363,9 @@ void ScriptEditor::_notification(int p_what) {
if (is_visible()) {
find_in_files_button->show();
} else {
- find_in_files->hide();
+ if (find_in_files->is_visible_in_tree()) {
+ editor->hide_bottom_panel();
+ }
find_in_files_button->hide();
}
@@ -2806,8 +2808,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) {
find_in_files->set_with_replace(with_replace);
find_in_files->start_search();
- find_in_files_button->set_pressed(true);
- find_in_files->show();
+ editor->make_bottom_panel_item_visible(find_in_files);
}
void ScriptEditor::_on_find_in_files_modified_files(PoolStringArray paths) {
@@ -3174,7 +3175,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
add_child(find_in_files_dialog);
find_in_files = memnew(FindInFilesPanel);
find_in_files_button = editor->add_bottom_panel_item(TTR("Search Results"), find_in_files);
- find_in_files_button->set_tooltip(TTR("Search in files"));
find_in_files->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
find_in_files->connect(FindInFilesPanel::SIGNAL_RESULT_SELECTED, this, "_on_find_in_files_result_selected");
find_in_files->connect(FindInFilesPanel::SIGNAL_FILES_MODIFIED, this, "_on_find_in_files_modified_files");
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 3ec49e187f..d2dccdb425 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -50,6 +50,7 @@ void ProjectExportDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
+ duplicate_preset->set_icon(get_icon("Duplicate", "EditorIcons"));
delete_preset->set_icon(get_icon("Remove", "EditorIcons"));
connect("confirmed", this, "_export_pck_zip");
custom_feature_display->get_parent_control()->add_style_override("panel", get_stylebox("bg", "Tree"));
@@ -58,6 +59,7 @@ void ProjectExportDialog::_notification(int p_what) {
EditorSettings::get_singleton()->set("interface/dialogs/export_bounds", get_rect());
} break;
case NOTIFICATION_THEME_CHANGED: {
+ duplicate_preset->set_icon(get_icon("Duplicate", "EditorIcons"));
delete_preset->set_icon(get_icon("Remove", "EditorIcons"));
Control *panel = custom_feature_display->get_parent_control();
if (panel)
@@ -171,6 +173,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
runnable->set_disabled(true);
parameters->edit(NULL);
presets->unselect_all();
+ duplicate_preset->set_disabled(true);
delete_preset->set_disabled(true);
sections->hide();
patches->clear();
@@ -188,6 +191,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
sections->show();
name->set_editable(true);
+ duplicate_preset->set_disabled(false);
delete_preset->set_disabled(false);
name->set_text(current->get_name());
runnable->set_disabled(false);
@@ -428,6 +432,61 @@ void ProjectExportDialog::_name_changed(const String &p_string) {
_update_presets();
}
+void ProjectExportDialog::_duplicate_preset() {
+
+ Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
+ if (current.is_null())
+ return;
+
+ Ref<EditorExportPreset> preset = current->get_platform()->create_preset();
+ ERR_FAIL_COND(!preset.is_valid());
+
+ String name = current->get_name() + "" + itos(1);
+ bool make_runnable = true;
+ int attempt = 2;
+ while (true) {
+
+ bool valid = true;
+
+ for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
+ Ref<EditorExportPreset> p = EditorExport::get_singleton()->get_export_preset(i);
+ if (p->get_platform() == preset->get_platform() && p->is_runnable()) {
+ make_runnable = false;
+ }
+ if (p->get_name() == name) {
+ valid = false;
+ break;
+ }
+ }
+
+ if (valid)
+ break;
+
+ attempt++;
+ name = current->get_name() + " " + itos(attempt);
+ }
+
+ preset->set_name(name);
+ if (make_runnable)
+ preset->set_runnable(make_runnable);
+ preset->set_export_filter(current->get_export_filter());
+ preset->set_include_filter(current->get_include_filter());
+ preset->set_exclude_filter(current->get_exclude_filter());
+ Vector<String> list = current->get_patches();
+ for (int i = 0; i < list.size(); i++) {
+ preset->add_patch(list[i]);
+ }
+ preset->set_custom_features(current->get_custom_features());
+
+ for (const List<PropertyInfo>::Element *E = current->get_properties().front(); E; E = E->next()) {
+ preset->set(E->get().name, current->get(E->get().name));
+ }
+
+ EditorExport::get_singleton()->add_export_preset(preset);
+ _update_presets();
+ _edit_preset(EditorExport::get_singleton()->get_export_preset_count() - 1);
+}
+
void ProjectExportDialog::_delete_preset() {
Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
@@ -745,12 +804,16 @@ void ProjectExportDialog::_export_project() {
export_project->set_access(FileDialog::ACCESS_FILESYSTEM);
export_project->clear_filters();
- String extension = platform->get_binary_extension(current);
- if (extension != String()) {
- export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export");
- export_project->set_current_file(default_filename + "." + extension);
+ if (current->get_export_path() != "") {
+ export_project->set_current_path(current->get_export_path());
} else {
- export_project->set_current_file(default_filename);
+ String extension = platform->get_binary_extension(current);
+ if (extension != String()) {
+ export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export");
+ export_project->set_current_file(default_filename + "." + extension);
+ } else {
+ export_project->set_current_file(default_filename);
+ }
}
// Ensure that signal is connected if previous attempt left it disconnected with _validate_export_path
@@ -772,6 +835,7 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
ERR_FAIL_COND(current.is_null());
Ref<EditorExportPlatform> platform = current->get_platform();
ERR_FAIL_COND(platform.is_null());
+ current->set_export_path(p_path);
Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0);
if (err != OK) {
@@ -789,6 +853,7 @@ void ProjectExportDialog::_bind_methods() {
ClassDB::bind_method("_update_parameters", &ProjectExportDialog::_update_parameters);
ClassDB::bind_method("_runnable_pressed", &ProjectExportDialog::_runnable_pressed);
ClassDB::bind_method("_name_changed", &ProjectExportDialog::_name_changed);
+ ClassDB::bind_method("_duplicate_preset", &ProjectExportDialog::_duplicate_preset);
ClassDB::bind_method("_delete_preset", &ProjectExportDialog::_delete_preset);
ClassDB::bind_method("_delete_preset_confirm", &ProjectExportDialog::_delete_preset_confirm);
ClassDB::bind_method("get_drag_data_fw", &ProjectExportDialog::get_drag_data_fw);
@@ -842,6 +907,9 @@ ProjectExportDialog::ProjectExportDialog() {
presets->set_drag_forwarding(this);
mc->add_child(presets);
presets->connect("item_selected", this, "_edit_preset");
+ duplicate_preset = memnew(ToolButton);
+ preset_hb->add_child(duplicate_preset);
+ duplicate_preset->connect("pressed", this, "_duplicate_preset");
delete_preset = memnew(ToolButton);
preset_hb->add_child(delete_preset);
delete_preset->connect("pressed", this, "_delete_preset");
@@ -949,6 +1017,7 @@ ProjectExportDialog::ProjectExportDialog() {
//disable by default
name->set_editable(false);
runnable->set_disabled(true);
+ duplicate_preset->set_disabled(true);
delete_preset->set_disabled(true);
sections->hide();
parameters->edit(NULL);
diff --git a/editor/project_export.h b/editor/project_export.h
index 552c6d7faf..a4bca843a8 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -61,6 +61,7 @@ private:
TabContainer *sections;
MenuButton *add_preset;
+ Button *duplicate_preset;
Button *delete_preset;
ItemList *presets;
@@ -108,6 +109,7 @@ private:
void _name_changed(const String &p_string);
void _add_preset(int p_platform);
void _edit_preset(int p_index);
+ void _duplicate_preset();
void _delete_preset();
void _delete_preset_confirm();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 4f0f79ee1b..f992d4d2e0 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -358,15 +358,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
ScriptLanguage *l = ScriptServer::get_language(i);
if (l->get_type() == existing->get_class()) {
String name = l->get_global_class_name(existing->get_path());
- if (ScriptServer::is_global_class(name)) {
- if (EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
- inherits = editor->get_editor_data().script_class_get_base(name);
- } else if (l->can_inherit_from_file()) {
- inherits = "\"" + existing->get_path() + "\"";
- }
- } else {
+ if (ScriptServer::is_global_class(name) && EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
+ inherits = name;
+ } else if (l->can_inherit_from_file()) {
inherits = "\"" + existing->get_path() + "\"";
}
+ break;
}
}
}
@@ -1503,6 +1500,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
editor_data->get_undo_redo().commit_action();
editor->push_item(p_script.operator->());
+ _update_script_button();
}
void SceneTreeDock::_toggle_editable_children() {
@@ -1618,17 +1616,17 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_update_script_button() {
if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) {
- button_create_script->show();
Node *n = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0];
if (n->get_script().is_null()) {
- button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
- button_create_script->set_tooltip(TTR("Attach a new or existing script for the selected node."));
+ button_create_script->show();
+ button_clear_script->hide();
} else {
- button_create_script->set_icon(get_icon("ScriptExtend", "EditorIcons"));
- button_create_script->set_tooltip(TTR("Extend the selected node's script with a new or existing script."));
+ button_create_script->hide();
+ button_clear_script->show();
}
} else {
- button_create_script->hide();
+ button_create_script->show();
+ button_clear_script->hide();
}
}
@@ -2076,6 +2074,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
if (selection.size() > 1 || existing_script.is_valid()) {
menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_ATTACH_SCRIPT);
}
menu->add_separator();
@@ -2339,6 +2338,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene"));
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
+ ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
ED_SHORTCUT("scene_tree/clear_script", TTR("Clear Script"));
ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP);
ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN);
@@ -2375,6 +2375,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
tb = memnew(ToolButton);
tb->connect("pressed", this, "_tool_selected", make_binds(TOOL_ATTACH_SCRIPT, false));
+ tb->set_tooltip(TTR("Attach a new or existing script for the selected node."));
tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script"));
filter_hbc->add_child(tb);
tb->hide();
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 848e4def6d..6614e24df7 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -665,6 +665,13 @@ void SceneTreeEditor::_renamed() {
Node *n = get_node(np);
ERR_FAIL_COND(!n);
+ // Empty node names are not allowed, so resets it to previous text and show warning
+ if (which->get_text(0).strip_edges().empty()) {
+ which->set_text(0, n->get_name());
+ EditorNode::get_singleton()->show_warning(TTR("No name provided"));
+ return;
+ }
+
String new_name = which->get_text(0);
if (!Node::_validate_node_name(new_name)) {
diff --git a/gles_builders.py b/gles_builders.py
index 1e63a53f1a..f9fd6d3fa2 100644
--- a/gles_builders.py
+++ b/gles_builders.py
@@ -59,11 +59,11 @@ def include_file_in_legacygl_header(filename, header_data, depth):
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
header_data.vertex_included_files += [included_file]
- if include_file_in_legacygl_header(included_file, header_data, depth + 1) == None:
+ if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
header_data.fragment_included_files += [included_file]
- if include_file_in_legacygl_header(included_file, header_data, depth + 1) == None:
+ if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
line = fs.readline()
diff --git a/methods.py b/methods.py
index 0cf05751a8..111a2347be 100644
--- a/methods.py
+++ b/methods.py
@@ -330,7 +330,7 @@ def split_lib(self, libname, src_list = None, env_lib = None):
list = []
lib_list = []
- if src_list == None:
+ if src_list is None:
src_list = getattr(env, libname + "_sources")
if type(env_lib) == type(None):
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index ecde73ae1c..283e9b3bc8 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -306,6 +306,13 @@ bool GDNative::initialize() {
#elif defined(UWP_ENABLED)
// On UWP we use a relative path from the app
String path = lib_path.replace("res://", "");
+#elif defined(OSX_ENABLED)
+ // On OSX the exported libraries are located under the Frameworks directory.
+ // So we need to replace the library path.
+ String path = ProjectSettings::get_singleton()->globalize_path(lib_path);
+ if (!FileAccess::exists(path)) {
+ path = OS::get_singleton()->get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(lib_path.get_file());
+ }
#else
String path = ProjectSettings::get_singleton()->globalize_path(lib_path);
#endif
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 1fb0ff0500..a30cc09bf6 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -318,6 +318,38 @@ void GDAPI godot_array_destroy(godot_array *p_self) {
((Array *)p_self)->~Array();
}
+godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep) {
+ const Array *self = (const Array *)p_self;
+ godot_array res;
+ Array *val = (Array *)&res;
+ memnew_placement(val, Array);
+ *val = self->duplicate(p_deep);
+ return res;
+}
+
+godot_variant GDAPI godot_array_max(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
+ godot_variant v;
+ Variant *val = (Variant *)&v;
+ memnew_placement(val, Variant);
+ *val = self->max();
+ return v;
+}
+
+godot_variant GDAPI godot_array_min(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
+ godot_variant v;
+ Variant *val = (Variant *)&v;
+ memnew_placement(val, Variant);
+ *val = self->min();
+ return v;
+}
+
+void GDAPI godot_array_shuffle(godot_array *p_self) {
+ Array *self = (Array *)p_self;
+ self->shuffle();
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index 70d2814577..d88499ade1 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -282,6 +282,15 @@ godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self
return raw_dest;
}
+godot_basis GDAPI godot_basis_slerp(const godot_basis *p_self, const godot_basis *p_b, const godot_real p_t) {
+ godot_basis raw_dest;
+ Basis *dest = (Basis *)&raw_dest;
+ const Basis *self = (const Basis *)p_self;
+ const Basis *b = (const Basis *)p_b;
+ *dest = self->slerp(*b, p_t);
+ return raw_dest;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp
index 4089f4458a..79f0c71b5e 100644
--- a/modules/gdnative/gdnative/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -116,6 +116,26 @@ godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self) {
return self->to_rgba32();
}
+godot_int GDAPI godot_color_to_abgr32(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->to_abgr32();
+}
+
+godot_int GDAPI godot_color_to_abgr64(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->to_abgr64();
+}
+
+godot_int GDAPI godot_color_to_argb64(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->to_argb64();
+}
+
+godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->to_rgba64();
+}
+
godot_int GDAPI godot_color_to_argb32(const godot_color *p_self) {
const Color *self = (const Color *)p_self;
return self->to_argb32();
@@ -156,6 +176,27 @@ godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color
return dest;
}
+godot_color GDAPI godot_color_darkened(const godot_color *p_self, const godot_real p_amount) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ *((Color *)&dest) = self->darkened(p_amount);
+ return dest;
+}
+
+godot_color GDAPI godot_color_from_hsv(const godot_color *p_self, const godot_real p_h, const godot_real p_s, const godot_real p_v, const godot_real p_a) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ *((Color *)&dest) = self->from_hsv(p_h, p_s, p_v, p_a);
+ return dest;
+}
+
+godot_color GDAPI godot_color_lightened(const godot_color *p_self, const godot_real p_amount) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ *((Color *)&dest) = self->lightened(p_amount);
+ return dest;
+}
+
godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha) {
godot_string dest;
const Color *self = (const Color *)p_self;
diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp
index f24facaae8..cf82940e09 100644
--- a/modules/gdnative/gdnative/node_path.cpp
+++ b/modules/gdnative/gdnative/node_path.cpp
@@ -110,6 +110,15 @@ godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, c
return *self == *b;
}
+godot_node_path godot_node_path_get_as_property_path(const godot_node_path *p_self) {
+ const NodePath *self = (const NodePath *)p_self;
+ godot_node_path res;
+ NodePath *val = (NodePath *)&res;
+ memnew_placement(val, NodePath);
+ *val = self->get_as_property_path();
+ return res;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index ddec77edcd..2594759508 100644
--- a/modules/gdnative/gdnative/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -225,6 +225,12 @@ godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self) {
return raw_dest;
}
+void GDAPI godot_quat_set_axis_angle(godot_quat *p_self, const godot_vector3 *p_axis, const godot_real p_angle) {
+ Quat *self = (Quat *)p_self;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ self->set_axis_angle(*axis, p_angle);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp
index 54b98fc4e5..5cbc2712c3 100644
--- a/modules/gdnative/gdnative/rect2.cpp
+++ b/modules/gdnative/gdnative/rect2.cpp
@@ -109,6 +109,27 @@ godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p
return dest;
}
+godot_rect2 GDAPI godot_rect2_grow_individual(const godot_rect2 *p_self, const godot_real p_left, const godot_real p_top, const godot_real p_right, const godot_real p_bottom) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ *((Rect2 *)&dest) = self->grow_individual(p_left, p_top, p_right, p_bottom);
+ return dest;
+}
+
+godot_rect2 GDAPI godot_rect2_grow_margin(const godot_rect2 *p_self, const godot_int p_margin, const godot_real p_by) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ *((Rect2 *)&dest) = self->grow_margin((Margin)p_margin, p_by);
+ return dest;
+}
+
+godot_rect2 GDAPI godot_rect2_abs(const godot_rect2 *p_self) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ *((Rect2 *)&dest) = self->abs();
+ return dest;
+}
+
godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to) {
godot_rect2 dest;
const Rect2 *self = (const Rect2 *)p_self;
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 8ca57392a3..0996633b70 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -1285,6 +1285,64 @@ godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self) {
return self->is_valid_ip_address();
}
+godot_string GDAPI godot_string_dedent(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+ godot_string result;
+ String return_value = self->dedent();
+ memnew_placement(&result, String(return_value));
+
+ return result;
+}
+
+godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix) {
+ const String *self = (const String *)p_self;
+ String *prefix = (String *)p_prefix;
+ godot_string result;
+ String return_value = self->trim_prefix(*prefix);
+ memnew_placement(&result, String(return_value));
+
+ return result;
+}
+
+godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix) {
+ const String *self = (const String *)p_self;
+ String *suffix = (String *)p_suffix;
+ godot_string result;
+ String return_value = self->trim_suffix(*suffix);
+ memnew_placement(&result, String(return_value));
+
+ return result;
+}
+
+godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars) {
+ const String *self = (const String *)p_self;
+ String *chars = (String *)p_chars;
+ godot_string result;
+ String return_value = self->rstrip(*chars);
+ memnew_placement(&result, String(return_value));
+
+ return result;
+}
+
+godot_pool_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor,
+ const godot_bool p_allow_empty, const godot_int p_maxsplit) {
+ const String *self = (const String *)p_self;
+ String *divisor = (String *)p_divisor;
+
+ godot_pool_string_array result;
+ memnew_placement(&result, PoolStringArray);
+ PoolStringArray *proxy = (PoolStringArray *)&result;
+ PoolStringArray::Write proxy_writer = proxy->write();
+ Vector<String> tmp_result = self->rsplit(*divisor, p_allow_empty, p_maxsplit);
+ proxy->resize(tmp_result.size());
+
+ for (int i = 0; i < tmp_result.size(); i++) {
+ proxy_writer[i] = tmp_result[i];
+ }
+
+ return result;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 16a34a9a33..c5a1fa139e 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -14,6 +14,183 @@
"next": null,
"api": [
{
+ "name": "godot_color_to_abgr32",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_to_abgr64",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_to_argb64",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_to_rgba64",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_color *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_color_darkened",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_real", "p_amount"]
+ ]
+ },
+ {
+ "name": "godot_color_from_hsv",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_real", "p_h"],
+ ["const godot_real", "p_s"],
+ ["const godot_real", "p_v"],
+ ["const godot_real", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_color_lightened",
+ "return_type": "godot_color",
+ "arguments": [
+ ["const godot_color *", "p_self"],
+ ["const godot_real", "p_amount"]
+ ]
+ },
+ {
+ "name": "godot_array_duplicate",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_bool", "p_deep"]
+ ]
+ },
+ {
+ "name": "godot_array_max",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_min",
+ "return_type": "godot_variant",
+ "arguments": [
+ ["const godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_array_shuffle",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_slerp",
+ "return_type": "godot_basis",
+ "arguments": [
+ ["const godot_basis *", "p_self"],
+ ["const godot_basis *", "p_b"],
+ ["const godot_real", "p_t"]
+ ]
+ },
+ {
+ "name": "godot_node_path_get_as_property_path",
+ "return_type": "godot_node_path",
+ "arguments": [
+ ["const godot_node_path *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_quat_set_axis_angle",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "p_self"],
+ ["const godot_vector3 *", "p_axis"],
+ ["const godot_real", "p_angle"]
+ ]
+ },
+ {
+ "name": "godot_rect2_grow_individual",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_real", "p_left"],
+ ["const godot_real", "p_top"],
+ ["const godot_real", "p_right"],
+ ["const godot_real", "p_bottom"]
+ ]
+ },
+ {
+ "name": "godot_rect2_grow_margin",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"],
+ ["const godot_int", "p_margin"],
+ ["const godot_real", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_rect2_abs",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_dedent",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_trim_prefix",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_prefix"]
+ ]
+ },
+ {
+ "name": "godot_string_trim_suffix",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_suffix"]
+ ]
+ },
+ {
+ "name": "godot_string_rstrip",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_chars"]
+ ]
+ },
+ {
+ "name": "godot_string_rsplit",
+ "return_type": "godot_pool_string_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_divisor"],
+ ["const godot_bool", "p_allow_empty"],
+ ["const godot_int", "p_maxsplit"]
+ ]
+ },
+ {
"name": "godot_basis_get_quat",
"return_type": "godot_quat",
"arguments": [
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index 1e66d133b9..876b8f8e8f 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -130,6 +130,14 @@ godot_int GDAPI godot_array_bsearch_custom(godot_array *p_self, const godot_vari
void GDAPI godot_array_destroy(godot_array *p_self);
+godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep);
+
+godot_variant GDAPI godot_array_max(const godot_array *p_self);
+
+godot_variant GDAPI godot_array_min(const godot_array *p_self);
+
+void GDAPI godot_array_shuffle(godot_array *p_self);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h
index ebe2b1125b..6128bf3ac3 100644
--- a/modules/gdnative/include/gdnative/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -127,6 +127,8 @@ godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self
godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b);
+godot_basis GDAPI godot_basis_slerp(const godot_basis *p_self, const godot_basis *p_b, const godot_real p_t);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index 1f0ac8354d..3007dbc6e3 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -81,6 +81,14 @@ godot_string GDAPI godot_color_as_string(const godot_color *p_self);
godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self);
+godot_int GDAPI godot_color_to_abgr32(const godot_color *p_self);
+
+godot_int GDAPI godot_color_to_abgr64(const godot_color *p_self);
+
+godot_int GDAPI godot_color_to_argb64(const godot_color *p_self);
+
+godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self);
+
godot_int GDAPI godot_color_to_argb32(const godot_color *p_self);
godot_real GDAPI godot_color_gray(const godot_color *p_self);
@@ -93,6 +101,12 @@ godot_color GDAPI godot_color_linear_interpolate(const godot_color *p_self, cons
godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over);
+godot_color GDAPI godot_color_darkened(const godot_color *p_self, const godot_real p_amount);
+
+godot_color GDAPI godot_color_from_hsv(const godot_color *p_self, const godot_real p_h, const godot_real p_s, const godot_real p_v, const godot_real p_a);
+
+godot_color GDAPI godot_color_lightened(const godot_color *p_self, const godot_real p_amount);
+
godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha);
godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b);
diff --git a/modules/gdnative/include/gdnative/node_path.h b/modules/gdnative/include/gdnative/node_path.h
index 2b55e01d13..48fe5b4d3d 100644
--- a/modules/gdnative/include/gdnative/node_path.h
+++ b/modules/gdnative/include/gdnative/node_path.h
@@ -80,6 +80,8 @@ godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self);
godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b);
+godot_node_path godot_node_path_get_as_property_path(const godot_node_path *p_self);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h
index b1290f745c..634f486e66 100644
--- a/modules/gdnative/include/gdnative/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -109,6 +109,8 @@ godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot
godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self);
+void GDAPI godot_quat_set_axis_angle(godot_quat *p_self, const godot_vector3 *p_axis, const godot_real p_angle);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h
index 4adcb73e3d..47c15c80bd 100644
--- a/modules/gdnative/include/gdnative/rect2.h
+++ b/modules/gdnative/include/gdnative/rect2.h
@@ -77,6 +77,12 @@ godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_ve
godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by);
+godot_rect2 GDAPI godot_rect2_grow_individual(const godot_rect2 *p_self, const godot_real p_left, const godot_real p_top, const godot_real p_right, const godot_real p_bottom);
+
+godot_rect2 GDAPI godot_rect2_grow_margin(const godot_rect2 *p_self, const godot_int p_margin, const godot_real p_by);
+
+godot_rect2 GDAPI godot_rect2_abs(const godot_rect2 *p_self);
+
godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to);
godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b);
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index 73245160c1..95ae42a9ec 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -246,6 +246,12 @@ godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self);
godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self);
godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self);
+godot_string GDAPI godot_string_dedent(const godot_string *p_self);
+godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix);
+godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix);
+godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars);
+godot_pool_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor, const godot_bool p_allow_empty, const godot_int p_maxsplit);
+
void GDAPI godot_string_destroy(godot_string *p_self);
#ifdef __cplusplus
diff --git a/modules/mono/glue/Managed/Files/GD.cs b/modules/mono/glue/Managed/Files/GD.cs
index e4818e186c..8c1a5a6ee8 100644
--- a/modules/mono/glue/Managed/Files/GD.cs
+++ b/modules/mono/glue/Managed/Files/GD.cs
@@ -70,6 +70,16 @@ namespace Godot
return ResourceLoader.Load<T>(path);
}
+ public static void LogError(string message)
+ {
+ godot_icall_GD_logerror(message);
+ }
+
+ public static void LogWarning(string message)
+ {
+ godot_icall_GD_logwarning(message);
+ }
+
public static void Print(params object[] what)
{
godot_icall_GD_print(what);
@@ -238,5 +248,11 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static string godot_icall_GD_var2str(object var);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_logerror(string type);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_logwarning(string type);
}
}
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 051f42b966..6a5430489e 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -157,6 +157,14 @@ bool godot_icall_GD_type_exists(MonoString *p_type) {
return ClassDB::class_exists(GDMonoMarshal::mono_string_to_godot(p_type));
}
+void godot_icall_GD_logerror(MonoString *p_str) {
+ ERR_PRINTS(GDMonoMarshal::mono_string_to_godot(p_str));
+}
+
+void godot_icall_GD_logwarning(MonoString *p_str) {
+ WARN_PRINTS(GDMonoMarshal::mono_string_to_godot(p_str));
+}
+
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var) {
Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
@@ -186,6 +194,8 @@ void godot_register_gd_icalls() {
mono_add_internal_call("Godot.GD::godot_icall_GD_convert", (void *)godot_icall_GD_convert);
mono_add_internal_call("Godot.GD::godot_icall_GD_hash", (void *)godot_icall_GD_hash);
mono_add_internal_call("Godot.GD::godot_icall_GD_instance_from_id", (void *)godot_icall_GD_instance_from_id);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_logerror", (void *)godot_icall_GD_logerror);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_logwarning", (void *)godot_icall_GD_logwarning);
mono_add_internal_call("Godot.GD::godot_icall_GD_print", (void *)godot_icall_GD_print);
mono_add_internal_call("Godot.GD::godot_icall_GD_printerr", (void *)godot_icall_GD_printerr);
mono_add_internal_call("Godot.GD::godot_icall_GD_printraw", (void *)godot_icall_GD_printraw);
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 7fdd7fe446..a80a015ed3 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -3018,11 +3018,15 @@ void VisualScriptEditor::_node_filter_changed(const String &p_text) {
void VisualScriptEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
+ if (p_what == NOTIFICATION_READY || (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree())) {
+
node_filter->set_right_icon(Control::get_icon("Search", "EditorIcons"));
node_filter->set_clear_button_enabled(true);
- variable_editor->connect("changed", this, "_update_members");
- signal_editor->connect("changed", this, "_update_members");
+
+ if (p_what == NOTIFICATION_READY) {
+ variable_editor->connect("changed", this, "_update_members");
+ signal_editor->connect("changed", this, "_update_members");
+ }
Ref<Theme> tm = EditorNode::get_singleton()->get_theme_base()->get_theme();
@@ -3056,8 +3060,12 @@ void VisualScriptEditor::_notification(int p_what) {
node_styles[E->get().first] = frame_style;
}
}
- }
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+
+ if (is_visible_in_tree()) {
+ _update_members();
+ _update_graph();
+ }
+ } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
left_vsplit->set_visible(is_visible_in_tree());
}
}
diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template
index 1603ea70d9..18ffc74fc3 100644
--- a/platform/android/build.gradle.template
+++ b/platform/android/build.gradle.template
@@ -14,9 +14,9 @@ apply plugin: 'com.android.application'
allprojects {
repositories {
- jcenter()
mavenCentral()
google()
+ jcenter()
$$GRADLE_REPOSITORY_URLS$$
}
}
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 953a2fa6d2..e4cab2fb23 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -186,7 +186,7 @@ def configure(env):
env.PrependENVPath('PATH', tools_path)
ccache_path = os.environ.get("CCACHE")
- if ccache_path == None:
+ if ccache_path is None:
env['CC'] = compiler_path + '/clang'
env['CXX'] = compiler_path + '/clang++'
else:
@@ -293,7 +293,7 @@ def configure(env):
# Return NDK version string in source.properties (adapted from the Chromium project).
def get_ndk_version(path):
- if path == None:
+ if path is None:
return None
prop_file_path = os.path.join(path, "source.properties")
try:
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index ab37f7a02c..88194f00d1 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -279,7 +279,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
// ...add to FrameLayout
layout.addView(edittext);
- mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, use_debug_opengl,this);
+ mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, use_debug_opengl, this);
layout.addView(mView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
edittext.setView(mView);
io.setEdit(edittext);
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index 181ffc3b4b..4cb4db33de 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -86,7 +86,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
private Godot activity;
private InputManagerCompat mInputManager;
- public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl,Godot p_activity) {
+ public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl, Godot p_activity) {
super(context);
ctx = context;
io = p_io;
@@ -204,48 +204,65 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
return i;
}
}
- onInputDeviceAdded(device_id);
- return joy_devices.size() - 1;
+
+ return -1;
}
@Override
public void onInputDeviceAdded(int deviceId) {
- joystick joy = new joystick();
- joy.device_id = deviceId;
- final int id = joy_devices.size();
- InputDevice device = mInputManager.getInputDevice(deviceId);
- final String name = device.getName();
- joy.name = device.getName();
- joy.axes = new ArrayList<InputDevice.MotionRange>();
- joy.hats = new ArrayList<InputDevice.MotionRange>();
- List<InputDevice.MotionRange> ranges = device.getMotionRanges();
- Collections.sort(ranges, new RangeComparator());
- for (InputDevice.MotionRange range : ranges) {
- if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
- joy.hats.add(range);
- } else {
- joy.axes.add(range);
+ int id = find_joy_device(deviceId);
+
+ // Check if the device has not been already added
+ if (id < 0) {
+ InputDevice device = mInputManager.getInputDevice(deviceId);
+
+ id = joy_devices.size();
+
+ joystick joy = new joystick();
+ joy.device_id = deviceId;
+ joy.name = device.getName();
+ joy.axes = new ArrayList<InputDevice.MotionRange>();
+ joy.hats = new ArrayList<InputDevice.MotionRange>();
+
+ List<InputDevice.MotionRange> ranges = device.getMotionRanges();
+ Collections.sort(ranges, new RangeComparator());
+
+ for (InputDevice.MotionRange range : ranges) {
+ if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
+ joy.hats.add(range);
+ } else {
+ joy.axes.add(range);
+ }
}
+
+ joy_devices.add(joy);
+
+ final int device_id = id;
+ final String name = joy.name;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(device_id, true, name);
+ }
+ });
}
- joy_devices.add(joy);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(id, true, name);
- }
- });
}
@Override
public void onInputDeviceRemoved(int deviceId) {
- final int id = find_joy_device(deviceId);
- joy_devices.remove(id);
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(id, false, "");
- }
- });
+ final int device_id = find_joy_device(deviceId);
+
+ // Check if the evice has not been already removed
+ if (device_id > -1) {
+ joy_devices.remove(device_id);
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(device_id, false, "");
+ }
+ });
+ }
}
@Override
@@ -266,15 +283,18 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
if ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) {
final int button = get_godot_button(keyCode);
- final int device = find_joy_device(event.getDeviceId());
+ final int device_id = find_joy_device(event.getDeviceId());
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joybutton(device, button, false);
- }
- });
- return true;
+ // Check if the device exists
+ if (device_id > -1) {
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joybutton(device_id, button, false);
+ }
+ });
+ return true;
+ }
} else {
final int chr = event.getUnicodeChar(0);
queueEvent(new Runnable() {
@@ -284,6 +304,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
}
});
};
+
return super.onKeyUp(keyCode, event);
};
@@ -308,18 +329,20 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
if (event.getRepeatCount() > 0) // ignore key echo
return true;
- final int button = get_godot_button(keyCode);
- final int device = find_joy_device(event.getDeviceId());
- //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device));
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joybutton(device, button, true);
- }
- });
- return true;
+ final int button = get_godot_button(keyCode);
+ final int device_id = find_joy_device(event.getDeviceId());
+ // Check if the device exists
+ if (device_id > -1) {
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joybutton(device_id, button, true);
+ }
+ });
+ return true;
+ }
} else {
final int chr = event.getUnicodeChar(0);
queueEvent(new Runnable() {
@@ -329,6 +352,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
}
});
};
+
return super.onKeyDown(keyCode, event);
}
@@ -338,33 +362,35 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
final int device_id = find_joy_device(event.getDeviceId());
- joystick joy = joy_devices.get(device_id);
- for (int i = 0; i < joy.axes.size(); i++) {
- InputDevice.MotionRange range = joy.axes.get(i);
- final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
- //Log.e(TAG, String.format("axis event: %d, value %f", i, value));
- final int idx = i;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyaxis(device_id, idx, value);
- }
- });
- }
+ // Check if the device exists
+ if (device_id > -1) {
+ joystick joy = joy_devices.get(device_id);
+
+ for (int i = 0; i < joy.axes.size(); i++) {
+ InputDevice.MotionRange range = joy.axes.get(i);
+ final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
+ final int idx = i;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyaxis(device_id, idx, value);
+ }
+ });
+ }
- for (int i = 0; i < joy.hats.size(); i += 2) {
- final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
- final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis()));
- //Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY));
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyhat(device_id, hatX, hatY);
- }
- });
+ for (int i = 0; i < joy.hats.size(); i += 2) {
+ final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
+ final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis()));
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyhat(device_id, hatX, hatY);
+ }
+ });
+ }
+ return true;
}
- return true;
};
return super.onGenericMotionEvent(event);
@@ -408,9 +434,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
setRenderer(new Renderer());
}
- private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC;
- private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR= 0x00000001;
-
+ private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC;
+ private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR = 0x00000001;
+
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
@@ -422,9 +448,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
checkEglError("Before eglCreateContext", egl);
EGLContext context;
if (use_debug_opengl) {
- int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2,_EGL_CONTEXT_FLAGS_KHR,_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
- int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3,_EGL_CONTEXT_FLAGS_KHR,_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
- context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
+ int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
+ int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
+ context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
} else {
int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index b13a1e9643..417571f6f3 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -87,7 +87,7 @@ def configure(env):
s_compiler_path = '$IPHONEPATH/Developer/usr/bin/'
ccache_path = os.environ.get("CCACHE")
- if ccache_path == None:
+ if ccache_path is None:
env['CC'] = compiler_path + 'clang'
env['CXX'] = compiler_path + 'clang++'
env['S_compiler'] = s_compiler_path + 'gcc'
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 17b31f8d73..cf85c3df7f 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -128,6 +128,10 @@ def configure(env):
# us since we don't know requirements at compile-time.
env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1'])
+ # Since we use both memory growth and MEMFS preloading,
+ # this avoids unecessary copying on start-up.
+ env.Append(LINKFLAGS=['--no-heap-copy'])
+
# This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1'])
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 7c7aeac980..9250ca4903 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -862,6 +862,24 @@ void OS_JavaScript::finalize() {
// Miscellaneous
+Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) {
+
+ ERR_EXPLAIN("OS::execute() is not available on the HTML5 platform");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+}
+
+Error OS_JavaScript::kill(const ProcessID &p_pid) {
+
+ ERR_EXPLAIN("OS::kill() is not available on the HTML5 platform");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+}
+
+int OS_JavaScript::get_process_id() const {
+
+ ERR_EXPLAIN("OS::get_process_id() is not available on the HTML5 platform");
+ ERR_FAIL_V(0);
+}
+
extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int p_notification) {
if (p_notification == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || p_notification == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) {
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 84075898ac..79dac5940f 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -133,6 +133,10 @@ public:
void run_async();
bool main_loop_iterate();
+ 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, bool read_stderr = false);
+ virtual Error kill(const ProcessID &p_pid);
+ virtual int get_process_id() const;
+
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_window_title(const String &p_title);
virtual void set_icon(const Ref<Image> &p_icon);
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 8a0883eca3..c5bd64b15c 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -89,7 +89,7 @@ def configure(env):
basecmd = root + "/target/bin/x86_64-apple-" + env["osxcross_sdk"] + "-"
ccache_path = os.environ.get("CCACHE")
- if ccache_path == None:
+ if ccache_path is None:
env['CC'] = basecmd + "cc"
env['CXX'] = basecmd + "c++"
else:
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 6fd52f09d1..546c88e74a 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -74,8 +74,12 @@ public:
IP_Unix *ip_unix;
+#ifdef COREAUDIO_ENABLED
AudioDriverCoreAudio audio_driver;
+#endif
+#ifdef COREMIDI_ENABLED
MIDIDriverCoreMidi midi_driver;
+#endif
InputDefault *input;
JoypadOSX *joypad_osx;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 70b49805d2..b84e22f53c 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -331,7 +331,8 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
get_mouse_pos(
[OS_OSX::singleton->window_object mouseLocationOutsideOfEventStream],
[OS_OSX::singleton->window_view backingScaleFactor]);
- OS_OSX::singleton->input->set_mouse_position(Point2(mouse_x, mouse_y));
+ if (OS_OSX::singleton->input)
+ OS_OSX::singleton->input->set_mouse_position(Point2(mouse_x, mouse_y));
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
@@ -1408,7 +1409,9 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
void OS_OSX::finalize() {
+#ifdef COREMIDI_ENABLED
midi_driver.close();
+#endif
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);
@@ -2725,7 +2728,9 @@ OS_OSX::OS_OSX() {
[NSApp sendEvent:event];
}
+#ifdef COREAUDIO_ENABLED
AudioDriverManager::add_driver(&audio_driver);
+#endif
}
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
diff --git a/platform/server/SCsub b/platform/server/SCsub
index c9082f9b3a..51fd05a87e 100644
--- a/platform/server/SCsub
+++ b/platform/server/SCsub
@@ -1,10 +1,21 @@
#!/usr/bin/env python
+import os
+import platform
+import sys
+
Import('env')
common_server = [\
"os_server.cpp",\
- "#platform/x11/crash_handler_x11.cpp",
- "#platform/x11/power_x11.cpp",
]
+
+if sys.platform == "darwin":
+ common_server.append("#platform/osx/crash_handler_osx.mm")
+ common_server.append("#platform/osx/power_osx.cpp")
+ common_server.append("#platform/osx/sem_osx.cpp")
+else:
+ common_server.append("#platform/x11/crash_handler_x11.cpp")
+ common_server.append("#platform/x11/power_x11.cpp")
+
prog = env.add_program('#bin/godot_server', ['godot_server.cpp'] + common_server)
diff --git a/platform/server/detect.py b/platform/server/detect.py
index 597a2ff6a0..0b23e9c649 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -11,9 +11,15 @@ def get_name():
return "Server"
+def get_program_suffix():
+ if (sys.platform == "darwin"):
+ return "osx"
+ return "x11"
+
+
def can_build():
- if (os.name != "posix" or sys.platform == "darwin"):
+ if (os.name != "posix"):
return False
return True
@@ -147,6 +153,10 @@ def configure(env):
env.Append(CPPPATH=['#platform/server'])
env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED'])
+
+ if (platform.system() == "Darwin"):
+ env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-lz', '-framework', 'IOKit'])
+
env.Append(LIBS=['pthread'])
if (platform.system() == "Linux"):
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 6a7038e946..60f20d6009 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -68,6 +68,10 @@ void OS_Server::initialize_core() {
crash_handler.initialize();
OS_Unix::initialize_core();
+
+#ifdef __APPLE__
+ SemaphoreOSX::make_default();
+#endif
}
Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
@@ -87,7 +91,11 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
input = memnew(InputDefault);
+#ifdef __APPLE__
+ power_manager = memnew(power_osx);
+#else
power_manager = memnew(PowerX11);
+#endif
_ensure_user_data_dir();
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 07d70e5236..0367ec3db9 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -34,8 +34,14 @@
#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/unix/os_unix.h"
#include "main/input_default.h"
+#ifdef __APPLE__
+#include "platform/osx/crash_handler_osx.h"
+#include "platform/osx/power_osx.h"
+#include "platform/osx/sem_osx.h"
+#else
#include "platform/x11/crash_handler_x11.h"
#include "platform/x11/power_x11.h"
+#endif
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
@@ -61,7 +67,11 @@ class OS_Server : public OS_Unix {
InputDefault *input;
+#ifdef __APPLE__
+ power_osx *power_manager;
+#else
PowerX11 *power_manager;
+#endif
CrashHandler crash_handler;
diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h
index 2fa8eda337..26ba8f26c6 100644
--- a/platform/server/platform_config.h
+++ b/platform/server/platform_config.h
@@ -28,10 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
#include <alloca.h>
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__)
#include <stdlib.h>
#define PTHREAD_BSD_SET_NAME
#endif
+#ifdef __APPLE__
+#define PTHREAD_RENAME_SELF
+#endif
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 559f23ca5b..f25b9ba9cd 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -17,7 +17,7 @@ def can_build():
# building natively on windows!
if (os.getenv("VSINSTALLDIR")):
- if (os.getenv("ANGLE_SRC_PATH") == None):
+ if (os.getenv("ANGLE_SRC_PATH") is None):
return False
return True
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index bb56eea98e..d996132960 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1429,9 +1429,6 @@ void TextEdit::_notification(int p_what) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect());
- if (raised_from_completion) {
- VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1);
- }
} break;
case NOTIFICATION_FOCUS_EXIT: {
@@ -1443,9 +1440,6 @@ void TextEdit::_notification(int p_what) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard();
- if (raised_from_completion) {
- VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0);
- }
} break;
}
}
@@ -5666,16 +5660,12 @@ void TextEdit::_confirm_completion() {
void TextEdit::_cancel_code_hint() {
- VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0);
- raised_from_completion = false;
completion_hint = "";
update();
}
void TextEdit::_cancel_completion() {
- VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 0);
- raised_from_completion = false;
if (!completion_active)
return;
@@ -5833,8 +5823,6 @@ void TextEdit::query_code_comple() {
void TextEdit::set_code_hint(const String &p_hint) {
- VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1);
- raised_from_completion = true;
completion_hint = p_hint;
completion_hint_offset = -0xFFFF;
update();
@@ -5842,8 +5830,6 @@ void TextEdit::set_code_hint(const String &p_hint) {
void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) {
- VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1);
- raised_from_completion = true;
completion_strings = p_strings;
completion_active = true;
completion_forced = p_forced;
@@ -6346,8 +6332,6 @@ TextEdit::TextEdit() {
target_v_scroll = 0;
v_scroll_speed = 80;
- raised_from_completion = false;
-
context_menu_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index f0c18ad047..8a508a8738 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -306,8 +306,6 @@ private:
float target_v_scroll;
float v_scroll_speed;
- bool raised_from_completion;
-
String highlighted_word;
uint64_t last_dblclk;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 50e94e6db5..9f234f832d 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1835,7 +1835,7 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) {
}
}
-bool Node::is_editable_instance(Node *p_node) const {
+bool Node::is_editable_instance(const Node *p_node) const {
if (!p_node)
return false; //easier, null is never editable :)
diff --git a/scene/main/node.h b/scene/main/node.h
index a7baebc9c2..78db12dda9 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -303,7 +303,7 @@ public:
String get_filename() const;
void set_editable_instance(Node *p_node, bool p_editable);
- bool is_editable_instance(Node *p_node) const;
+ bool is_editable_instance(const Node *p_node) const;
void set_editable_instances(const HashMap<NodePath, int> &p_editable_instances);
HashMap<NodePath, int> get_editable_instances() const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 274c74a9a2..c3030ee741 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -614,7 +614,7 @@ void SpatialMaterial::_update_shader() {
code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0.0,particle_total_frames-1.0); else particle_frame=mod(particle_frame,float(particle_total_frames));\n";
code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n";
- code += "\tUV += vec2(mod(particle_frame,float(particles_anim_h_frames)) / float(particles_anim_h_frames),particle_frame / float(particles_anim_h_frames) / float(particles_anim_v_frames));\n";
+ code += "\tUV += vec2(mod(particle_frame,float(particles_anim_h_frames)) / float(particles_anim_h_frames), floor(particle_frame / float(particles_anim_h_frames)) / float(particles_anim_v_frames));\n";
} break;
}
diff --git a/thirdparty/libwebsockets/lws_config.h b/thirdparty/libwebsockets/lws_config.h
index e5e15cc2fd..86ce9ac38a 100644
--- a/thirdparty/libwebsockets/lws_config.h
+++ b/thirdparty/libwebsockets/lws_config.h
@@ -174,7 +174,7 @@
#define LWS_HAVE_MALLOC_H
#endif
-#if !defined(IPHONE_ENABLED) && !defined(OSX_ENABLED) && !defined(__HAIKU__)
+#if !defined(__APPLE__) && !defined(__HAIKU__)
#define LWS_HAVE_PIPE2
#endif
diff --git a/thirdparty/libwebsockets/lws_config_private.h b/thirdparty/libwebsockets/lws_config_private.h
index b26d225afa..e531777624 100644
--- a/thirdparty/libwebsockets/lws_config_private.h
+++ b/thirdparty/libwebsockets/lws_config_private.h
@@ -81,7 +81,7 @@
/* Define to 1 if you have the <sys/prctl.h> header file. */
#define LWS_HAVE_SYS_PRCTL_H
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
#undef LWS_HAVE_SYS_PRCTL_H
#endif