Browse Source

-Changed Godot exit to be clean.
-Added more debug information on memory cleanliness on exit (if run with -v)
-Fixed several memory leaks, fixes #1731, fixes #755

Juan Linietsky 10 years ago
parent
commit
59154cccf9
37 changed files with 263 additions and 68 deletions
  1. 7 1
      bin/tests/test_render.cpp
  2. 1 0
      core/io/file_access_network.cpp
  3. 15 0
      core/io/file_access_pack.cpp
  4. 4 0
      core/io/file_access_pack.h
  5. 1 1
      core/io/file_access_zip.cpp
  6. 14 1
      core/object.cpp
  7. 4 2
      core/register_core_types.cpp
  8. 16 2
      core/string_db.cpp
  9. 5 1
      drivers/gles2/rasterizer_gles2.cpp
  10. 14 1
      main/main.cpp
  11. 15 10
      modules/gridmap/grid_map_editor_plugin.cpp
  12. 7 0
      modules/gridmap/grid_map_editor_plugin.h
  13. 3 0
      platform/android/export/export.cpp
  14. 2 0
      platform/bb10/export/export.cpp
  15. 7 0
      platform/x11/detect.py
  16. 3 0
      platform/x11/os_x11.cpp
  17. 2 1
      platform/x11/os_x11.h
  18. 2 1
      scene/2d/camera_2d.cpp
  19. 0 1
      scene/2d/canvas_item.cpp
  20. 1 0
      scene/main/viewport.cpp
  21. 1 0
      servers/visual/rasterizer.h
  22. 7 3
      servers/visual/visual_server_raster.cpp
  23. 26 7
      servers/visual_server.cpp
  24. 2 0
      servers/visual_server.h
  25. 2 2
      tools/editor/animation_editor.cpp
  26. 8 0
      tools/editor/editor_import_export.cpp
  27. 1 0
      tools/editor/editor_import_export.h
  28. 13 8
      tools/editor/editor_node.cpp
  29. 2 0
      tools/editor/fileserver/editor_file_server.cpp
  30. 2 1
      tools/editor/io_plugins/editor_font_import_plugin.cpp
  31. 1 0
      tools/editor/plugins/baked_light_baker.cpp
  32. 31 8
      tools/editor/plugins/canvas_item_editor_plugin.cpp
  33. 4 1
      tools/editor/plugins/canvas_item_editor_plugin.h
  34. 2 1
      tools/editor/plugins/sample_library_editor_plugin.cpp
  35. 29 12
      tools/editor/plugins/spatial_editor_plugin.cpp
  36. 3 0
      tools/editor/plugins/spatial_editor_plugin.h
  37. 6 3
      tools/editor/project_settings.cpp

+ 7 - 1
bin/tests/test_render.cpp

@@ -33,6 +33,8 @@
 #include "print_string.h"
 #include "print_string.h"
 #include "os/os.h"
 #include "os/os.h"
 #include "quick_hull.h"
 #include "quick_hull.h"
+#include "os/keyboard.h"
+
 #define OBJECT_COUNT 50
 #define OBJECT_COUNT 50
 
 
 namespace TestRender {
 namespace TestRender {
@@ -59,10 +61,14 @@ class TestMainLoop : public MainLoop {
 	
 	
 	float ofs;
 	float ofs;
 	bool quit;
 	bool quit;
+protected:
+
+
 public:
 public:
 	virtual void input_event(const InputEvent& p_event) {
 	virtual void input_event(const InputEvent& p_event) {
 	
 	
-		
+		if (p_event.type==InputEvent::KEY && p_event.key.pressed)
+			quit=true;
 	}
 	}
 
 
 	virtual void init() {
 	virtual void init() {

+ 1 - 0
core/io/file_access_network.cpp

@@ -254,6 +254,7 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
 		quit=true;
 		quit=true;
 		sem->post();
 		sem->post();
 		Thread::wait_to_finish(thread);
 		Thread::wait_to_finish(thread);
+		memdelete(thread);
 	}
 	}
 
 
 	memdelete(blockrequest_mutex);
 	memdelete(blockrequest_mutex);

+ 15 - 0
core/io/file_access_pack.cpp

@@ -107,6 +107,21 @@ PackedData::PackedData() {
 	add_pack_source(memnew(PackedSourcePCK));
 	add_pack_source(memnew(PackedSourcePCK));
 }
 }
 
 
+void PackedData::_free_packed_dirs(PackedDir *p_dir) {
+
+	for (Map<String,PackedDir*>::Element *E=p_dir->subdirs.front();E;E=E->next())
+		_free_packed_dirs(E->get());
+	memdelete(p_dir);
+}
+
+PackedData::~PackedData() {
+
+	for(int i=0;i<sources.size();i++) {
+		memdelete(sources[i]);
+	}
+	_free_packed_dirs(root);
+}
+
 
 
 //////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////
 
 

+ 4 - 0
core/io/file_access_pack.h

@@ -96,6 +96,8 @@ private:
 	static PackedData *singleton;
 	static PackedData *singleton;
 	bool disabled;
 	bool disabled;
 
 
+	void _free_packed_dirs(PackedDir *p_dir);
+
 public:
 public:
 
 
 	void add_pack_source(PackSource* p_source);
 	void add_pack_source(PackSource* p_source);
@@ -111,6 +113,7 @@ public:
 	_FORCE_INLINE_ bool has_path(const String& p_path);
 	_FORCE_INLINE_ bool has_path(const String& p_path);
 
 
 	PackedData();
 	PackedData();
+	~PackedData();
 };
 };
 
 
 class PackSource {
 class PackSource {
@@ -119,6 +122,7 @@ public:
 
 
 	virtual bool try_open_pack(const String& p_path)=0;
 	virtual bool try_open_pack(const String& p_path)=0;
 	virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file)=0;
 	virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file)=0;
+	virtual ~PackSource() {}
 };
 };
 
 
 class PackedSourcePCK : public PackSource {
 class PackedSourcePCK : public PackSource {

+ 1 - 1
core/io/file_access_zip.cpp

@@ -150,7 +150,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
 
 
 bool ZipArchive::try_open_pack(const String& p_name) {
 bool ZipArchive::try_open_pack(const String& p_name) {
 
 
-	printf("opening pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
+	//printf("opening pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
 	if (p_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0)
 	if (p_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0)
 		return false;
 		return false;
 
 

+ 14 - 1
core/object.cpp

@@ -33,6 +33,7 @@
 #include "message_queue.h"
 #include "message_queue.h"
 #include "core_string_names.h"
 #include "core_string_names.h"
 #include "translation.h"
 #include "translation.h"
+#include "os/os.h"
 
 
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
 
 
@@ -1728,8 +1729,20 @@ void ObjectDB::cleanup() {
 
 
 	GLOBAL_LOCK_FUNCTION;
 	GLOBAL_LOCK_FUNCTION;
 	if (instances.size()) {
 	if (instances.size()) {
-	
+			
 		WARN_PRINT("ObjectDB Instances still exist!");		
 		WARN_PRINT("ObjectDB Instances still exist!");		
+		if (OS::get_singleton()->is_stdout_verbose()) {
+			const uint32_t *K=NULL;
+			while((K=instances.next(K))) {
+
+				String node_name;
+				if (instances[*K]->is_type("Node"))
+					node_name=" - Node Name: "+String(instances[*K]->call("get_name"));
+				if (instances[*K]->is_type("Resoucre"))
+					node_name=" - Resource Name: "+String(instances[*K]->call("get_name"))+" Path: "+String(instances[*K]->call("get_path"));
+				print_line("Leaked Instance: "+String(instances[*K]->get_type())+":"+itos(*K)+node_name);
+			}
+		}
 	}
 	}
 	instances.clear();
 	instances.clear();
 	instance_checks.clear();
 	instance_checks.clear();

+ 4 - 2
core/register_core_types.cpp

@@ -205,12 +205,14 @@ void unregister_core_types() {
 	if (ip)
 	if (ip)
 		memdelete(ip);
 		memdelete(ip);
 
 
+
+	ObjectDB::cleanup();
+
 	unregister_variant_methods();
 	unregister_variant_methods();
 
 
-	CoreStringNames::free();
 	ObjectTypeDB::cleanup();
 	ObjectTypeDB::cleanup();
 	ResourceCache::clear();
 	ResourceCache::clear();
-	ObjectDB::cleanup();
+	CoreStringNames::free();
 	StringName::cleanup();
 	StringName::cleanup();
 
 
 	if (_global_mutex) {
 	if (_global_mutex) {

+ 16 - 2
core/string_db.cpp

@@ -28,7 +28,7 @@
 /*************************************************************************/
 /*************************************************************************/
 #include "string_db.h"
 #include "string_db.h"
 #include "print_string.h"
 #include "print_string.h"
-
+#include "os/os.h"
 StaticCString StaticCString::create(const char *p_ptr) {
 StaticCString StaticCString::create(const char *p_ptr) {
 	StaticCString scs; scs.ptr=p_ptr; return scs;
 	StaticCString scs; scs.ptr=p_ptr; return scs;
 }
 }
@@ -55,15 +55,29 @@ void StringName::setup() {
 void StringName::cleanup() {
 void StringName::cleanup() {
 	
 	
 	_global_lock();	
 	_global_lock();	
+	int lost_strings=0;
 	for(int i=0;i<STRING_TABLE_LEN;i++) {
 	for(int i=0;i<STRING_TABLE_LEN;i++) {
 		
 		
 		while(_table[i]) {
 		while(_table[i]) {
 			
 			
 			_Data*d=_table[i];
 			_Data*d=_table[i];
-			_table[i]=_table[i]->next;
+			lost_strings++;
+			if (OS::get_singleton()->is_stdout_verbose()) {
+
+				if (d->cname) {
+					print_line("Orphan StringName: "+String(d->cname));
+				} else {
+					print_line("Orphan StringName: "+String(d->name));
+				}
+			}
+
+			_table[i]=_table[i]->next;			
 			memdelete(d);
 			memdelete(d);
 		}
 		}
 	}
 	}
+	if (OS::get_singleton()->is_stdout_verbose() && lost_strings) {
+		print_line("StringName: "+itos(lost_strings)+" unclaimed string names at exit.");
+	}
 	_global_unlock();	
 	_global_unlock();	
 }
 }
 
 

+ 5 - 1
drivers/gles2/rasterizer_gles2.cpp

@@ -1613,7 +1613,8 @@ Variant RasterizerGLES2::shader_get_default_param(RID p_shader, const StringName
 
 
 RID RasterizerGLES2::material_create() {
 RID RasterizerGLES2::material_create() {
 
 
-	return material_owner.make_rid( memnew( Material ) );
+	RID material = material_owner.make_rid( memnew( Material ) );
+	return material;
 }
 }
 
 
 void RasterizerGLES2::material_set_shader(RID p_material, RID p_shader) {
 void RasterizerGLES2::material_set_shader(RID p_material, RID p_shader) {
@@ -10815,7 +10816,10 @@ void RasterizerGLES2::init() {
 
 
 void RasterizerGLES2::finish() {
 void RasterizerGLES2::finish() {
 
 
+	free(default_material);
+	free(shadow_material);
 	free(canvas_shadow_blur);
 	free(canvas_shadow_blur);
+	free( overdraw_material );
 }
 }
 
 
 int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) {
 int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) {

+ 14 - 1
main/main.cpp

@@ -87,6 +87,9 @@ static MessageQueue *message_queue=NULL;
 static Performance *performance = NULL;
 static Performance *performance = NULL;
 static PathRemap *path_remap;
 static PathRemap *path_remap;
 static PackedData *packed_data=NULL;
 static PackedData *packed_data=NULL;
+#ifdef MINIZIP_ENABLED
+static ZipArchive *zip_packed_data=NULL;
+#endif
 static FileAccessNetworkClient *file_access_network_client=NULL;
 static FileAccessNetworkClient *file_access_network_client=NULL;
 static TranslationServer *translation_server = NULL;
 static TranslationServer *translation_server = NULL;
 
 
@@ -248,7 +251,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 		packed_data = memnew(PackedData);
 		packed_data = memnew(PackedData);
 
 
 #ifdef MINIZIP_ENABLED
 #ifdef MINIZIP_ENABLED
-	packed_data->add_pack_source(ZipArchive::get_singleton());
+	zip_packed_data = ZipArchive::get_singleton();
+	packed_data->add_pack_source(zip_packed_data);
 #endif
 #endif
 
 
 	bool editor=false;
 	bool editor=false;
@@ -740,6 +744,15 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 		memdelete(packed_data);
 		memdelete(packed_data);
 	if (file_access_network_client)
 	if (file_access_network_client)
 		memdelete(file_access_network_client);
 		memdelete(file_access_network_client);
+
+	if (packed_data)
+		memdelete( packed_data );
+#ifdef MINIZIP_ENABLED
+	if (zip_packed_data)
+		memdelete( zip_packed_data );
+#endif
+
+
 	unregister_core_types();
 	unregister_core_types();
 	
 	
 	OS::get_singleton()->_cmdline.clear();
 	OS::get_singleton()->_cmdline.clear();

+ 15 - 10
modules/gridmap/grid_map_editor_plugin.cpp

@@ -868,7 +868,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
 	{
 	{
 
 
 		//update grids
 		//update grids
-		RID indicator_mat = VisualServer::get_singleton()->fixed_material_create();
+		indicator_mat = VisualServer::get_singleton()->fixed_material_create();
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_ONTOP, false );
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_ONTOP, false );
 
 
@@ -922,7 +922,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
 			d[VS::ARRAY_VERTEX]=grid_points[i];
 			d[VS::ARRAY_VERTEX]=grid_points[i];
 			d[VS::ARRAY_COLOR]=grid_colors[i];
 			d[VS::ARRAY_COLOR]=grid_colors[i];
 			VisualServer::get_singleton()->mesh_add_surface(grid[i],VisualServer::PRIMITIVE_LINES,d);
 			VisualServer::get_singleton()->mesh_add_surface(grid[i],VisualServer::PRIMITIVE_LINES,d);
-			VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat,true);
+			VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat);
 
 
 
 
 		}
 		}
@@ -1340,7 +1340,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 		Array d;
 		Array d;
 		d.resize(VS::ARRAY_MAX);
 		d.resize(VS::ARRAY_MAX);
 
 
-		RID inner_mat = VisualServer::get_singleton()->fixed_material_create();
+		inner_mat = VisualServer::get_singleton()->fixed_material_create();
 		VisualServer::get_singleton()->fixed_material_set_param(inner_mat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.7,0.7,1.0,0.3));
 		VisualServer::get_singleton()->fixed_material_set_param(inner_mat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.7,0.7,1.0,0.3));
 		VisualServer::get_singleton()->material_set_flag(inner_mat,VS::MATERIAL_FLAG_ONTOP,true);
 		VisualServer::get_singleton()->material_set_flag(inner_mat,VS::MATERIAL_FLAG_ONTOP,true);
 		VisualServer::get_singleton()->material_set_flag(inner_mat,VS::MATERIAL_FLAG_UNSHADED,true);
 		VisualServer::get_singleton()->material_set_flag(inner_mat,VS::MATERIAL_FLAG_UNSHADED,true);
@@ -1349,9 +1349,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 
 
 		d[VS::ARRAY_VERTEX]=triangles;
 		d[VS::ARRAY_VERTEX]=triangles;
 		VisualServer::get_singleton()->mesh_add_surface(selection_mesh,VS::PRIMITIVE_TRIANGLES,d);
 		VisualServer::get_singleton()->mesh_add_surface(selection_mesh,VS::PRIMITIVE_TRIANGLES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh,0,inner_mat,true);
+		VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh,0,inner_mat);
 
 
-		RID outer_mat = VisualServer::get_singleton()->fixed_material_create();
+		outer_mat = VisualServer::get_singleton()->fixed_material_create();
 		VisualServer::get_singleton()->fixed_material_set_param(outer_mat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.7,0.7,1.0,0.8));
 		VisualServer::get_singleton()->fixed_material_set_param(outer_mat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.7,0.7,1.0,0.8));
 		VisualServer::get_singleton()->material_set_line_width(outer_mat,3.0);
 		VisualServer::get_singleton()->material_set_line_width(outer_mat,3.0);
 		VisualServer::get_singleton()->material_set_flag(outer_mat,VS::MATERIAL_FLAG_ONTOP,true);
 		VisualServer::get_singleton()->material_set_flag(outer_mat,VS::MATERIAL_FLAG_ONTOP,true);
@@ -1361,10 +1361,10 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 
 
 		d[VS::ARRAY_VERTEX]=lines;
 		d[VS::ARRAY_VERTEX]=lines;
 		VisualServer::get_singleton()->mesh_add_surface(selection_mesh,VS::PRIMITIVE_LINES,d);
 		VisualServer::get_singleton()->mesh_add_surface(selection_mesh,VS::PRIMITIVE_LINES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh,1,outer_mat,true);
+		VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh,1,outer_mat);
 
 
 
 
-		RID inner_mat_dup = VisualServer::get_singleton()->fixed_material_create();
+		inner_mat_dup = VisualServer::get_singleton()->fixed_material_create();
 		VisualServer::get_singleton()->fixed_material_set_param(inner_mat_dup,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(1.0,0.7,0.7,0.3));
 		VisualServer::get_singleton()->fixed_material_set_param(inner_mat_dup,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(1.0,0.7,0.7,0.3));
 		VisualServer::get_singleton()->material_set_flag(inner_mat_dup,VS::MATERIAL_FLAG_ONTOP,true);
 		VisualServer::get_singleton()->material_set_flag(inner_mat_dup,VS::MATERIAL_FLAG_ONTOP,true);
 		VisualServer::get_singleton()->material_set_flag(inner_mat_dup,VS::MATERIAL_FLAG_UNSHADED,true);
 		VisualServer::get_singleton()->material_set_flag(inner_mat_dup,VS::MATERIAL_FLAG_UNSHADED,true);
@@ -1373,9 +1373,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 
 
 		d[VS::ARRAY_VERTEX]=triangles;
 		d[VS::ARRAY_VERTEX]=triangles;
 		VisualServer::get_singleton()->mesh_add_surface(duplicate_mesh,VS::PRIMITIVE_TRIANGLES,d);
 		VisualServer::get_singleton()->mesh_add_surface(duplicate_mesh,VS::PRIMITIVE_TRIANGLES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh,0,inner_mat_dup,true);
+		VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh,0,inner_mat_dup);
 
 
-		RID outer_mat_dup = VisualServer::get_singleton()->fixed_material_create();
+		outer_mat_dup = VisualServer::get_singleton()->fixed_material_create();
 		VisualServer::get_singleton()->fixed_material_set_param(outer_mat_dup,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(1.0,0.7,0.7,0.8));
 		VisualServer::get_singleton()->fixed_material_set_param(outer_mat_dup,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(1.0,0.7,0.7,0.8));
 		VisualServer::get_singleton()->material_set_line_width(outer_mat_dup,3.0);
 		VisualServer::get_singleton()->material_set_line_width(outer_mat_dup,3.0);
 		VisualServer::get_singleton()->material_set_flag(outer_mat_dup,VS::MATERIAL_FLAG_ONTOP,true);
 		VisualServer::get_singleton()->material_set_flag(outer_mat_dup,VS::MATERIAL_FLAG_ONTOP,true);
@@ -1385,7 +1385,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 
 
 		d[VS::ARRAY_VERTEX]=lines;
 		d[VS::ARRAY_VERTEX]=lines;
 		VisualServer::get_singleton()->mesh_add_surface(duplicate_mesh,VS::PRIMITIVE_LINES,d);
 		VisualServer::get_singleton()->mesh_add_surface(duplicate_mesh,VS::PRIMITIVE_LINES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh,1,outer_mat_dup,true);
+		VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh,1,outer_mat_dup);
 
 
 	}
 	}
 
 
@@ -1409,6 +1409,11 @@ GridMapEditor::~GridMapEditor() {
 			VisualServer::get_singleton()->free(cursor_instance);
 			VisualServer::get_singleton()->free(cursor_instance);
 	}
 	}
 
 
+	VisualServer::get_singleton()->free(inner_mat);
+	VisualServer::get_singleton()->free(outer_mat);
+	VisualServer::get_singleton()->free(inner_mat_dup);
+	VisualServer::get_singleton()->free(outer_mat_dup);
+
 	VisualServer::get_singleton()->free(selection_mesh);
 	VisualServer::get_singleton()->free(selection_mesh);
 	if (selection_instance.is_valid())
 	if (selection_instance.is_valid())
 		VisualServer::get_singleton()->free(selection_instance);
 		VisualServer::get_singleton()->free(selection_instance);

+ 7 - 0
modules/gridmap/grid_map_editor_plugin.h

@@ -105,6 +105,13 @@ class GridMapEditor : public VBoxContainer {
 	RID duplicate_mesh;
 	RID duplicate_mesh;
 	RID duplicate_instance;
 	RID duplicate_instance;
 
 
+	RID indicator_mat;
+
+	RID inner_mat;
+	RID outer_mat;
+	RID inner_mat_dup;
+	RID outer_mat_dup;
+
 	bool updating;
 	bool updating;
 
 
 
 

+ 3 - 0
platform/android/export/export.cpp

@@ -1635,8 +1635,11 @@ bool EditorExportPlatformAndroid::can_export(String *r_error) const {
 
 
 EditorExportPlatformAndroid::~EditorExportPlatformAndroid() {
 EditorExportPlatformAndroid::~EditorExportPlatformAndroid() {
 
 
+
 	quit_request=true;
 	quit_request=true;
 	Thread::wait_to_finish(device_thread);
 	Thread::wait_to_finish(device_thread);
+	memdelete(device_lock);
+	memdelete(device_thread);
 }
 }
 
 
 
 

+ 2 - 0
platform/bb10/export/export.cpp

@@ -764,6 +764,8 @@ EditorExportPlatformBB10::~EditorExportPlatformBB10() {
 
 
 	quit_request=true;
 	quit_request=true;
 	Thread::wait_to_finish(device_thread);
 	Thread::wait_to_finish(device_thread);
+	memdelete(device_lock);
+	memdelete(device_thread);
 }
 }
 
 
 
 

+ 7 - 0
platform/x11/detect.py

@@ -52,6 +52,7 @@ def get_opts():
 	return [
 	return [
 	('use_llvm','Use llvm compiler','no'),
 	('use_llvm','Use llvm compiler','no'),
 	('use_sanitizer','Use llvm compiler sanitize address','no'),
 	('use_sanitizer','Use llvm compiler sanitize address','no'),
+	('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'),
 	('pulseaudio','Detect & Use pulseaudio','yes'),
 	('pulseaudio','Detect & Use pulseaudio','yes'),
 	('new_wm_api', 'Use experimental window management API','no'),
 	('new_wm_api', 'Use experimental window management API','no'),
 	]
 	]
@@ -94,6 +95,12 @@ def configure(env):
 		env.Append(LINKFLAGS=['-fsanitize=address'])
 		env.Append(LINKFLAGS=['-fsanitize=address'])
 		env.extra_suffix+="s"
 		env.extra_suffix+="s"
 
 
+	if (env["use_leak_sanitizer"]=="yes"):
+		env.Append(CXXFLAGS=['-fsanitize=address','-fno-omit-frame-pointer'])
+		env.Append(LINKFLAGS=['-fsanitize=address'])
+		env.extra_suffix+="s"
+
+
 	#if (env["tools"]=="no"):
 	#if (env["tools"]=="no"):
 	#	#no tools suffix
 	#	#no tools suffix
 	#	env['OBJSUFFIX'] = ".nt"+env['OBJSUFFIX']
 	#	env['OBJSUFFIX'] = ".nt"+env['OBJSUFFIX']

+ 3 - 0
platform/x11/os_x11.cpp

@@ -258,9 +258,11 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
 
 
 	AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
 	AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
 
 
+	audio_driver_index=p_audio_driver;
 	if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
 	if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
 
 
 		bool success=false;
 		bool success=false;
+		audio_driver_index=-1;
 		for(int i=0;i<AudioDriverManagerSW::get_driver_count();i++) {
 		for(int i=0;i<AudioDriverManagerSW::get_driver_count();i++) {
 			if (i==p_audio_driver)
 			if (i==p_audio_driver)
 				continue;
 				continue;
@@ -268,6 +270,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
 				success=true;
 				success=true;
 				print_line("Audio Driver Failed: "+String(AudioDriverManagerSW::get_driver(p_audio_driver)->get_name()));
 				print_line("Audio Driver Failed: "+String(AudioDriverManagerSW::get_driver(p_audio_driver)->get_name()));
 				print_line("Using alternate audio driver: "+String(AudioDriverManagerSW::get_driver(i)->get_name()));
 				print_line("Using alternate audio driver: "+String(AudioDriverManagerSW::get_driver(i)->get_name()));
+				audio_driver_index=i;
 				break;
 				break;
 			}
 			}
 		}
 		}

+ 2 - 1
platform/x11/os_x11.h

@@ -157,9 +157,10 @@ class OS_X11 : public OS_Unix {
 
 
 
 
 	int joystick_count;
 	int joystick_count;
-	Joystick joysticks[JOYSTICKS_MAX];
 
 
+	Joystick joysticks[JOYSTICKS_MAX];
 
 
+	int audio_driver_index;
 	unsigned int capture_idle;
 	unsigned int capture_idle;
 	bool maximized;
 	bool maximized;
 	//void set_wm_border(bool p_enabled);
 	//void set_wm_border(bool p_enabled);

+ 2 - 1
scene/2d/camera_2d.cpp

@@ -37,7 +37,8 @@ void Camera2D::_update_scroll() {
 		return;
 		return;
 
 
 	if (get_tree()->is_editor_hint()) {
 	if (get_tree()->is_editor_hint()) {
-		update(); //will just be drawn
+	//	update(); //will just be drawn
+		//??
 		return;
 		return;
 	}
 	}
 
 

+ 0 - 1
scene/2d/canvas_item.cpp

@@ -342,7 +342,6 @@ void CanvasItem::_update_callback() {
 		return;
 		return;
 	}
 	}
 
 
-
 	VisualServer::get_singleton()->canvas_item_clear(get_canvas_item());
 	VisualServer::get_singleton()->canvas_item_clear(get_canvas_item());
 	//todo updating = true - only allow drawing here
 	//todo updating = true - only allow drawing here
 	if (is_visible()) { //todo optimize this!!
 	if (is_visible()) { //todo optimize this!!

+ 1 - 0
scene/main/viewport.cpp

@@ -1450,6 +1450,7 @@ Viewport::~Viewport() {
 
 
 	VisualServer::get_singleton()->free( viewport );
 	VisualServer::get_singleton()->free( viewport );
 	SpatialSoundServer::get_singleton()->free(listener);
 	SpatialSoundServer::get_singleton()->free(listener);
+	SpatialSound2DServer::get_singleton()->free(listener_2d);
 	if (render_target_texture.is_valid())
 	if (render_target_texture.is_valid())
 		render_target_texture->vp=NULL; //so if used, will crash
 		render_target_texture->vp=NULL; //so if used, will crash
 }
 }

+ 1 - 0
servers/visual/rasterizer.h

@@ -661,6 +661,7 @@ public:
 			};
 			};
 
 
 			Type type;
 			Type type;
+			virtual ~Command(){}
 		};
 		};
 
 
 		struct CommandLine : public Command {
 		struct CommandLine : public Command {

+ 7 - 3
servers/visual/visual_server_raster.cpp

@@ -4393,7 +4393,7 @@ void VisualServerRaster::free( RID p_rid ) {
 
 
 	VS_CHANGED;
 	VS_CHANGED;
 
 
-	if (rasterizer->is_texture(p_rid) || rasterizer->is_material(p_rid) ||  rasterizer->is_shader(p_rid)) {
+	if (rasterizer->is_texture(p_rid) || rasterizer->is_material(p_rid) ||  rasterizer->is_shader(p_rid) || rasterizer->is_environment(p_rid)) {
 	
 	
 		rasterizer->free(p_rid);
 		rasterizer->free(p_rid);
 	} else if (rasterizer->is_skeleton(p_rid)) {
 	} else if (rasterizer->is_skeleton(p_rid)) {
@@ -4410,7 +4410,7 @@ void VisualServerRaster::free( RID p_rid ) {
 		}
 		}
 
 
 		rasterizer->free(p_rid);
 		rasterizer->free(p_rid);
-	} else if (rasterizer->is_mesh(p_rid) || rasterizer->is_multimesh(p_rid) || rasterizer->is_light(p_rid) || rasterizer->is_particles(p_rid) ) {
+	} else if (rasterizer->is_mesh(p_rid) || rasterizer->is_multimesh(p_rid) || rasterizer->is_light(p_rid) || rasterizer->is_particles(p_rid) || rasterizer->is_immediate(p_rid)) {
 		//delete the resource
 		//delete the resource
 	
 	
 		_free_attached_instances(p_rid);
 		_free_attached_instances(p_rid);
@@ -7488,6 +7488,10 @@ void VisualServerRaster::finish() {
 
 
 
 
 	free(default_cursor_texture);
 	free(default_cursor_texture);
+	if (test_cube.is_valid())
+		free(test_cube);
+
+	_free_internal_rids();
 
 
 	_clean_up_owner( &room_owner,"Room" );
 	_clean_up_owner( &room_owner,"Room" );
 	_clean_up_owner( &portal_owner,"Portal" );
 	_clean_up_owner( &portal_owner,"Portal" );
@@ -7505,7 +7509,7 @@ void VisualServerRaster::finish() {
 	octree_allocator.clear();
 	octree_allocator.clear();
 	
 	
 	if (instance_dependency_map.size()) {
 	if (instance_dependency_map.size()) {
-		print_line("base resources missing "+itos(instance_dependency_map.size()));
+		print_line("Base resources missing amount: "+itos(instance_dependency_map.size()));
 	}
 	}
 	ERR_FAIL_COND( instance_dependency_map.size() );
 	ERR_FAIL_COND( instance_dependency_map.size() );
 }
 }

+ 26 - 7
servers/visual_server.cpp

@@ -130,6 +130,24 @@ RID VisualServer::get_test_texture() {
 	return test_texture;
 	return test_texture;
 };
 };
 
 
+void VisualServer::_free_internal_rids() {
+
+	if (test_texture.is_valid())
+		free(test_texture);
+	if (white_texture.is_valid())
+		free(white_texture);
+	if (test_material.is_valid())
+		free(test_material);
+
+	for(int i=0;i<16;i++) {
+		if (material_2d[i].is_valid())
+			free(material_2d[i]);
+	}
+
+
+
+}
+
 RID VisualServer::_make_test_cube() {
 RID VisualServer::_make_test_cube() {
 
 
 	DVector<Vector3> vertices;
 	DVector<Vector3> vertices;
@@ -202,16 +220,17 @@ RID VisualServer::_make_test_cube() {
 	mesh_add_surface( test_cube, PRIMITIVE_TRIANGLES,d );
 	mesh_add_surface( test_cube, PRIMITIVE_TRIANGLES,d );
 	
 	
 
 
-	RID material = fixed_material_create();
+
+	test_material = fixed_material_create();
 	//material_set_flag(material, MATERIAL_FLAG_BILLBOARD_TOGGLE,true);
 	//material_set_flag(material, MATERIAL_FLAG_BILLBOARD_TOGGLE,true);
-	fixed_material_set_texture( material, FIXED_MATERIAL_PARAM_DIFFUSE, get_test_texture() );
-	fixed_material_set_param( material, FIXED_MATERIAL_PARAM_SPECULAR_EXP, 70 );
-	fixed_material_set_param( material, FIXED_MATERIAL_PARAM_EMISSION, Color(0.2,0.2,0.2) );
+	fixed_material_set_texture( test_material, FIXED_MATERIAL_PARAM_DIFFUSE, get_test_texture() );
+	fixed_material_set_param( test_material, FIXED_MATERIAL_PARAM_SPECULAR_EXP, 70 );
+	fixed_material_set_param( test_material, FIXED_MATERIAL_PARAM_EMISSION, Color(0.2,0.2,0.2) );
 
 
-	fixed_material_set_param( material, FIXED_MATERIAL_PARAM_DIFFUSE, Color(1, 1, 1) );
-	fixed_material_set_param( material, FIXED_MATERIAL_PARAM_SPECULAR, Color(1,1,1) );
+	fixed_material_set_param( test_material, FIXED_MATERIAL_PARAM_DIFFUSE, Color(1, 1, 1) );
+	fixed_material_set_param( test_material, FIXED_MATERIAL_PARAM_SPECULAR, Color(1,1,1) );
 
 
-	mesh_surface_set_material(test_cube, 0, material );
+	mesh_surface_set_material(test_cube, 0, test_material );
 	
 	
 	return test_cube;
 	return test_cube;
 }
 }

+ 2 - 0
servers/visual_server.h

@@ -55,8 +55,10 @@ class VisualServer : public Object {
 	void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1));
 	void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1));
 protected:	
 protected:	
 	RID _make_test_cube();
 	RID _make_test_cube();
+	void _free_internal_rids();
 	RID test_texture;
 	RID test_texture;
 	RID white_texture;
 	RID white_texture;
+	RID test_material;
 	RID material_2d[16];
 	RID material_2d[16];
 	
 	
 	static VisualServer* (*create_func)();
 	static VisualServer* (*create_func)();

+ 2 - 2
tools/editor/animation_editor.cpp

@@ -3289,10 +3289,10 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
 	keying->connect("pressed",this,"_keying_toggled");
 	keying->connect("pressed",this,"_keying_toggled");
 	*/
 	*/
 
 
-	l = memnew( Label );
+/*	l = memnew( Label );
 	l->set_text("Base: ");
 	l->set_text("Base: ");
 	l->set_pos(Point2(0,3));
 	l->set_pos(Point2(0,3));
-//	dr_panel->add_child(l);
+//	dr_panel->add_child(l);*/
 
 
 //	menu->get_popup()->connect("item_pressed",this,"_menu_callback");
 //	menu->get_popup()->connect("item_pressed",this,"_menu_callback");
 
 

+ 8 - 0
tools/editor/editor_import_export.cpp

@@ -1779,3 +1779,11 @@ EditorImportExport::EditorImportExport() {
 }
 }
 
 
 
 
+
+EditorImportExport::~EditorImportExport() {
+
+
+
+}
+
+

+ 1 - 0
tools/editor/editor_import_export.h

@@ -336,6 +336,7 @@ public:
 	void save_config();
 	void save_config();
 
 
 	EditorImportExport();
 	EditorImportExport();
+	~EditorImportExport();
 };
 };
 
 
 VARIANT_ENUM_CAST(EditorImportExport::ImageAction);
 VARIANT_ENUM_CAST(EditorImportExport::ImageAction);

+ 13 - 8
tools/editor/editor_node.cpp

@@ -144,6 +144,7 @@ void EditorNode::_unhandled_input(const InputEvent& p_event) {
 void EditorNode::_notification(int p_what) {
 void EditorNode::_notification(int p_what) {
 
 
 	if (p_what==NOTIFICATION_EXIT_TREE) {
 	if (p_what==NOTIFICATION_EXIT_TREE) {
+
 		editor_data.save_editor_external_data();
 		editor_data.save_editor_external_data();
 
 
 		log->deinit(); // do not get messages anymore
 		log->deinit(); // do not get messages anymore
@@ -1393,7 +1394,7 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
 	}
 	}
 
 
 	play_button->set_pressed(false);
 	play_button->set_pressed(false);
-	pause_button->set_pressed(false);
+	//pause_button->set_pressed(false);
 	play_scene_button->set_pressed(false);
 	play_scene_button->set_pressed(false);
 
 
 	String current_filename;
 	String current_filename;
@@ -2152,7 +2153,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
 			editor_run.stop();
 			editor_run.stop();
 			play_button->set_pressed(false);
 			play_button->set_pressed(false);
 			play_scene_button->set_pressed(false);
 			play_scene_button->set_pressed(false);
-			pause_button->set_pressed(false);
+			//pause_button->set_pressed(false);
 			emit_signal("stop_pressed");
 			emit_signal("stop_pressed");
 
 
 		} break;
 		} break;
@@ -3023,7 +3024,7 @@ void EditorNode::notify_child_process_exited() {
 
 
 	play_button->set_pressed(false);
 	play_button->set_pressed(false);
 	play_scene_button->set_pressed(false);
 	play_scene_button->set_pressed(false);
-	pause_button->set_pressed(false);
+	//pause_button->set_pressed(false);
 	stop_button->set_pressed(false);
 	stop_button->set_pressed(false);
 	editor_run.stop();
 	editor_run.stop();
 
 
@@ -3306,6 +3307,7 @@ EditorNode::EditorNode() {
 	FileDialog::unregister_func=_file_dialog_unregister;
 	FileDialog::unregister_func=_file_dialog_unregister;
 
 
 	editor_import_export = memnew( EditorImportExport );
 	editor_import_export = memnew( EditorImportExport );
+	add_child(editor_import_export);
 
 
 	register_exporters();
 	register_exporters();
 
 
@@ -3491,8 +3493,9 @@ EditorNode::EditorNode() {
 	prev_scene->set_disabled(true);
 	prev_scene->set_disabled(true);
 	//left_menu_hb->add_child( prev_scene );
 	//left_menu_hb->add_child( prev_scene );
 	prev_scene->connect("pressed",this,"_menu_option",make_binds(FILE_OPEN_PREV));
 	prev_scene->connect("pressed",this,"_menu_option",make_binds(FILE_OPEN_PREV));
-	//gui_base->add_child(prev_scene);
+	gui_base->add_child(prev_scene);
 	prev_scene->set_pos(Point2(3,24));
 	prev_scene->set_pos(Point2(3,24));
+	prev_scene->hide();
 
 
 
 
 	Separator *vs=NULL;
 	Separator *vs=NULL;
@@ -3617,14 +3620,14 @@ EditorNode::EditorNode() {
 
 
 
 
 
 
-	pause_button = memnew( ToolButton );
+	/*pause_button = memnew( ToolButton );
 	//menu_panel->add_child(pause_button); - not needed for now?
 	//menu_panel->add_child(pause_button); - not needed for now?
 	pause_button->set_toggle_mode(true);
 	pause_button->set_toggle_mode(true);
 	pause_button->set_icon(gui_base->get_icon("Pause","EditorIcons"));
 	pause_button->set_icon(gui_base->get_icon("Pause","EditorIcons"));
 	pause_button->set_focus_mode(Control::FOCUS_NONE);
 	pause_button->set_focus_mode(Control::FOCUS_NONE);
 	pause_button->connect("pressed", this,"_menu_option",make_binds(RUN_PAUSE));
 	pause_button->connect("pressed", this,"_menu_option",make_binds(RUN_PAUSE));
 	pause_button->set_tooltip("Pause the scene (F7).");
 	pause_button->set_tooltip("Pause the scene (F7).");
-
+*/
 	stop_button = memnew( ToolButton );
 	stop_button = memnew( ToolButton );
 	play_hb->add_child(stop_button);
 	play_hb->add_child(stop_button);
 	//stop_button->set_toggle_mode(true);
 	//stop_button->set_toggle_mode(true);
@@ -3641,7 +3644,7 @@ EditorNode::EditorNode() {
 	native_play_button->hide();
 	native_play_button->hide();
 	native_play_button->get_popup()->connect("item_pressed",this,"_run_in_device");
 	native_play_button->get_popup()->connect("item_pressed",this,"_run_in_device");
 
 
-	VSeparator *s1 = memnew( VSeparator );
+//	VSeparator *s1 = memnew( VSeparator );
 //	play_hb->add_child(s1);
 //	play_hb->add_child(s1);
 
 
 	play_scene_button = memnew( ToolButton );
 	play_scene_button = memnew( ToolButton );
@@ -3677,13 +3680,14 @@ EditorNode::EditorNode() {
 	p->set_item_tooltip(p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),"Deploy dumb clients when the File Server is active.");
 	p->set_item_tooltip(p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),"Deploy dumb clients when the File Server is active.");
 	p->connect("item_pressed",this,"_menu_option");
 	p->connect("item_pressed",this,"_menu_option");
 
 
+	/*
 	run_settings_button = memnew( ToolButton );
 	run_settings_button = memnew( ToolButton );
 	//menu_hb->add_child(run_settings_button);
 	//menu_hb->add_child(run_settings_button);
 	//run_settings_button->set_toggle_mode(true);
 	//run_settings_button->set_toggle_mode(true);
 	run_settings_button->set_focus_mode(Control::FOCUS_NONE);
 	run_settings_button->set_focus_mode(Control::FOCUS_NONE);
 	run_settings_button->set_icon(gui_base->get_icon("Run","EditorIcons"));
 	run_settings_button->set_icon(gui_base->get_icon("Run","EditorIcons"));
 	run_settings_button->connect("pressed", this,"_menu_option",make_binds(RUN_SCENE_SETTINGS));
 	run_settings_button->connect("pressed", this,"_menu_option",make_binds(RUN_SCENE_SETTINGS));
-
+*/
 
 
 	/*
 	/*
 	run_settings_button = memnew( ToolButton );
 	run_settings_button = memnew( ToolButton );
@@ -4246,6 +4250,7 @@ EditorNode::EditorNode() {
 
 
 EditorNode::~EditorNode() {	
 EditorNode::~EditorNode() {	
 
 
+
 	memdelete(editor_selection);
 	memdelete(editor_selection);
 	memdelete(file_server);
 	memdelete(file_server);
 	EditorSettings::destroy();
 	EditorSettings::destroy();

+ 2 - 0
tools/editor/fileserver/editor_file_server.cpp

@@ -278,6 +278,7 @@ void EditorFileServer::_thread_start(void*s) {
 			self->to_wait.erase(w);
 			self->to_wait.erase(w);
 			self->wait_mutex->unlock();
 			self->wait_mutex->unlock();
 			Thread::wait_to_finish(w);
 			Thread::wait_to_finish(w);
+			memdelete(w);
 			self->wait_mutex->lock();
 			self->wait_mutex->lock();
 		}
 		}
 		self->wait_mutex->unlock();
 		self->wait_mutex->unlock();
@@ -346,5 +347,6 @@ EditorFileServer::~EditorFileServer() {
 
 
 	quit=true;
 	quit=true;
 	Thread::wait_to_finish(thread);
 	Thread::wait_to_finish(thread);
+	memdelete(thread);
 	memdelete(wait_mutex);
 	memdelete(wait_mutex);
 }
 }

+ 2 - 1
tools/editor/io_plugins/editor_font_import_plugin.cpp

@@ -650,6 +650,7 @@ public:
 
 
 		vbl->add_spacer();
 		vbl->add_spacer();
 		vbl->add_margin_child("Test: ",testhb);
 		vbl->add_margin_child("Test: ",testhb);
+		/*
 		HBoxContainer *upd_hb = memnew( HBoxContainer );
 		HBoxContainer *upd_hb = memnew( HBoxContainer );
 //		vbl->add_child(upd_hb);
 //		vbl->add_child(upd_hb);
 		upd_hb->add_spacer();
 		upd_hb->add_spacer();
@@ -657,7 +658,7 @@ public:
 		upd_hb->add_child(update);
 		upd_hb->add_child(update);
 		update->set_text("Update");
 		update->set_text("Update");
 		update->connect("pressed",this,"_update");
 		update->connect("pressed",this,"_update");
-
+*/
 		options = memnew( _EditorFontImportOptions );
 		options = memnew( _EditorFontImportOptions );
 		prop_edit = memnew( PropertyEditor() );
 		prop_edit = memnew( PropertyEditor() );
 		vbr->add_margin_child("Options:",prop_edit,true);
 		vbr->add_margin_child("Options:",prop_edit,true);

+ 1 - 0
tools/editor/plugins/baked_light_baker.cpp

@@ -2127,6 +2127,7 @@ void BakedLightBaker::_stop_thread() {
 	bake_thread_exit=true;
 	bake_thread_exit=true;
 	for(int i=0;i<threads.size();i++) {
 	for(int i=0;i<threads.size();i++) {
 		Thread::wait_to_finish(threads[i]);
 		Thread::wait_to_finish(threads[i]);
+		memdelete(threads[i]);
 	}
 	}
 	threads.clear();
 	threads.clear();
 }
 }

+ 31 - 8
tools/editor/plugins/canvas_item_editor_plugin.cpp

@@ -943,13 +943,13 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
 		}
 		}
 
 
 
 
-		List<BoneList>::Element *Cbone=NULL; //closest
+		Map<ObjectID,BoneList>::Element *Cbone=NULL; //closest
 
 
 		{
 		{
 			bone_ik_list.clear();
 			bone_ik_list.clear();
 			float closest_dist=1e20;
 			float closest_dist=1e20;
 			int bone_width = EditorSettings::get_singleton()->get("2d_editor/bone_width");
 			int bone_width = EditorSettings::get_singleton()->get("2d_editor/bone_width");
-			for(List<BoneList>::Element *E=bone_list.front();E;E=E->next()) {
+			for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) {
 
 
 				if (E->get().from == E->get().to)
 				if (E->get().from == E->get().to)
 					continue;
 					continue;
@@ -1789,7 +1789,7 @@ void CanvasItemEditor::_viewport_draw() {
 	Color bone_ik_color = EditorSettings::get_singleton()->get("2d_editor/bone_ik_color");
 	Color bone_ik_color = EditorSettings::get_singleton()->get("2d_editor/bone_ik_color");
 	Color bone_selected_color = EditorSettings::get_singleton()->get("2d_editor/bone_selected_color");
 	Color bone_selected_color = EditorSettings::get_singleton()->get("2d_editor/bone_selected_color");
 
 
-	for(List<BoneList>::Element*E=bone_list.front();E;E=E->next()) {
+	for(Map<ObjectID,BoneList>::Element*E=bone_list.front();E;E=E->next()) {
 
 
 		E->get().from=Vector2();
 		E->get().from=Vector2();
 		E->get().to=Vector2();
 		E->get().to=Vector2();
@@ -1884,10 +1884,12 @@ void CanvasItemEditor::_notification(int p_what) {
 
 
 		}
 		}
 
 
-		for(List<BoneList>::Element *E=bone_list.front();E;E=E->next()) {
+
+		for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) {
 
 
 			Object *b = ObjectDB::get_instance(E->get().bone);
 			Object *b = ObjectDB::get_instance(E->get().bone);
 			if (!b) {
 			if (!b) {
+
 				viewport->update();
 				viewport->update();
 				break;
 				break;
 			}
 			}
@@ -1989,9 +1991,14 @@ void CanvasItemEditor::_find_canvas_items_span(Node *p_node, Rect2& r_rect, cons
 
 
 		if (c->has_meta("_edit_bone_")) {
 		if (c->has_meta("_edit_bone_")) {
 
 
-			BoneList bone;
-			bone.bone=c->get_instance_ID();
-			bone_list.push_back(bone);
+			ObjectID id = c->get_instance_ID();
+			if (!bone_list.has(id)) {
+				BoneList bone;
+				bone.bone=id;
+				bone_list[id]=bone;
+			}
+
+			bone_list[id].last_pass=bone_last_frame;
 		}
 		}
 
 
 		r_rect.expand_to( xform.xform(rect.pos) );
 		r_rect.expand_to( xform.xform(rect.pos) );
@@ -2026,11 +2033,26 @@ void CanvasItemEditor::_update_scrollbars() {
 	Rect2 canvas_item_rect=Rect2(Point2(),screen_rect);
 	Rect2 canvas_item_rect=Rect2(Point2(),screen_rect);
 
 
 	lock_list.clear();;
 	lock_list.clear();;
-	bone_list.clear();;
+	bone_last_frame++;
+
+
 
 
 	if (editor->get_edited_scene())
 	if (editor->get_edited_scene())
 		_find_canvas_items_span(editor->get_edited_scene(),canvas_item_rect,Matrix32());
 		_find_canvas_items_span(editor->get_edited_scene(),canvas_item_rect,Matrix32());
 
 
+	List<Map<ObjectID,BoneList>::Element*> bone_to_erase;
+
+	for(Map<ObjectID,BoneList>::Element*E=bone_list.front();E;E=E->next()) {
+
+		if (E->get().last_pass!=bone_last_frame) {
+			bone_to_erase.push_back(E);
+		}
+	}
+
+	while(bone_to_erase.size()) {
+		bone_list.erase(bone_to_erase.front()->get());
+		bone_to_erase.pop_front();
+	}
 
 
 	//expand area so it's easier to do animations and stuff at 0,0
 	//expand area so it's easier to do animations and stuff at 0,0
 	canvas_item_rect.size+=screen_rect*2;
 	canvas_item_rect.size+=screen_rect*2;
@@ -3024,6 +3046,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	set_process_unhandled_key_input(true);
 	set_process_unhandled_key_input(true);
 	can_move_pivot=false;
 	can_move_pivot=false;
 	drag=DRAG_NONE;
 	drag=DRAG_NONE;
+	bone_last_frame=0;
 }
 }
 
 
 CanvasItemEditor *CanvasItemEditor::singleton=NULL;
 CanvasItemEditor *CanvasItemEditor::singleton=NULL;

+ 4 - 1
tools/editor/plugins/canvas_item_editor_plugin.h

@@ -181,9 +181,12 @@ class CanvasItemEditor : public VBoxContainer {
 		Vector2 from;
 		Vector2 from;
 		Vector2 to;
 		Vector2 to;
 		ObjectID bone;
 		ObjectID bone;
+		uint64_t last_pass;
 	};
 	};
 
 
-	List<BoneList> bone_list;
+	uint64_t bone_last_frame;
+	Map<ObjectID,BoneList> bone_list;
+
 	Matrix32 bone_orig_xform;
 	Matrix32 bone_orig_xform;
 
 
 	struct BoneIK {
 	struct BoneIK {

+ 2 - 1
tools/editor/plugins/sample_library_editor_plugin.cpp

@@ -332,7 +332,8 @@ SampleLibraryEditor::SampleLibraryEditor() {
 	play->set_pos(Point2( 5, 5 ));
 	play->set_pos(Point2( 5, 5 ));
 	play->set_size( Size2(1,1 ) );
 	play->set_size( Size2(1,1 ) );
 	play->set_toggle_mode(true);
 	play->set_toggle_mode(true);
-	//add_child(play);
+	add_child(play);
+	play->hide();
 
 
 	stop = memnew( Button );
 	stop = memnew( Button );
 
 

+ 29 - 12
tools/editor/plugins/spatial_editor_plugin.cpp

@@ -1764,6 +1764,12 @@ void SpatialEditorViewport::_notification(int p_what) {
 		preview_camera->set_icon(get_icon("Camera","EditorIcons"));
 		preview_camera->set_icon(get_icon("Camera","EditorIcons"));
 		_init_gizmo_instance(index);
 		_init_gizmo_instance(index);
 
 
+	}
+	if (p_what==NOTIFICATION_EXIT_TREE) {
+
+
+		_finish_gizmo_instances();
+
 	}
 	}
 
 
 	if (p_what==NOTIFICATION_MOUSE_ENTER) {
 	if (p_what==NOTIFICATION_MOUSE_ENTER) {
@@ -2052,6 +2058,16 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 
 
 }
 }
 
 
+
+void SpatialEditorViewport::_finish_gizmo_instances() {
+
+
+	for(int i=0;i<3;i++) {
+		VS::get_singleton()->free(move_gizmo_instance[i]);
+		VS::get_singleton()->free(rotate_gizmo_instance[i]);
+	}
+
+}
 void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
 void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
 
 
 
 
@@ -2971,14 +2987,14 @@ void SpatialEditor::_init_indicators() {
 	VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform);
 	VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform);
 
 
 
 
-	RID mat = VisualServer::get_singleton()->fixed_material_create();
-	VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
-	VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
+	//RID mat = VisualServer::get_singleton()->fixed_material_create();
+	///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
+	//VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
 
 
 
 
 	{
 	{
 
 
-		RID indicator_mat = VisualServer::get_singleton()->fixed_material_create();
+		indicator_mat = VisualServer::get_singleton()->fixed_material_create();
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_ONTOP, false );
 		VisualServer::get_singleton()->material_set_flag( indicator_mat, VisualServer::MATERIAL_FLAG_ONTOP, false );
 		VisualServer::get_singleton()->fixed_material_set_flag(indicator_mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
 		VisualServer::get_singleton()->fixed_material_set_flag(indicator_mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
@@ -3042,7 +3058,7 @@ void SpatialEditor::_init_indicators() {
 		d[VisualServer::ARRAY_COLOR]=origin_colors;
 		d[VisualServer::ARRAY_COLOR]=origin_colors;
 
 
 		VisualServer::get_singleton()->mesh_add_surface(origin,VisualServer::PRIMITIVE_LINES,d);
 		VisualServer::get_singleton()->mesh_add_surface(origin,VisualServer::PRIMITIVE_LINES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(origin,0,indicator_mat,true);
+		VisualServer::get_singleton()->mesh_surface_set_material(origin,0,indicator_mat);
 
 
 
 
 //		origin = VisualServer::get_singleton()->poly_create();
 //		origin = VisualServer::get_singleton()->poly_create();
@@ -3073,17 +3089,17 @@ void SpatialEditor::_init_indicators() {
 		cursor_points.push_back(Vector3(0,-cs,0));
 		cursor_points.push_back(Vector3(0,-cs,0));
 		cursor_points.push_back(Vector3(0,0,+cs));
 		cursor_points.push_back(Vector3(0,0,+cs));
 		cursor_points.push_back(Vector3(0,0,-cs));
 		cursor_points.push_back(Vector3(0,0,-cs));
-		RID cmat=VisualServer::get_singleton()->fixed_material_create();
-		VisualServer::get_singleton()->fixed_material_set_param(cmat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0,1,1));
-		VisualServer::get_singleton()->material_set_flag( cmat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
-		VisualServer::get_singleton()->fixed_material_set_flag(cmat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
-		VisualServer::get_singleton()->fixed_material_set_flag(cmat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
+		cursor_material=VisualServer::get_singleton()->fixed_material_create();
+		VisualServer::get_singleton()->fixed_material_set_param(cursor_material,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0,1,1));
+		VisualServer::get_singleton()->material_set_flag( cursor_material, VisualServer::MATERIAL_FLAG_UNSHADED, true );
+		VisualServer::get_singleton()->fixed_material_set_flag(cursor_material, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
+		VisualServer::get_singleton()->fixed_material_set_flag(cursor_material, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
 
 
 		Array d;
 		Array d;
 		d.resize(VS::ARRAY_MAX);
 		d.resize(VS::ARRAY_MAX);
 		d[VS::ARRAY_VERTEX]=cursor_points;
 		d[VS::ARRAY_VERTEX]=cursor_points;
 		VisualServer::get_singleton()->mesh_add_surface(cursor_mesh,VS::PRIMITIVE_LINES,d);
 		VisualServer::get_singleton()->mesh_add_surface(cursor_mesh,VS::PRIMITIVE_LINES,d);
-		VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cmat,true);
+		VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cursor_material);
 
 
 		cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_tree()->get_root()->get_world()->get_scenario());
 		cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER);
 		VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER);
@@ -3252,7 +3268,6 @@ void SpatialEditor::_init_indicators() {
 
 
 void SpatialEditor::_finish_indicators() {
 void SpatialEditor::_finish_indicators() {
 
 
-
 	VisualServer::get_singleton()->free(origin_instance);
 	VisualServer::get_singleton()->free(origin_instance);
 	VisualServer::get_singleton()->free(origin);
 	VisualServer::get_singleton()->free(origin);
 	for(int i=0;i<3;i++) {
 	for(int i=0;i<3;i++) {
@@ -3267,6 +3282,8 @@ void SpatialEditor::_finish_indicators() {
 
 
 	VisualServer::get_singleton()->free(cursor_instance);
 	VisualServer::get_singleton()->free(cursor_instance);
 	VisualServer::get_singleton()->free(cursor_mesh);
 	VisualServer::get_singleton()->free(cursor_mesh);
+	VisualServer::get_singleton()->free(indicator_mat);
+	VisualServer::get_singleton()->free(cursor_material);
 }
 }
 
 
 void SpatialEditor::_instance_scene() {
 void SpatialEditor::_instance_scene() {

+ 3 - 0
tools/editor/plugins/spatial_editor_plugin.h

@@ -224,6 +224,7 @@ private:
 	void _preview_exited_scene();
 	void _preview_exited_scene();
 	void _toggle_camera_preview(bool);
 	void _toggle_camera_preview(bool);
 	void _init_gizmo_instance(int p_idx);
 	void _init_gizmo_instance(int p_idx);
+	void _finish_gizmo_instances();
 
 
 
 
 protected:
 protected:
@@ -324,6 +325,8 @@ private:
 	RID indicators_instance;	
 	RID indicators_instance;	
 	RID cursor_mesh;
 	RID cursor_mesh;
 	RID cursor_instance;
 	RID cursor_instance;
+	RID indicator_mat;
+	RID cursor_material;
 
 
 /*
 /*
 	struct Selected {
 	struct Selected {

+ 6 - 3
tools/editor/project_settings.cpp

@@ -1280,8 +1280,10 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 	del->set_text("Del");
 	del->set_text("Del");
 	del->connect("pressed",this,"_item_del");
 	del->connect("pressed",this,"_item_del");
 
 
+	/*
 	Button *save = memnew( Button );
 	Button *save = memnew( Button );
-	//props_base->add_child(save);
+	props_base->add_child(save);
+
 	save->set_anchor(MARGIN_LEFT,ANCHOR_END);
 	save->set_anchor(MARGIN_LEFT,ANCHOR_END);
 	save->set_anchor(MARGIN_RIGHT,ANCHOR_END);
 	save->set_anchor(MARGIN_RIGHT,ANCHOR_END);
 	save->set_anchor(MARGIN_TOP,ANCHOR_END);
 	save->set_anchor(MARGIN_TOP,ANCHOR_END);
@@ -1290,7 +1292,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 	save->set_end( Point2(10,20) );
 	save->set_end( Point2(10,20) );
 	save->set_text("Save");
 	save->set_text("Save");
 	save->connect("pressed",this,"_save");
 	save->connect("pressed",this,"_save");
-
+*/
 	popup_platform = memnew( MenuButton );
 	popup_platform = memnew( MenuButton );
 	popup_platform->set_text("Copy To Platform..");
 	popup_platform->set_text("Copy To Platform..");
 	popup_platform->set_disabled(true);
 	popup_platform->set_disabled(true);
@@ -1409,6 +1411,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 
 
 	device_input->add_child(device_index);
 	device_input->add_child(device_index);
 
 
+	/*
 	save = memnew( Button );
 	save = memnew( Button );
 	input_base->add_child(save);
 	input_base->add_child(save);
 	save->set_anchor(MARGIN_LEFT,ANCHOR_END);
 	save->set_anchor(MARGIN_LEFT,ANCHOR_END);
@@ -1419,7 +1422,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
 	save->set_end( Point2(10,20) );
 	save->set_end( Point2(10,20) );
 	save->set_text("Save");
 	save->set_text("Save");
 	save->connect("pressed",this,"_save");
 	save->connect("pressed",this,"_save");
-
+*/
 	setting=false;
 	setting=false;
 
 
 	//translations
 	//translations