瀏覽代碼

Reduce unnecessary COW on Vector by make writing explicit

This commit makes operator[] on Vector const and adds a write proxy to it.  From
now on writes to Vectors need to happen through the .write proxy. So for
instance:

Vector<int> vec;
vec.push_back(10);
std::cout << vec[0] << std::endl;
vec.write[0] = 20;

Failing to use the .write proxy will cause a compilation error.

In addition COWable datatypes can now embed a CowData pointer to their data.
This means that String, CharString, and VMap no longer use or derive from
Vector.

_ALWAYS_INLINE_ and _FORCE_INLINE_ are now equivalent for debug and non-debug
builds. This is a lot faster for Vector in the editor and while running tests.
The reason why this difference used to exist is because force-inlined methods
used to give a bad debugging experience. After extensive testing with modern
compilers this is no longer the case.
Hein-Pieter van Braam 7 年之前
父節點
當前提交
0e29f7974b
共有 100 個文件被更改,包括 1060 次插入942 次删除
  1. 1 1
      core/array.cpp
  2. 91 91
      core/class_db.cpp
  3. 6 6
      core/compressed_translation.cpp
  4. 332 0
      core/cowdata.h
  5. 6 6
      core/io/file_access_encrypted.cpp
  6. 1 1
      core/io/file_access_memory.cpp
  7. 5 5
      core/io/file_access_network.cpp
  8. 1 1
      core/io/http_client.cpp
  9. 18 18
      core/io/multiplayer_api.cpp
  10. 4 4
      core/io/packet_peer.cpp
  11. 1 1
      core/io/pck_packer.cpp
  12. 2 2
      core/io/resource_format_binary.cpp
  13. 1 1
      core/io/resource_loader.cpp
  14. 1 1
      core/io/stream_peer.cpp
  15. 11 11
      core/math/bsp_tree.cpp
  16. 3 3
      core/math/delaunay.h
  17. 11 11
      core/math/geometry.cpp
  18. 2 2
      core/math/geometry.h
  19. 4 4
      core/math/quick_hull.cpp
  20. 3 3
      core/math/triangulate.cpp
  21. 1 1
      core/method_bind.h
  22. 6 6
      core/method_ptrcall.h
  23. 1 1
      core/node_path.cpp
  24. 4 4
      core/object.cpp
  25. 4 4
      core/os/file_access.cpp
  26. 1 1
      core/os/threaded_array_processor.h
  27. 9 9
      core/packed_data_container.cpp
  28. 2 2
      core/project_settings.cpp
  29. 3 3
      core/ring_buffer.h
  30. 2 2
      core/script_debugger_local.cpp
  31. 4 4
      core/script_debugger_remote.cpp
  32. 1 1
      core/string_buffer.h
  33. 1 5
      core/typedefs.h
  34. 13 13
      core/undo_redo.cpp
  35. 19 9
      core/ustring.cpp
  36. 44 7
      core/ustring.h
  37. 11 11
      core/variant.cpp
  38. 1 1
      core/variant_call.cpp
  39. 59 323
      core/vector.h
  40. 28 21
      core/vmap.h
  41. 1 1
      core/vset.h
  42. 2 2
      drivers/alsa/audio_driver_alsa.cpp
  43. 1 1
      drivers/dummy/rasterizer_dummy.h
  44. 3 3
      drivers/gles2/shader_compiler_gles2.cpp
  45. 2 2
      drivers/gles2/shader_gles2.cpp
  46. 14 14
      drivers/gles3/rasterizer_scene_gles3.cpp
  47. 44 44
      drivers/gles3/rasterizer_storage_gles3.cpp
  48. 5 5
      drivers/gles3/shader_compiler_gles3.cpp
  49. 1 1
      drivers/gles3/shader_gles3.cpp
  50. 4 4
      drivers/pulseaudio/audio_driver_pulseaudio.cpp
  51. 1 1
      drivers/wasapi/audio_driver_wasapi.cpp
  52. 6 6
      editor/animation_track_editor.cpp
  53. 4 4
      editor/animation_track_editor_plugins.cpp
  54. 2 2
      editor/audio_stream_preview.cpp
  55. 1 1
      editor/code_editor.cpp
  56. 32 32
      editor/collada/collada.cpp
  57. 2 2
      editor/collada/collada.h
  58. 1 1
      editor/connections_dialog.cpp
  59. 14 14
      editor/doc/doc_data.cpp
  60. 1 1
      editor/editor_autoload_settings.cpp
  61. 14 14
      editor/editor_data.cpp
  62. 12 12
      editor/editor_export.cpp
  63. 2 2
      editor/editor_file_dialog.cpp
  64. 1 1
      editor/editor_node.cpp
  65. 13 13
      editor/editor_profiler.cpp
  66. 1 1
      editor/editor_profiler.h
  67. 2 2
      editor/editor_resource_preview.cpp
  68. 2 2
      editor/editor_resource_preview.h
  69. 1 1
      editor/editor_settings.cpp
  70. 2 2
      editor/fileserver/editor_file_server.cpp
  71. 1 1
      editor/find_in_files.cpp
  72. 25 25
      editor/import/editor_import_collada.cpp
  73. 18 18
      editor/import/editor_scene_importer_gltf.cpp
  74. 1 1
      editor/import/resource_importer_csv_translation.cpp
  75. 1 1
      editor/import/resource_importer_scene.cpp
  76. 10 10
      editor/import/resource_importer_wav.cpp
  77. 2 2
      editor/plugins/abstract_polygon_2d_editor.cpp
  78. 1 1
      editor/plugins/animation_blend_space_2d_editor.cpp
  79. 2 2
      editor/plugins/animation_player_editor_plugin.cpp
  80. 2 2
      editor/plugins/animation_state_machine_editor.cpp
  81. 1 1
      editor/plugins/asset_library_editor_plugin.cpp
  82. 2 2
      editor/plugins/audio_stream_editor_plugin.cpp
  83. 1 1
      editor/plugins/canvas_item_editor_plugin.cpp
  84. 1 1
      editor/plugins/collision_polygon_editor_plugin.cpp
  85. 10 10
      editor/plugins/collision_shape_2d_editor_plugin.cpp
  86. 1 1
      editor/plugins/light_occluder_2d_editor_plugin.cpp
  87. 11 11
      editor/plugins/particles_2d_editor_plugin.cpp
  88. 6 6
      editor/plugins/script_editor_plugin.cpp
  89. 3 3
      editor/plugins/skeleton_editor_plugin.cpp
  90. 9 9
      editor/plugins/spatial_editor_plugin.cpp
  91. 1 1
      editor/plugins/sprite_editor_plugin.cpp
  92. 6 6
      editor/plugins/tile_map_editor_plugin.cpp
  93. 1 1
      editor/plugins/visual_shader_editor_plugin.cpp
  94. 2 2
      editor/project_manager.cpp
  95. 2 2
      editor/project_settings_editor.cpp
  96. 1 1
      editor/property_editor.cpp
  97. 1 1
      editor/property_editor.h
  98. 1 1
      editor/quick_open.cpp
  99. 6 6
      editor/script_editor_debugger.cpp
  100. 22 22
      editor/spatial_editor_gizmos.cpp

+ 1 - 1
core/array.cpp

@@ -72,7 +72,7 @@ void Array::_unref() const {
 
 
 Variant &Array::operator[](int p_idx) {
 Variant &Array::operator[](int p_idx) {
 
 
-	return _p->array[p_idx];
+	return _p->array.write[p_idx];
 }
 }
 
 
 const Variant &Array::operator[](int p_idx) const {
 const Variant &Array::operator[](int p_idx) const {

+ 91 - 91
core/class_db.cpp

@@ -58,8 +58,8 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(2);
 	md.args.resize(2);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
 	return md;
 	return md;
 }
 }
 
 
@@ -68,9 +68,9 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(3);
 	md.args.resize(3);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
 	return md;
 	return md;
 }
 }
 
 
@@ -79,10 +79,10 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(4);
 	md.args.resize(4);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
 	return md;
 	return md;
 }
 }
 
 
@@ -91,11 +91,11 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(5);
 	md.args.resize(5);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
 	return md;
 	return md;
 }
 }
 
 
@@ -104,12 +104,12 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(6);
 	md.args.resize(6);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
 	return md;
 	return md;
 }
 }
 
 
@@ -118,13 +118,13 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(7);
 	md.args.resize(7);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
 	return md;
 	return md;
 }
 }
 
 
@@ -133,14 +133,14 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(8);
 	md.args.resize(8);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
-	md.args[7] = StaticCString::create(p_arg8);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
+	md.args.write[7] = StaticCString::create(p_arg8);
 	return md;
 	return md;
 }
 }
 
 
@@ -149,15 +149,15 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(9);
 	md.args.resize(9);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
-	md.args[7] = StaticCString::create(p_arg8);
-	md.args[8] = StaticCString::create(p_arg9);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
+	md.args.write[7] = StaticCString::create(p_arg8);
+	md.args.write[8] = StaticCString::create(p_arg9);
 	return md;
 	return md;
 }
 }
 
 
@@ -166,16 +166,16 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(10);
 	md.args.resize(10);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
-	md.args[7] = StaticCString::create(p_arg8);
-	md.args[8] = StaticCString::create(p_arg9);
-	md.args[9] = StaticCString::create(p_arg10);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
+	md.args.write[7] = StaticCString::create(p_arg8);
+	md.args.write[8] = StaticCString::create(p_arg9);
+	md.args.write[9] = StaticCString::create(p_arg10);
 	return md;
 	return md;
 }
 }
 
 
@@ -184,17 +184,17 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(11);
 	md.args.resize(11);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
-	md.args[7] = StaticCString::create(p_arg8);
-	md.args[8] = StaticCString::create(p_arg9);
-	md.args[9] = StaticCString::create(p_arg10);
-	md.args[10] = StaticCString::create(p_arg11);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
+	md.args.write[7] = StaticCString::create(p_arg8);
+	md.args.write[8] = StaticCString::create(p_arg9);
+	md.args.write[9] = StaticCString::create(p_arg10);
+	md.args.write[10] = StaticCString::create(p_arg11);
 	return md;
 	return md;
 }
 }
 
 
@@ -203,18 +203,18 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(12);
 	md.args.resize(12);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
-	md.args[7] = StaticCString::create(p_arg8);
-	md.args[8] = StaticCString::create(p_arg9);
-	md.args[9] = StaticCString::create(p_arg10);
-	md.args[10] = StaticCString::create(p_arg11);
-	md.args[11] = StaticCString::create(p_arg12);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
+	md.args.write[7] = StaticCString::create(p_arg8);
+	md.args.write[8] = StaticCString::create(p_arg9);
+	md.args.write[9] = StaticCString::create(p_arg10);
+	md.args.write[10] = StaticCString::create(p_arg11);
+	md.args.write[11] = StaticCString::create(p_arg12);
 	return md;
 	return md;
 }
 }
 
 
@@ -223,19 +223,19 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
 	MethodDefinition md;
 	MethodDefinition md;
 	md.name = StaticCString::create(p_name);
 	md.name = StaticCString::create(p_name);
 	md.args.resize(13);
 	md.args.resize(13);
-	md.args[0] = StaticCString::create(p_arg1);
-	md.args[1] = StaticCString::create(p_arg2);
-	md.args[2] = StaticCString::create(p_arg3);
-	md.args[3] = StaticCString::create(p_arg4);
-	md.args[4] = StaticCString::create(p_arg5);
-	md.args[5] = StaticCString::create(p_arg6);
-	md.args[6] = StaticCString::create(p_arg7);
-	md.args[7] = StaticCString::create(p_arg8);
-	md.args[8] = StaticCString::create(p_arg9);
-	md.args[9] = StaticCString::create(p_arg10);
-	md.args[10] = StaticCString::create(p_arg11);
-	md.args[11] = StaticCString::create(p_arg12);
-	md.args[12] = StaticCString::create(p_arg13);
+	md.args.write[0] = StaticCString::create(p_arg1);
+	md.args.write[1] = StaticCString::create(p_arg2);
+	md.args.write[2] = StaticCString::create(p_arg3);
+	md.args.write[3] = StaticCString::create(p_arg4);
+	md.args.write[4] = StaticCString::create(p_arg5);
+	md.args.write[5] = StaticCString::create(p_arg6);
+	md.args.write[6] = StaticCString::create(p_arg7);
+	md.args.write[7] = StaticCString::create(p_arg8);
+	md.args.write[8] = StaticCString::create(p_arg9);
+	md.args.write[9] = StaticCString::create(p_arg10);
+	md.args.write[10] = StaticCString::create(p_arg11);
+	md.args.write[11] = StaticCString::create(p_arg12);
+	md.args.write[12] = StaticCString::create(p_arg13);
 	return md;
 	return md;
 }
 }
 
 
@@ -1246,7 +1246,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
 	defvals.resize(p_defcount);
 	defvals.resize(p_defcount);
 	for (int i = 0; i < p_defcount; i++) {
 	for (int i = 0; i < p_defcount; i++) {
 
 
-		defvals[i] = *p_defs[p_defcount - i - 1];
+		defvals.write[i] = *p_defs[p_defcount - i - 1];
 	}
 	}
 
 
 	p_bind->set_default_arguments(defvals);
 	p_bind->set_default_arguments(defvals);

+ 6 - 6
core/compressed_translation.cpp

@@ -73,7 +73,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
 		Pair<int, CharString> p;
 		Pair<int, CharString> p;
 		p.first = idx;
 		p.first = idx;
 		p.second = cs;
 		p.second = cs;
-		buckets[h % size].push_back(p);
+		buckets.write[h % size].push_back(p);
 
 
 		//compress string
 		//compress string
 		CharString src_s = p_from->get_message(E->get()).operator String().utf8();
 		CharString src_s = p_from->get_message(E->get()).operator String().utf8();
@@ -100,7 +100,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
 			ps.compressed[0] = 0;
 			ps.compressed[0] = 0;
 		}
 		}
 
 
-		compressed[idx] = ps;
+		compressed.write[idx] = ps;
 		total_compression_size += ps.compressed.size();
 		total_compression_size += ps.compressed.size();
 		total_string_size += src_s.size();
 		total_string_size += src_s.size();
 		idx++;
 		idx++;
@@ -111,8 +111,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
 
 
 	for (int i = 0; i < size; i++) {
 	for (int i = 0; i < size; i++) {
 
 
-		Vector<Pair<int, CharString> > &b = buckets[i];
-		Map<uint32_t, int> &t = table[i];
+		const Vector<Pair<int, CharString> > &b = buckets[i];
+		Map<uint32_t, int> &t = table.write[i];
 
 
 		if (b.size() == 0)
 		if (b.size() == 0)
 			continue;
 			continue;
@@ -136,7 +136,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
 			}
 			}
 		}
 		}
 
 
-		hfunc_table[i] = d;
+		hfunc_table.write[i] = d;
 		bucket_table_size += 2 + b.size() * 4;
 		bucket_table_size += 2 + b.size() * 4;
 	}
 	}
 
 
@@ -157,7 +157,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
 
 
 	for (int i = 0; i < size; i++) {
 	for (int i = 0; i < size; i++) {
 
 
-		Map<uint32_t, int> &t = table[i];
+		const Map<uint32_t, int> &t = table[i];
 		if (t.size() == 0) {
 		if (t.size() == 0) {
 			htw[i] = 0xFFFFFFFF; //nothing
 			htw[i] = 0xFFFFFFFF; //nothing
 			continue;
 			continue;

+ 332 - 0
core/cowdata.h

@@ -0,0 +1,332 @@
+/*************************************************************************/
+/*  cowdata.h                                                            */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef COWDATA_H_
+#define COWDATA_H_
+
+#include "os/memory.h"
+#include "safe_refcount.h"
+
+template <class T>
+class Vector;
+class String;
+class CharString;
+template <class T, class V>
+class VMap;
+
+template <class T>
+class CowData {
+	template <class TV>
+	friend class Vector;
+	friend class String;
+	friend class CharString;
+	template <class TV, class VV>
+	friend class VMap;
+
+private:
+	mutable T *_ptr;
+
+	// internal helpers
+
+	_FORCE_INLINE_ uint32_t *_get_refcount() const {
+
+		if (!_ptr)
+			return NULL;
+
+		return reinterpret_cast<uint32_t *>(_ptr) - 2;
+	}
+
+	_FORCE_INLINE_ uint32_t *_get_size() const {
+
+		if (!_ptr)
+			return NULL;
+
+		return reinterpret_cast<uint32_t *>(_ptr) - 1;
+	}
+
+	_FORCE_INLINE_ T *_get_data() const {
+
+		if (!_ptr)
+			return NULL;
+		return reinterpret_cast<T *>(_ptr);
+	}
+
+	_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
+		//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+		return next_power_of_2(p_elements * sizeof(T));
+	}
+
+	_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
+#if defined(_add_overflow) && defined(_mul_overflow)
+		size_t o;
+		size_t p;
+		if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
+		*out = next_power_of_2(o);
+		if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
+		return true;
+#else
+		// Speed is more important than correctness here, do the operations unchecked
+		// and hope the best
+		*out = _get_alloc_size(p_elements);
+		return true;
+#endif
+	}
+
+	void _unref(void *p_data);
+	void _ref(const CowData &p_from);
+	void _copy_on_write();
+
+public:
+	void operator=(const CowData<T> &p_from) { _ref(p_from); }
+
+	_FORCE_INLINE_ T *ptrw() {
+		_copy_on_write();
+		return (T *)_get_data();
+	}
+
+	_FORCE_INLINE_ const T *ptr() const {
+		return _get_data();
+	}
+
+	_FORCE_INLINE_ int size() const {
+		uint32_t *size = (uint32_t *)_get_size();
+		if (size)
+			return *size;
+		else
+			return 0;
+	}
+
+	_FORCE_INLINE_ void clear() { resize(0); }
+	_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
+
+	_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
+
+		CRASH_BAD_INDEX(p_index, size());
+		_copy_on_write();
+		_get_data()[p_index] = p_elem;
+	}
+
+	_FORCE_INLINE_ T &get_m(int p_index) {
+
+		CRASH_BAD_INDEX(p_index, size());
+		_copy_on_write();
+		return _get_data()[p_index];
+	}
+
+	_FORCE_INLINE_ const T &get(int p_index) const {
+
+		CRASH_BAD_INDEX(p_index, size());
+
+		return _get_data()[p_index];
+	}
+
+	Error resize(int p_size);
+
+	_FORCE_INLINE_ void remove(int p_index) {
+
+		ERR_FAIL_INDEX(p_index, size());
+		T *p = ptrw();
+		int len = size();
+		for (int i = p_index; i < len - 1; i++) {
+
+			p[i] = p[i + 1];
+		};
+
+		resize(len - 1);
+	};
+
+	Error insert(int p_pos, const T &p_val) {
+
+		ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
+		resize(size() + 1);
+		for (int i = (size() - 1); i > p_pos; i--)
+			set(i, get(i - 1));
+		set(p_pos, p_val);
+
+		return OK;
+	};
+
+	_FORCE_INLINE_ CowData();
+	_FORCE_INLINE_ ~CowData();
+	_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
+};
+
+template <class T>
+void CowData<T>::_unref(void *p_data) {
+
+	if (!p_data)
+		return;
+
+	uint32_t *refc = _get_refcount();
+
+	if (atomic_decrement(refc) > 0)
+		return; // still in use
+	// clean up
+
+	uint32_t *count = _get_size();
+	T *data = (T *)(count + 1);
+
+	for (uint32_t i = 0; i < *count; ++i) {
+		// call destructors
+		data[i].~T();
+	}
+
+	// free mem
+	Memory::free_static((uint8_t *)p_data, true);
+}
+
+template <class T>
+void CowData<T>::_copy_on_write() {
+
+	if (!_ptr)
+		return;
+
+	uint32_t *refc = _get_refcount();
+
+	if (unlikely(*refc > 1)) {
+		/* in use by more than me */
+		uint32_t current_size = *_get_size();
+
+		uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
+
+		*(mem_new - 2) = 1; //refcount
+		*(mem_new - 1) = current_size; //size
+
+		T *_data = (T *)(mem_new);
+
+		// initialize new elements
+		for (uint32_t i = 0; i < current_size; i++) {
+
+			memnew_placement(&_data[i], T(_get_data()[i]));
+		}
+
+		_unref(_ptr);
+		_ptr = _data;
+	}
+}
+
+template <class T>
+Error CowData<T>::resize(int p_size) {
+
+	ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
+
+	if (p_size == size())
+		return OK;
+
+	if (p_size == 0) {
+		// wants to clean up
+		_unref(_ptr);
+		_ptr = NULL;
+		return OK;
+	}
+
+	// possibly changing size, copy on write
+	_copy_on_write();
+
+	size_t alloc_size;
+	ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
+
+	if (p_size > size()) {
+
+		if (size() == 0) {
+			// alloc from scratch
+			uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
+			ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
+			*(ptr - 1) = 0; //size, currently none
+			*(ptr - 2) = 1; //refcount
+
+			_ptr = (T *)ptr;
+
+		} else {
+			void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
+			ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
+			_ptr = (T *)(_ptrnew);
+		}
+
+		// construct the newly created elements
+		T *elems = _get_data();
+
+		for (int i = *_get_size(); i < p_size; i++) {
+
+			memnew_placement(&elems[i], T);
+		}
+
+		*_get_size() = p_size;
+
+	} else if (p_size < size()) {
+
+		// deinitialize no longer needed elements
+		for (uint32_t i = p_size; i < *_get_size(); i++) {
+
+			T *t = &_get_data()[i];
+			t->~T();
+		}
+
+		void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
+		ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
+
+		_ptr = (T *)(_ptrnew);
+
+		*_get_size() = p_size;
+	}
+
+	return OK;
+}
+
+template <class T>
+void CowData<T>::_ref(const CowData &p_from) {
+
+	if (_ptr == p_from._ptr)
+		return; // self assign, do nothing.
+
+	_unref(_ptr);
+	_ptr = NULL;
+
+	if (!p_from._ptr)
+		return; //nothing to do
+
+	if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
+		_ptr = p_from._ptr;
+	}
+}
+
+template <class T>
+CowData<T>::CowData() {
+
+	_ptr = NULL;
+}
+
+template <class T>
+CowData<T>::~CowData() {
+
+	_unref(_ptr);
+}
+
+#endif /* COW_H_ */

+ 6 - 6
core/io/file_access_encrypted.cpp

@@ -89,7 +89,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
 
 
 		for (size_t i = 0; i < ds; i += 16) {
 		for (size_t i = 0; i < ds; i += 16) {
 
 
-			aes256_decrypt_ecb(&ctx, &data[i]);
+			aes256_decrypt_ecb(&ctx, &data.write[i]);
 		}
 		}
 
 
 		aes256_done(&ctx);
 		aes256_done(&ctx);
@@ -117,7 +117,7 @@ Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const Str
 	key.resize(32);
 	key.resize(32);
 	for (int i = 0; i < 32; i++) {
 	for (int i = 0; i < 32; i++) {
 
 
-		key[i] = cs[i];
+		key.write[i] = cs[i];
 	}
 	}
 
 
 	return open_and_parse(p_base, key, p_mode);
 	return open_and_parse(p_base, key, p_mode);
@@ -148,7 +148,7 @@ void FileAccessEncrypted::close() {
 		compressed.resize(len);
 		compressed.resize(len);
 		zeromem(compressed.ptrw(), len);
 		zeromem(compressed.ptrw(), len);
 		for (int i = 0; i < data.size(); i++) {
 		for (int i = 0; i < data.size(); i++) {
-			compressed[i] = data[i];
+			compressed.write[i] = data[i];
 		}
 		}
 
 
 		aes256_context ctx;
 		aes256_context ctx;
@@ -156,7 +156,7 @@ void FileAccessEncrypted::close() {
 
 
 		for (size_t i = 0; i < len; i += 16) {
 		for (size_t i = 0; i < len; i += 16) {
 
 
-			aes256_encrypt_ecb(&ctx, &compressed[i]);
+			aes256_encrypt_ecb(&ctx, &compressed.write[i]);
 		}
 		}
 
 
 		aes256_done(&ctx);
 		aes256_done(&ctx);
@@ -263,7 +263,7 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
 		data.resize(pos + p_length);
 		data.resize(pos + p_length);
 		for (int i = 0; i < p_length; i++) {
 		for (int i = 0; i < p_length; i++) {
 
 
-			data[pos + i] = p_src[i];
+			data.write[pos + i] = p_src[i];
 		}
 		}
 		pos += p_length;
 		pos += p_length;
 	}
 	}
@@ -280,7 +280,7 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
 	ERR_FAIL_COND(!writing);
 	ERR_FAIL_COND(!writing);
 
 
 	if (pos < data.size()) {
 	if (pos < data.size()) {
-		data[pos] = p_dest;
+		data.write[pos] = p_dest;
 		pos++;
 		pos++;
 	} else if (pos == data.size()) {
 	} else if (pos == data.size()) {
 		data.push_back(p_dest);
 		data.push_back(p_dest);

+ 1 - 1
core/io/file_access_memory.cpp

@@ -92,7 +92,7 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
 	Map<String, Vector<uint8_t> >::Element *E = files->find(name);
 	Map<String, Vector<uint8_t> >::Element *E = files->find(name);
 	ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
 	ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
 
 
-	data = &(E->get()[0]);
+	data = E->get().ptrw();
 	length = E->get().size();
 	length = E->get().size();
 	pos = 0;
 	pos = 0;
 
 

+ 5 - 5
core/io/file_access_network.cpp

@@ -258,8 +258,8 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
 	}
 	}
 
 
 	buffer_mutex->lock();
 	buffer_mutex->lock();
-	pages[page].buffer = p_block;
-	pages[page].queued = false;
+	pages.write[page].buffer = p_block;
+	pages.write[page].queued = false;
 	buffer_mutex->unlock();
 	buffer_mutex->unlock();
 
 
 	if (waiting_on_page == page) {
 	if (waiting_on_page == page) {
@@ -389,7 +389,7 @@ void FileAccessNetwork::_queue_page(int p_page) const {
 		br.offset = size_t(p_page) * page_size;
 		br.offset = size_t(p_page) * page_size;
 		br.size = page_size;
 		br.size = page_size;
 		nc->block_requests.push_back(br);
 		nc->block_requests.push_back(br);
-		pages[p_page].queued = true;
+		pages.write[p_page].queued = true;
 		nc->blockrequest_mutex->unlock();
 		nc->blockrequest_mutex->unlock();
 		DEBUG_PRINT("QUEUE PAGE POST");
 		DEBUG_PRINT("QUEUE PAGE POST");
 		nc->sem->post();
 		nc->sem->post();
@@ -433,12 +433,12 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
 
 
 					_queue_page(page + j);
 					_queue_page(page + j);
 				}
 				}
-				buff = pages[page].buffer.ptrw();
+				buff = pages.write[page].buffer.ptrw();
 				//queue pages
 				//queue pages
 				buffer_mutex->unlock();
 				buffer_mutex->unlock();
 			}
 			}
 
 
-			buff = pages[page].buffer.ptrw();
+			buff = pages.write[page].buffer.ptrw();
 			last_page_buff = buff;
 			last_page_buff = buff;
 			last_page = page;
 			last_page = page;
 		}
 		}

+ 1 - 1
core/io/http_client.cpp

@@ -552,7 +552,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
 			} else {
 			} else {
 
 
 				int rec = 0;
 				int rec = 0;
-				err = _get_http_data(&chunk[chunk.size() - chunk_left], chunk_left, rec);
+				err = _get_http_data(&chunk.write[chunk.size() - chunk_left], chunk_left, rec);
 				if (rec == 0) {
 				if (rec == 0) {
 					break;
 					break;
 				}
 				}

+ 18 - 18
core/io/multiplayer_api.cpp

@@ -282,10 +282,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
 
 
 		ERR_FAIL_COND(p_offset >= p_packet_len);
 		ERR_FAIL_COND(p_offset >= p_packet_len);
 		int vlen;
 		int vlen;
-		Error err = decode_variant(args[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
+		Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
 		ERR_FAIL_COND(err != OK);
 		ERR_FAIL_COND(err != OK);
 		//args[i]=p_packet[3+i];
 		//args[i]=p_packet[3+i];
-		argp[i] = &args[i];
+		argp.write[i] = &args[i];
 		p_offset += vlen;
 		p_offset += vlen;
 	}
 	}
 
 
@@ -354,8 +354,8 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
 	Vector<uint8_t> packet;
 	Vector<uint8_t> packet;
 
 
 	packet.resize(1 + len);
 	packet.resize(1 + len);
-	packet[0] = NETWORK_COMMAND_CONFIRM_PATH;
-	encode_cstring(pname.get_data(), &packet[1]);
+	packet.write[0] = NETWORK_COMMAND_CONFIRM_PATH;
+	encode_cstring(pname.get_data(), &packet.write[1]);
 
 
 	network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
 	network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
 	network_peer->set_target_peer(p_from);
 	network_peer->set_target_peer(p_from);
@@ -415,9 +415,9 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
 		Vector<uint8_t> packet;
 		Vector<uint8_t> packet;
 
 
 		packet.resize(1 + 4 + len);
 		packet.resize(1 + 4 + len);
-		packet[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
-		encode_uint32(psc->id, &packet[1]);
-		encode_cstring(pname.get_data(), &packet[5]);
+		packet.write[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
+		encode_uint32(psc->id, &packet.write[1]);
+		encode_cstring(pname.get_data(), &packet.write[5]);
 
 
 		network_peer->set_target_peer(E->get()); //to all of you
 		network_peer->set_target_peer(E->get()); //to all of you
 		network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
 		network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
@@ -482,19 +482,19 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
 
 
 	//encode type
 	//encode type
 	MAKE_ROOM(1);
 	MAKE_ROOM(1);
-	packet_cache[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
+	packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
 	ofs += 1;
 	ofs += 1;
 
 
 	//encode ID
 	//encode ID
 	MAKE_ROOM(ofs + 4);
 	MAKE_ROOM(ofs + 4);
-	encode_uint32(psc->id, &(packet_cache[ofs]));
+	encode_uint32(psc->id, &(packet_cache.write[ofs]));
 	ofs += 4;
 	ofs += 4;
 
 
 	//encode function name
 	//encode function name
 	CharString name = String(p_name).utf8();
 	CharString name = String(p_name).utf8();
 	int len = encode_cstring(name.get_data(), NULL);
 	int len = encode_cstring(name.get_data(), NULL);
 	MAKE_ROOM(ofs + len);
 	MAKE_ROOM(ofs + len);
-	encode_cstring(name.get_data(), &(packet_cache[ofs]));
+	encode_cstring(name.get_data(), &(packet_cache.write[ofs]));
 	ofs += len;
 	ofs += len;
 
 
 	if (p_set) {
 	if (p_set) {
@@ -502,19 +502,19 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
 		Error err = encode_variant(*p_arg[0], NULL, len);
 		Error err = encode_variant(*p_arg[0], NULL, len);
 		ERR_FAIL_COND(err != OK);
 		ERR_FAIL_COND(err != OK);
 		MAKE_ROOM(ofs + len);
 		MAKE_ROOM(ofs + len);
-		encode_variant(*p_arg[0], &(packet_cache[ofs]), len);
+		encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len);
 		ofs += len;
 		ofs += len;
 
 
 	} else {
 	} else {
 		//call arguments
 		//call arguments
 		MAKE_ROOM(ofs + 1);
 		MAKE_ROOM(ofs + 1);
-		packet_cache[ofs] = p_argcount;
+		packet_cache.write[ofs] = p_argcount;
 		ofs += 1;
 		ofs += 1;
 		for (int i = 0; i < p_argcount; i++) {
 		for (int i = 0; i < p_argcount; i++) {
 			Error err = encode_variant(*p_arg[i], NULL, len);
 			Error err = encode_variant(*p_arg[i], NULL, len);
 			ERR_FAIL_COND(err != OK);
 			ERR_FAIL_COND(err != OK);
 			MAKE_ROOM(ofs + len);
 			MAKE_ROOM(ofs + len);
-			encode_variant(*p_arg[i], &(packet_cache[ofs]), len);
+			encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
 			ofs += len;
 			ofs += len;
 		}
 		}
 	}
 	}
@@ -537,7 +537,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
 		CharString pname = String(from_path).utf8();
 		CharString pname = String(from_path).utf8();
 		int path_len = encode_cstring(pname.get_data(), NULL);
 		int path_len = encode_cstring(pname.get_data(), NULL);
 		MAKE_ROOM(ofs + path_len);
 		MAKE_ROOM(ofs + path_len);
-		encode_cstring(pname.get_data(), &(packet_cache[ofs]));
+		encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
 
 
 		for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
 		for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
 
 
@@ -554,11 +554,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
 
 
 			if (F->get() == true) {
 			if (F->get() == true) {
 				//this one confirmed path, so use id
 				//this one confirmed path, so use id
-				encode_uint32(psc->id, &(packet_cache[1]));
+				encode_uint32(psc->id, &(packet_cache.write[1]));
 				network_peer->put_packet(packet_cache.ptr(), ofs);
 				network_peer->put_packet(packet_cache.ptr(), ofs);
 			} else {
 			} else {
 				//this one did not confirm path yet, so use entire path (sorry!)
 				//this one did not confirm path yet, so use entire path (sorry!)
-				encode_uint32(0x80000000 | ofs, &(packet_cache[1])); //offset to path and flag
+				encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); //offset to path and flag
 				network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
 				network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
 			}
 			}
 		}
 		}
@@ -712,8 +712,8 @@ Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, Networked
 
 
 	MAKE_ROOM(p_data.size() + 1);
 	MAKE_ROOM(p_data.size() + 1);
 	PoolVector<uint8_t>::Read r = p_data.read();
 	PoolVector<uint8_t>::Read r = p_data.read();
-	packet_cache[0] = NETWORK_COMMAND_RAW;
-	memcpy(&packet_cache[1], &r[0], p_data.size());
+	packet_cache.write[0] = NETWORK_COMMAND_RAW;
+	memcpy(&packet_cache.write[1], &r[0], p_data.size());
 
 
 	network_peer->set_target_peer(p_to);
 	network_peer->set_target_peer(p_to);
 	network_peer->set_transfer_mode(p_mode);
 	network_peer->set_transfer_mode(p_mode);

+ 4 - 4
core/io/packet_peer.cpp

@@ -173,7 +173,7 @@ Error PacketPeerStream::_poll_buffer() const {
 
 
 	int read = 0;
 	int read = 0;
 	ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
 	ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
-	Error err = peer->get_partial_data(&input_buffer[0], ring_buffer.space_left(), read);
+	Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read);
 	if (err)
 	if (err)
 		return err;
 		return err;
 	if (read == 0)
 	if (read == 0)
@@ -226,7 +226,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size)
 
 
 	ERR_FAIL_COND_V(input_buffer.size() < len, ERR_UNAVAILABLE);
 	ERR_FAIL_COND_V(input_buffer.size() < len, ERR_UNAVAILABLE);
 	ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
 	ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
-	ring_buffer.read(&input_buffer[0], len); // read packet
+	ring_buffer.read(input_buffer.ptrw(), len); // read packet
 
 
 	*r_buffer = &input_buffer[0];
 	*r_buffer = &input_buffer[0];
 	r_buffer_size = len;
 	r_buffer_size = len;
@@ -247,8 +247,8 @@ Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
 	ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
 	ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
 	ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
 	ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
 
 
-	encode_uint32(p_buffer_size, &output_buffer[0]);
-	uint8_t *dst = &output_buffer[4];
+	encode_uint32(p_buffer_size, output_buffer.ptrw());
+	uint8_t *dst = &output_buffer.write[4];
 	for (int i = 0; i < p_buffer_size; i++)
 	for (int i = 0; i < p_buffer_size; i++)
 		dst[i] = p_buffer[i];
 		dst[i] = p_buffer[i];
 
 

+ 1 - 1
core/io/pck_packer.cpp

@@ -120,7 +120,7 @@ Error PCKPacker::flush(bool p_verbose) {
 	for (int i = 0; i < files.size(); i++) {
 	for (int i = 0; i < files.size(); i++) {
 
 
 		file->store_pascal_string(files[i].path);
 		file->store_pascal_string(files[i].path);
-		files[i].offset_offset = file->get_position();
+		files.write[i].offset_offset = file->get_position();
 		file->store_64(0); // offset
 		file->store_64(0); // offset
 		file->store_64(files[i].size); // size
 		file->store_64(files[i].size); // size
 
 

+ 2 - 2
core/io/resource_format_binary.cpp

@@ -894,7 +894,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
 	for (uint32_t i = 0; i < string_table_size; i++) {
 	for (uint32_t i = 0; i < string_table_size; i++) {
 
 
 		StringName s = get_unicode_string();
 		StringName s = get_unicode_string();
-		string_map[i] = s;
+		string_map.write[i] = s;
 	}
 	}
 
 
 	print_bl("strings: " + itos(string_table_size));
 	print_bl("strings: " + itos(string_table_size));
@@ -1834,7 +1834,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
 	save_order.resize(external_resources.size());
 	save_order.resize(external_resources.size());
 
 
 	for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
 	for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
-		save_order[E->get()] = E->key();
+		save_order.write[E->get()] = E->key();
 	}
 	}
 
 
 	for (int i = 0; i < save_order.size(); i++) {
 	for (int i = 0; i < save_order.size(); i++) {

+ 1 - 1
core/io/resource_loader.cpp

@@ -556,7 +556,7 @@ void ResourceLoader::load_translation_remaps() {
 		Vector<String> lang_remaps;
 		Vector<String> lang_remaps;
 		lang_remaps.resize(langs.size());
 		lang_remaps.resize(langs.size());
 		for (int i = 0; i < langs.size(); i++) {
 		for (int i = 0; i < langs.size(); i++) {
-			lang_remaps[i] = langs[i];
+			lang_remaps.write[i] = langs[i];
 		}
 		}
 
 
 		translation_remaps[String(E->get())] = lang_remaps;
 		translation_remaps[String(E->get())] = lang_remaps;

+ 1 - 1
core/io/stream_peer.cpp

@@ -331,7 +331,7 @@ String StreamPeer::get_string(int p_bytes) {
 	ERR_FAIL_COND_V(err != OK, String());
 	ERR_FAIL_COND_V(err != OK, String());
 	err = get_data((uint8_t *)&buf[0], p_bytes);
 	err = get_data((uint8_t *)&buf[0], p_bytes);
 	ERR_FAIL_COND_V(err != OK, String());
 	ERR_FAIL_COND_V(err != OK, String());
-	buf[p_bytes] = 0;
+	buf.write[p_bytes] = 0;
 	return buf.ptr();
 	return buf.ptr();
 }
 }
 String StreamPeer::get_utf8_string(int p_bytes) {
 String StreamPeer::get_utf8_string(int p_bytes) {

+ 11 - 11
core/math/bsp_tree.cpp

@@ -449,10 +449,10 @@ BSP_Tree::operator Variant() const {
 
 
 	for (int i = 0; i < planes.size(); i++) {
 	for (int i = 0; i < planes.size(); i++) {
 
 
-		plane_values[i * 4 + 0] = planes[i].normal.x;
-		plane_values[i * 4 + 1] = planes[i].normal.y;
-		plane_values[i * 4 + 2] = planes[i].normal.z;
-		plane_values[i * 4 + 3] = planes[i].d;
+		plane_values.write[i * 4 + 0] = planes[i].normal.x;
+		plane_values.write[i * 4 + 1] = planes[i].normal.y;
+		plane_values.write[i * 4 + 2] = planes[i].normal.z;
+		plane_values.write[i * 4 + 3] = planes[i].d;
 	}
 	}
 
 
 	d["planes"] = plane_values;
 	d["planes"] = plane_values;
@@ -498,10 +498,10 @@ BSP_Tree::BSP_Tree(const Variant &p_variant) {
 			PoolVector<real_t>::Read r = src_planes.read();
 			PoolVector<real_t>::Read r = src_planes.read();
 			for (int i = 0; i < plane_count / 4; i++) {
 			for (int i = 0; i < plane_count / 4; i++) {
 
 
-				planes[i].normal.x = r[i * 4 + 0];
-				planes[i].normal.y = r[i * 4 + 1];
-				planes[i].normal.z = r[i * 4 + 2];
-				planes[i].d = r[i * 4 + 3];
+				planes.write[i].normal.x = r[i * 4 + 0];
+				planes.write[i].normal.y = r[i * 4 + 1];
+				planes.write[i].normal.z = r[i * 4 + 2];
+				planes.write[i].d = r[i * 4 + 3];
 			}
 			}
 		}
 		}
 
 
@@ -520,9 +520,9 @@ BSP_Tree::BSP_Tree(const Variant &p_variant) {
 
 
 	for (int i = 0; i < nodes.size(); i++) {
 	for (int i = 0; i < nodes.size(); i++) {
 
 
-		nodes[i].over = r[i * 3 + 0];
-		nodes[i].under = r[i * 3 + 1];
-		nodes[i].plane = r[i * 3 + 2];
+		nodes.write[i].over = r[i * 3 + 0];
+		nodes.write[i].under = r[i * 3 + 1];
+		nodes.write[i].plane = r[i * 3 + 2];
 	}
 	}
 }
 }
 
 

+ 3 - 3
core/math/delaunay.h

@@ -92,7 +92,7 @@ public:
 
 
 			for (int j = 0; j < triangles.size(); j++) {
 			for (int j = 0; j < triangles.size(); j++) {
 				if (circum_circle_contains(points, triangles[j], i)) {
 				if (circum_circle_contains(points, triangles[j], i)) {
-					triangles[j].bad = true;
+					triangles.write[j].bad = true;
 					polygon.push_back(Edge(triangles[j].points[0], triangles[j].points[1]));
 					polygon.push_back(Edge(triangles[j].points[0], triangles[j].points[1]));
 					polygon.push_back(Edge(triangles[j].points[1], triangles[j].points[2]));
 					polygon.push_back(Edge(triangles[j].points[1], triangles[j].points[2]));
 					polygon.push_back(Edge(triangles[j].points[2], triangles[j].points[0]));
 					polygon.push_back(Edge(triangles[j].points[2], triangles[j].points[0]));
@@ -109,8 +109,8 @@ public:
 			for (int j = 0; j < polygon.size(); j++) {
 			for (int j = 0; j < polygon.size(); j++) {
 				for (int k = j + 1; k < polygon.size(); k++) {
 				for (int k = j + 1; k < polygon.size(); k++) {
 					if (edge_compare(points, polygon[j], polygon[k])) {
 					if (edge_compare(points, polygon[j], polygon[k])) {
-						polygon[j].bad = true;
-						polygon[k].bad = true;
+						polygon.write[j].bad = true;
+						polygon.write[k].bad = true;
 					}
 					}
 				}
 				}
 			}
 			}

+ 11 - 11
core/math/geometry.cpp

@@ -56,7 +56,7 @@ void Geometry::MeshData::optimize_vertices() {
 				vtx_remap[idx] = ni;
 				vtx_remap[idx] = ni;
 			}
 			}
 
 
-			faces[i].indices[j] = vtx_remap[idx];
+			faces.write[i].indices.write[j] = vtx_remap[idx];
 		}
 		}
 	}
 	}
 
 
@@ -74,8 +74,8 @@ void Geometry::MeshData::optimize_vertices() {
 			vtx_remap[b] = ni;
 			vtx_remap[b] = ni;
 		}
 		}
 
 
-		edges[i].a = vtx_remap[a];
-		edges[i].b = vtx_remap[b];
+		edges.write[i].a = vtx_remap[a];
+		edges.write[i].b = vtx_remap[b];
 	}
 	}
 
 
 	Vector<Vector3> new_vertices;
 	Vector<Vector3> new_vertices;
@@ -84,7 +84,7 @@ void Geometry::MeshData::optimize_vertices() {
 	for (int i = 0; i < vertices.size(); i++) {
 	for (int i = 0; i < vertices.size(); i++) {
 
 
 		if (vtx_remap.has(i))
 		if (vtx_remap.has(i))
-			new_vertices[vtx_remap[i]] = vertices[i];
+			new_vertices.write[vtx_remap[i]] = vertices[i];
 	}
 	}
 	vertices = new_vertices;
 	vertices = new_vertices;
 }
 }
@@ -1014,8 +1014,8 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
 	Vector<_AtlasWorkRect> wrects;
 	Vector<_AtlasWorkRect> wrects;
 	wrects.resize(p_rects.size());
 	wrects.resize(p_rects.size());
 	for (int i = 0; i < p_rects.size(); i++) {
 	for (int i = 0; i < p_rects.size(); i++) {
-		wrects[i].s = p_rects[i];
-		wrects[i].idx = i;
+		wrects.write[i].s = p_rects[i];
+		wrects.write[i].idx = i;
 	}
 	}
 	wrects.sort();
 	wrects.sort();
 	int widest = wrects[0].s.width;
 	int widest = wrects[0].s.width;
@@ -1033,7 +1033,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
 		Vector<int> hmax;
 		Vector<int> hmax;
 		hmax.resize(w);
 		hmax.resize(w);
 		for (int j = 0; j < w; j++)
 		for (int j = 0; j < w; j++)
-			hmax[j] = 0;
+			hmax.write[j] = 0;
 
 
 		//place them
 		//place them
 		int ofs = 0;
 		int ofs = 0;
@@ -1052,8 +1052,8 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
 					from_y = hmax[ofs + k];
 					from_y = hmax[ofs + k];
 			}
 			}
 
 
-			wrects[j].p.x = ofs;
-			wrects[j].p.y = from_y;
+			wrects.write[j].p.x = ofs;
+			wrects.write[j].p.y = from_y;
 			int end_h = from_y + wrects[j].s.height;
 			int end_h = from_y + wrects[j].s.height;
 			int end_w = ofs + wrects[j].s.width;
 			int end_w = ofs + wrects[j].s.width;
 			if (ofs == 0)
 			if (ofs == 0)
@@ -1061,7 +1061,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
 
 
 			for (int k = 0; k < wrects[j].s.width; k++) {
 			for (int k = 0; k < wrects[j].s.width; k++) {
 
 
-				hmax[ofs + k] = end_h;
+				hmax.write[ofs + k] = end_h;
 			}
 			}
 
 
 			if (end_h > max_h)
 			if (end_h > max_h)
@@ -1101,7 +1101,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
 
 
 	for (int i = 0; i < p_rects.size(); i++) {
 	for (int i = 0; i < p_rects.size(); i++) {
 
 
-		r_result[results[best].result[i].idx] = results[best].result[i].p;
+		r_result.write[results[best].result[i].idx] = results[best].result[i].p;
 	}
 	}
 
 
 	r_size = Size2(results[best].max_w, results[best].max_h);
 	r_size = Size2(results[best].max_w, results[best].max_h);

+ 2 - 2
core/math/geometry.h

@@ -890,14 +890,14 @@ public:
 		for (int i = 0; i < n; ++i) {
 		for (int i = 0; i < n; ++i) {
 			while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
 			while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
 				k--;
 				k--;
-			H[k++] = P[i];
+			H.write[k++] = P[i];
 		}
 		}
 
 
 		// Build upper hull
 		// Build upper hull
 		for (int i = n - 2, t = k + 1; i >= 0; i--) {
 		for (int i = n - 2, t = k + 1; i >= 0; i--) {
 			while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
 			while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
 				k--;
 				k--;
-			H[k++] = P[i];
+			H.write[k++] = P[i];
 		}
 		}
 
 
 		H.resize(k);
 		H.resize(k);

+ 4 - 4
core/math/quick_hull.cpp

@@ -61,10 +61,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
 
 
 		Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001));
 		Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001));
 		if (valid_cache.has(sp)) {
 		if (valid_cache.has(sp)) {
-			valid_points[i] = false;
+			valid_points.write[i] = false;
 			//print_line("INVALIDATED: "+itos(i));
 			//print_line("INVALIDATED: "+itos(i));
 		} else {
 		} else {
-			valid_points[i] = true;
+			valid_points.write[i] = true;
 			valid_cache.insert(sp);
 			valid_cache.insert(sp);
 		}
 		}
 	}
 	}
@@ -452,7 +452,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
 
 
 	int idx = 0;
 	int idx = 0;
 	for (List<Geometry::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) {
 	for (List<Geometry::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) {
-		r_mesh.faces[idx++] = E->get();
+		r_mesh.faces.write[idx++] = E->get();
 	}
 	}
 	r_mesh.edges.resize(ret_edges.size());
 	r_mesh.edges.resize(ret_edges.size());
 	idx = 0;
 	idx = 0;
@@ -461,7 +461,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
 		Geometry::MeshData::Edge e;
 		Geometry::MeshData::Edge e;
 		e.a = E->key().vertices[0];
 		e.a = E->key().vertices[0];
 		e.b = E->key().vertices[1];
 		e.b = E->key().vertices[1];
-		r_mesh.edges[idx++] = e;
+		r_mesh.edges.write[idx++] = e;
 	}
 	}
 
 
 	r_mesh.vertices = p_points;
 	r_mesh.vertices = p_points;

+ 3 - 3
core/math/triangulate.cpp

@@ -128,10 +128,10 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
 
 
 	if (0.0 < get_area(contour))
 	if (0.0 < get_area(contour))
 		for (int v = 0; v < n; v++)
 		for (int v = 0; v < n; v++)
-			V[v] = v;
+			V.write[v] = v;
 	else
 	else
 		for (int v = 0; v < n; v++)
 		for (int v = 0; v < n; v++)
-			V[v] = (n - 1) - v;
+			V.write[v] = (n - 1) - v;
 
 
 	bool relaxed = false;
 	bool relaxed = false;
 
 
@@ -182,7 +182,7 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
 
 
 			/* remove v from remaining polygon */
 			/* remove v from remaining polygon */
 			for (s = v, t = v + 1; t < nv; s++, t++)
 			for (s = v, t = v + 1; t < nv; s++, t++)
-				V[s] = V[t];
+				V.write[s] = V[t];
 
 
 			nv--;
 			nv--;
 
 

+ 1 - 1
core/method_bind.h

@@ -354,7 +354,7 @@ public:
 			for (int i = 0; i < p_info.arguments.size(); i++) {
 			for (int i = 0; i < p_info.arguments.size(); i++) {
 
 
 				at[i + 1] = p_info.arguments[i].type;
 				at[i + 1] = p_info.arguments[i].type;
-				names[i] = p_info.arguments[i].name;
+				names.write[i] = p_info.arguments[i].name;
 			}
 			}
 
 
 			set_argument_names(names);
 			set_argument_names(names);

+ 6 - 6
core/method_ptrcall.h

@@ -180,7 +180,7 @@ struct PtrToArg<const T *> {
 			{                                                                                    \
 			{                                                                                    \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				for (int i = 0; i < len; i++) {                                                  \
 				for (int i = 0; i < len; i++) {                                                  \
-					ret[i] = r[i];                                                               \
+					ret.write[i] = r[i];                                                         \
 				}                                                                                \
 				}                                                                                \
 			}                                                                                    \
 			}                                                                                    \
 			return ret;                                                                          \
 			return ret;                                                                          \
@@ -207,7 +207,7 @@ struct PtrToArg<const T *> {
 			{                                                                                    \
 			{                                                                                    \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				for (int i = 0; i < len; i++) {                                                  \
 				for (int i = 0; i < len; i++) {                                                  \
-					ret[i] = r[i];                                                               \
+					ret.write[i] = r[i];                                                         \
 				}                                                                                \
 				}                                                                                \
 			}                                                                                    \
 			}                                                                                    \
 			return ret;                                                                          \
 			return ret;                                                                          \
@@ -225,7 +225,7 @@ struct PtrToArg<const T *> {
 			{                                                                                    \
 			{                                                                                    \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				for (int i = 0; i < len; i++) {                                                  \
 				for (int i = 0; i < len; i++) {                                                  \
-					ret[i] = r[i];                                                               \
+					ret.write[i] = r[i];                                                         \
 				}                                                                                \
 				}                                                                                \
 			}                                                                                    \
 			}                                                                                    \
 			return ret;                                                                          \
 			return ret;                                                                          \
@@ -252,7 +252,7 @@ struct PtrToArg<const T *> {
 			{                                                                                    \
 			{                                                                                    \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				PoolVector<m_type>::Read r = dvs->read();                                        \
 				for (int i = 0; i < len; i++) {                                                  \
 				for (int i = 0; i < len; i++) {                                                  \
-					ret[i] = r[i];                                                               \
+					ret.write[i] = r[i];                                                         \
 				}                                                                                \
 				}                                                                                \
 			}                                                                                    \
 			}                                                                                    \
 			return ret;                                                                          \
 			return ret;                                                                          \
@@ -277,7 +277,7 @@ MAKE_VECARG_ALT(String, StringName);
 			int len = arr->size();                                             \
 			int len = arr->size();                                             \
 			ret.resize(len);                                                   \
 			ret.resize(len);                                                   \
 			for (int i = 0; i < len; i++) {                                    \
 			for (int i = 0; i < len; i++) {                                    \
-				ret[i] = (*arr)[i];                                            \
+				ret.write[i] = (*arr)[i];                                      \
 			}                                                                  \
 			}                                                                  \
 			return ret;                                                        \
 			return ret;                                                        \
 		}                                                                      \
 		}                                                                      \
@@ -298,7 +298,7 @@ MAKE_VECARG_ALT(String, StringName);
 			int len = arr->size();                                             \
 			int len = arr->size();                                             \
 			ret.resize(len);                                                   \
 			ret.resize(len);                                                   \
 			for (int i = 0; i < len; i++) {                                    \
 			for (int i = 0; i < len; i++) {                                    \
-				ret[i] = (*arr)[i];                                            \
+				ret.write[i] = (*arr)[i];                                      \
 			}                                                                  \
 			}                                                                  \
 			return ret;                                                        \
 			return ret;                                                        \
 		}                                                                      \
 		}                                                                      \

+ 1 - 1
core/node_path.cpp

@@ -427,7 +427,7 @@ NodePath::NodePath(const String &p_path) {
 
 
 				String name = path.substr(from, i - from);
 				String name = path.substr(from, i - from);
 				ERR_FAIL_INDEX(slice, data->path.size());
 				ERR_FAIL_INDEX(slice, data->path.size());
-				data->path[slice++] = name;
+				data->path.write[slice++] = name;
 			}
 			}
 			from = i + 1;
 			from = i + 1;
 			last_is_slash = true;
 			last_is_slash = true;

+ 4 - 4
core/object.cpp

@@ -818,8 +818,8 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
 	argptrs.resize(p_args.size());
 	argptrs.resize(p_args.size());
 
 
 	for (int i = 0; i < p_args.size(); i++) {
 	for (int i = 0; i < p_args.size(); i++) {
-		args[i] = p_args[i];
-		argptrs[i] = &args[i];
+		args.write[i] = p_args[i];
+		argptrs.write[i] = &args[i];
 	}
 	}
 
 
 	Variant::CallError ce;
 	Variant::CallError ce;
@@ -1182,10 +1182,10 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 			bind_mem.resize(p_argcount + c.binds.size());
 			bind_mem.resize(p_argcount + c.binds.size());
 
 
 			for (int j = 0; j < p_argcount; j++) {
 			for (int j = 0; j < p_argcount; j++) {
-				bind_mem[j] = p_args[j];
+				bind_mem.write[j] = p_args[j];
 			}
 			}
 			for (int j = 0; j < c.binds.size(); j++) {
 			for (int j = 0; j < c.binds.size(); j++) {
-				bind_mem[p_argcount + j] = &c.binds[j];
+				bind_mem.write[p_argcount + j] = &c.binds[j];
 			}
 			}
 
 
 			args = (const Variant **)bind_mem.ptr();
 			args = (const Variant **)bind_mem.ptr();

+ 4 - 4
core/os/file_access.cpp

@@ -262,15 +262,15 @@ String FileAccess::get_token() const {
 	while (!eof_reached()) {
 	while (!eof_reached()) {
 
 
 		if (c <= ' ') {
 		if (c <= ' ') {
-			if (!token.empty())
+			if (token.length())
 				break;
 				break;
 		} else {
 		} else {
-			token.push_back(c);
+			token += c;
 		}
 		}
 		c = get_8();
 		c = get_8();
 	}
 	}
 
 
-	token.push_back(0);
+	token += '0';
 	return String::utf8(token.get_data());
 	return String::utf8(token.get_data());
 }
 }
 
 
@@ -293,7 +293,7 @@ class CharBuffer {
 
 
 			for (int i = 0; i < written; i++) {
 			for (int i = 0; i < written; i++) {
 
 
-				vector[i] = stack_buffer[i];
+				vector.write[i] = stack_buffer[i];
 			}
 			}
 		}
 		}
 
 

+ 1 - 1
core/os/threaded_array_processor.h

@@ -80,7 +80,7 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
 	threads.resize(OS::get_singleton()->get_processor_count());
 	threads.resize(OS::get_singleton()->get_processor_count());
 
 
 	for (int i = 0; i < threads.size(); i++) {
 	for (int i = 0; i < threads.size(); i++) {
-		threads[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U> >, &data);
+		threads.write[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U> >, &data);
 	}
 	}
 
 
 	for (int i = 0; i < threads.size(); i++) {
 	for (int i = 0; i < threads.size(); i++) {

+ 9 - 9
core/packed_data_container.cpp

@@ -251,7 +251,7 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
 			int len;
 			int len;
 			encode_variant(p_data, NULL, len);
 			encode_variant(p_data, NULL, len);
 			tmpdata.resize(tmpdata.size() + len);
 			tmpdata.resize(tmpdata.size() + len);
-			encode_variant(p_data, &tmpdata[pos], len);
+			encode_variant(p_data, &tmpdata.write[pos], len);
 			return pos;
 			return pos;
 
 
 		} break;
 		} break;
@@ -268,8 +268,8 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
 			uint32_t pos = tmpdata.size();
 			uint32_t pos = tmpdata.size();
 			int len = d.size();
 			int len = d.size();
 			tmpdata.resize(tmpdata.size() + len * 12 + 8);
 			tmpdata.resize(tmpdata.size() + len * 12 + 8);
-			encode_uint32(TYPE_DICT, &tmpdata[pos + 0]);
-			encode_uint32(len, &tmpdata[pos + 4]);
+			encode_uint32(TYPE_DICT, &tmpdata.write[pos + 0]);
+			encode_uint32(len, &tmpdata.write[pos + 4]);
 
 
 			List<Variant> keys;
 			List<Variant> keys;
 			d.get_key_list(&keys);
 			d.get_key_list(&keys);
@@ -288,11 +288,11 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
 			int idx = 0;
 			int idx = 0;
 			for (List<DictKey>::Element *E = sortk.front(); E; E = E->next()) {
 			for (List<DictKey>::Element *E = sortk.front(); E; E = E->next()) {
 
 
-				encode_uint32(E->get().hash, &tmpdata[pos + 8 + idx * 12 + 0]);
+				encode_uint32(E->get().hash, &tmpdata.write[pos + 8 + idx * 12 + 0]);
 				uint32_t ofs = _pack(E->get().key, tmpdata, string_cache);
 				uint32_t ofs = _pack(E->get().key, tmpdata, string_cache);
-				encode_uint32(ofs, &tmpdata[pos + 8 + idx * 12 + 4]);
+				encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 4]);
 				ofs = _pack(d[E->get().key], tmpdata, string_cache);
 				ofs = _pack(d[E->get().key], tmpdata, string_cache);
-				encode_uint32(ofs, &tmpdata[pos + 8 + idx * 12 + 8]);
+				encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 8]);
 				idx++;
 				idx++;
 			}
 			}
 
 
@@ -306,13 +306,13 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
 			uint32_t pos = tmpdata.size();
 			uint32_t pos = tmpdata.size();
 			int len = a.size();
 			int len = a.size();
 			tmpdata.resize(tmpdata.size() + len * 4 + 8);
 			tmpdata.resize(tmpdata.size() + len * 4 + 8);
-			encode_uint32(TYPE_ARRAY, &tmpdata[pos + 0]);
-			encode_uint32(len, &tmpdata[pos + 4]);
+			encode_uint32(TYPE_ARRAY, &tmpdata.write[pos + 0]);
+			encode_uint32(len, &tmpdata.write[pos + 4]);
 
 
 			for (int i = 0; i < len; i++) {
 			for (int i = 0; i < len; i++) {
 
 
 				uint32_t ofs = _pack(a[i], tmpdata, string_cache);
 				uint32_t ofs = _pack(a[i], tmpdata, string_cache);
-				encode_uint32(ofs, &tmpdata[pos + 8 + i * 4]);
+				encode_uint32(ofs, &tmpdata.write[pos + 8 + i * 4]);
 			}
 			}
 
 
 			return pos;
 			return pos;

+ 2 - 2
core/project_settings.cpp

@@ -627,7 +627,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
 		Vector<uint8_t> buff;
 		Vector<uint8_t> buff;
 		buff.resize(len);
 		buff.resize(len);
 
 
-		err = encode_variant(p_custom_features, &buff[0], len);
+		err = encode_variant(p_custom_features, buff.ptrw(), len);
 		if (err != OK) {
 		if (err != OK) {
 			memdelete(file);
 			memdelete(file);
 			ERR_FAIL_V(err);
 			ERR_FAIL_V(err);
@@ -664,7 +664,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
 			Vector<uint8_t> buff;
 			Vector<uint8_t> buff;
 			buff.resize(len);
 			buff.resize(len);
 
 
-			err = encode_variant(value, &buff[0], len);
+			err = encode_variant(value, buff.ptrw(), len);
 			if (err != OK)
 			if (err != OK)
 				memdelete(file);
 				memdelete(file);
 			ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
 			ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);

+ 3 - 3
core/ring_buffer.h

@@ -137,7 +137,7 @@ public:
 
 
 	Error write(const T &p_v) {
 	Error write(const T &p_v) {
 		ERR_FAIL_COND_V(space_left() < 1, FAILED);
 		ERR_FAIL_COND_V(space_left() < 1, FAILED);
-		data[inc(write_pos, 1)] = p_v;
+		data.write[inc(write_pos, 1)] = p_v;
 		return OK;
 		return OK;
 	};
 	};
 
 
@@ -156,7 +156,7 @@ public:
 			int total = end - pos;
 			int total = end - pos;
 
 
 			for (int i = 0; i < total; i++) {
 			for (int i = 0; i < total; i++) {
-				data[pos + i] = p_buf[src++];
+				data.write[pos + i] = p_buf[src++];
 			};
 			};
 			to_write -= total;
 			to_write -= total;
 			pos = 0;
 			pos = 0;
@@ -196,7 +196,7 @@ public:
 		data.resize(1 << p_power);
 		data.resize(1 << p_power);
 		if (old_size < new_size && read_pos > write_pos) {
 		if (old_size < new_size && read_pos > write_pos) {
 			for (int i = 0; i < write_pos; i++) {
 			for (int i = 0; i < write_pos; i++) {
-				data[(old_size + i) & mask] = data[i];
+				data.write[(old_size + i) & mask] = data[i];
 			};
 			};
 			write_pos = (old_size + write_pos) & mask;
 			write_pos = (old_size + write_pos) & mask;
 		} else {
 		} else {

+ 2 - 2
core/script_debugger_local.cpp

@@ -325,7 +325,7 @@ void ScriptDebuggerLocal::idle_poll() {
 
 
 	int ofs = 0;
 	int ofs = 0;
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-		ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo[ofs], pinfo.size() - ofs);
+		ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs);
 	}
 	}
 
 
 	SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
 	SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
@@ -377,7 +377,7 @@ void ScriptDebuggerLocal::profiling_end() {
 	int ofs = 0;
 	int ofs = 0;
 
 
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-		ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo[ofs], pinfo.size() - ofs);
+		ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs);
 	}
 	}
 
 
 	SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
 	SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;

+ 4 - 4
core/script_debugger_remote.cpp

@@ -783,13 +783,13 @@ void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) {
 
 
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
 		if (p_for_frame)
 		if (p_for_frame)
-			ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info[ofs], profile_info.size() - ofs);
+			ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info.write[ofs], profile_info.size() - ofs);
 		else
 		else
-			ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info[ofs], profile_info.size() - ofs);
+			ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info.write[ofs], profile_info.size() - ofs);
 	}
 	}
 
 
 	for (int i = 0; i < ofs; i++) {
 	for (int i = 0; i < ofs; i++) {
-		profile_info_ptrs[i] = &profile_info[i];
+		profile_info_ptrs.write[i] = &profile_info.write[i];
 	}
 	}
 
 
 	SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa;
 	SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa;
@@ -1054,7 +1054,7 @@ void ScriptDebuggerRemote::add_profiling_frame_data(const StringName &p_name, co
 	if (idx == -1) {
 	if (idx == -1) {
 		profile_frame_data.push_back(fd);
 		profile_frame_data.push_back(fd);
 	} else {
 	} else {
-		profile_frame_data[idx] = fd;
+		profile_frame_data.write[idx] = fd;
 	}
 	}
 }
 }
 
 

+ 1 - 1
core/string_buffer.h

@@ -42,7 +42,7 @@ class StringBuffer {
 	int string_length;
 	int string_length;
 
 
 	_FORCE_INLINE_ CharType *current_buffer_ptr() {
 	_FORCE_INLINE_ CharType *current_buffer_ptr() {
-		return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptrw();
+		return static_cast<String &>(buffer).empty() ? short_buffer : buffer.ptrw();
 	}
 	}
 
 
 public:
 public:

+ 1 - 5
core/typedefs.h

@@ -58,12 +58,8 @@
 #endif
 #endif
 
 
 #ifndef _FORCE_INLINE_
 #ifndef _FORCE_INLINE_
-#ifdef DEBUG_ENABLED
-#define _FORCE_INLINE_ inline
-#else
 #define _FORCE_INLINE_ _ALWAYS_INLINE_
 #define _FORCE_INLINE_ _ALWAYS_INLINE_
 #endif
 #endif
-#endif
 
 
 //custom, gcc-safe offsetof, because gcc complains a lot.
 //custom, gcc-safe offsetof, because gcc complains a lot.
 template <class T>
 template <class T>
@@ -267,7 +263,7 @@ static inline uint64_t BSWAP64(uint64_t x) {
 template <class T>
 template <class T>
 struct Comparator {
 struct Comparator {
 
 
-	inline bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
+	_ALWAYS_INLINE_ bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
 };
 };
 
 
 void _global_lock();
 void _global_lock();

+ 13 - 13
core/undo_redo.cpp

@@ -39,7 +39,7 @@ void UndoRedo::_discard_redo() {
 
 
 	for (int i = current_action + 1; i < actions.size(); i++) {
 	for (int i = current_action + 1; i < actions.size(); i++) {
 
 
-		for (List<Operation>::Element *E = actions[i].do_ops.front(); E; E = E->next()) {
+		for (List<Operation>::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) {
 
 
 			if (E->get().type == Operation::TYPE_REFERENCE) {
 			if (E->get().type == Operation::TYPE_REFERENCE) {
 
 
@@ -70,7 +70,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
 			if (p_mode == MERGE_ENDS) {
 			if (p_mode == MERGE_ENDS) {
 
 
 				// Clear all do ops from last action, and delete all object references
 				// Clear all do ops from last action, and delete all object references
-				List<Operation>::Element *E = actions[current_action + 1].do_ops.front();
+				List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
 
 
 				while (E) {
 				while (E) {
 
 
@@ -83,11 +83,11 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
 					}
 					}
 
 
 					E = E->next();
 					E = E->next();
-					actions[current_action + 1].do_ops.pop_front();
+					actions.write[current_action + 1].do_ops.pop_front();
 				}
 				}
 			}
 			}
 
 
-			actions[actions.size() - 1].last_tick = ticks;
+			actions.write[actions.size() - 1].last_tick = ticks;
 
 
 			merge_mode = p_mode;
 			merge_mode = p_mode;
 
 
@@ -122,7 +122,7 @@ void UndoRedo::add_do_method(Object *p_object, const String &p_method, VARIANT_A
 	for (int i = 0; i < VARIANT_ARG_MAX; i++) {
 	for (int i = 0; i < VARIANT_ARG_MAX; i++) {
 		do_op.args[i] = *argptr[i];
 		do_op.args[i] = *argptr[i];
 	}
 	}
-	actions[current_action + 1].do_ops.push_back(do_op);
+	actions.write[current_action + 1].do_ops.push_back(do_op);
 }
 }
 
 
 void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT_ARG_DECLARE) {
 void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT_ARG_DECLARE) {
@@ -147,7 +147,7 @@ void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT
 	for (int i = 0; i < VARIANT_ARG_MAX; i++) {
 	for (int i = 0; i < VARIANT_ARG_MAX; i++) {
 		undo_op.args[i] = *argptr[i];
 		undo_op.args[i] = *argptr[i];
 	}
 	}
-	actions[current_action + 1].undo_ops.push_back(undo_op);
+	actions.write[current_action + 1].undo_ops.push_back(undo_op);
 }
 }
 void UndoRedo::add_do_property(Object *p_object, const String &p_property, const Variant &p_value) {
 void UndoRedo::add_do_property(Object *p_object, const String &p_property, const Variant &p_value) {
 
 
@@ -162,7 +162,7 @@ void UndoRedo::add_do_property(Object *p_object, const String &p_property, const
 	do_op.type = Operation::TYPE_PROPERTY;
 	do_op.type = Operation::TYPE_PROPERTY;
 	do_op.name = p_property;
 	do_op.name = p_property;
 	do_op.args[0] = p_value;
 	do_op.args[0] = p_value;
-	actions[current_action + 1].do_ops.push_back(do_op);
+	actions.write[current_action + 1].do_ops.push_back(do_op);
 }
 }
 void UndoRedo::add_undo_property(Object *p_object, const String &p_property, const Variant &p_value) {
 void UndoRedo::add_undo_property(Object *p_object, const String &p_property, const Variant &p_value) {
 
 
@@ -182,7 +182,7 @@ void UndoRedo::add_undo_property(Object *p_object, const String &p_property, con
 	undo_op.type = Operation::TYPE_PROPERTY;
 	undo_op.type = Operation::TYPE_PROPERTY;
 	undo_op.name = p_property;
 	undo_op.name = p_property;
 	undo_op.args[0] = p_value;
 	undo_op.args[0] = p_value;
-	actions[current_action + 1].undo_ops.push_back(undo_op);
+	actions.write[current_action + 1].undo_ops.push_back(undo_op);
 }
 }
 void UndoRedo::add_do_reference(Object *p_object) {
 void UndoRedo::add_do_reference(Object *p_object) {
 
 
@@ -195,7 +195,7 @@ void UndoRedo::add_do_reference(Object *p_object) {
 		do_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
 		do_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
 
 
 	do_op.type = Operation::TYPE_REFERENCE;
 	do_op.type = Operation::TYPE_REFERENCE;
-	actions[current_action + 1].do_ops.push_back(do_op);
+	actions.write[current_action + 1].do_ops.push_back(do_op);
 }
 }
 void UndoRedo::add_undo_reference(Object *p_object) {
 void UndoRedo::add_undo_reference(Object *p_object) {
 
 
@@ -213,7 +213,7 @@ void UndoRedo::add_undo_reference(Object *p_object) {
 		undo_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
 		undo_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
 
 
 	undo_op.type = Operation::TYPE_REFERENCE;
 	undo_op.type = Operation::TYPE_REFERENCE;
-	actions[current_action + 1].undo_ops.push_back(undo_op);
+	actions.write[current_action + 1].undo_ops.push_back(undo_op);
 }
 }
 
 
 void UndoRedo::_pop_history_tail() {
 void UndoRedo::_pop_history_tail() {
@@ -223,7 +223,7 @@ void UndoRedo::_pop_history_tail() {
 	if (!actions.size())
 	if (!actions.size())
 		return;
 		return;
 
 
-	for (List<Operation>::Element *E = actions[0].undo_ops.front(); E; E = E->next()) {
+	for (List<Operation>::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) {
 
 
 		if (E->get().type == Operation::TYPE_REFERENCE) {
 		if (E->get().type == Operation::TYPE_REFERENCE) {
 
 
@@ -307,7 +307,7 @@ bool UndoRedo::redo() {
 		return false; //nothing to redo
 		return false; //nothing to redo
 	current_action++;
 	current_action++;
 
 
-	_process_operation_list(actions[current_action].do_ops.front());
+	_process_operation_list(actions.write[current_action].do_ops.front());
 	version++;
 	version++;
 
 
 	return true;
 	return true;
@@ -318,7 +318,7 @@ bool UndoRedo::undo() {
 	ERR_FAIL_COND_V(action_level > 0, false);
 	ERR_FAIL_COND_V(action_level > 0, false);
 	if (current_action < 0)
 	if (current_action < 0)
 		return false; //nothing to redo
 		return false; //nothing to redo
-	_process_operation_list(actions[current_action].undo_ops.front());
+	_process_operation_list(actions.write[current_action].undo_ops.front());
 	current_action--;
 	current_action--;
 	version--;
 	version--;
 
 

+ 19 - 9
core/ustring.cpp

@@ -102,6 +102,15 @@ bool CharString::operator<(const CharString &p_right) const {
 	return is_str_less(get_data(), p_right.get_data());
 	return is_str_less(get_data(), p_right.get_data());
 }
 }
 
 
+CharString &CharString::operator+=(char p_char) {
+
+	resize(size() ? size() + 1 : 2);
+	set(length(), 0);
+	set(length() - 1, p_char);
+
+	return *this;
+}
+
 const char *CharString::get_data() const {
 const char *CharString::get_data() const {
 
 
 	if (size())
 	if (size())
@@ -1578,6 +1587,7 @@ String::String(const char *p_str) {
 
 
 	copy_from(p_str);
 	copy_from(p_str);
 }
 }
+
 String::String(const CharType *p_str, int p_clip_to_len) {
 String::String(const CharType *p_str, int p_clip_to_len) {
 
 
 	copy_from(p_str, p_clip_to_len);
 	copy_from(p_str, p_clip_to_len);
@@ -2197,7 +2207,7 @@ Vector<uint8_t> String::md5_buffer() const {
 	Vector<uint8_t> ret;
 	Vector<uint8_t> ret;
 	ret.resize(16);
 	ret.resize(16);
 	for (int i = 0; i < 16; i++) {
 	for (int i = 0; i < 16; i++) {
-		ret[i] = ctx.digest[i];
+		ret.write[i] = ctx.digest[i];
 	};
 	};
 
 
 	return ret;
 	return ret;
@@ -2214,7 +2224,7 @@ Vector<uint8_t> String::sha256_buffer() const {
 	Vector<uint8_t> ret;
 	Vector<uint8_t> ret;
 	ret.resize(32);
 	ret.resize(32);
 	for (int i = 0; i < 32; i++) {
 	for (int i = 0; i < 32; i++) {
-		ret[i] = hash[i];
+		ret.write[i] = hash[i];
 	}
 	}
 
 
 	return ret;
 	return ret;
@@ -2673,7 +2683,7 @@ Vector<String> String::bigrams() const {
 	}
 	}
 	b.resize(n_pairs);
 	b.resize(n_pairs);
 	for (int i = 0; i < n_pairs; i++) {
 	for (int i = 0; i < n_pairs; i++) {
-		b[i] = substr(i, 2);
+		b.write[i] = substr(i, 2);
 	}
 	}
 	return b;
 	return b;
 }
 }
@@ -3032,14 +3042,14 @@ String String::strip_escapes() const {
 	return substr(beg, end - beg);
 	return substr(beg, end - beg);
 }
 }
 
 
-String String::lstrip(const Vector<CharType> &p_chars) const {
+String String::lstrip(const String &p_chars) const {
 
 
 	int len = length();
 	int len = length();
 	int beg;
 	int beg;
 
 
 	for (beg = 0; beg < len; beg++) {
 	for (beg = 0; beg < len; beg++) {
 
 
-		if (p_chars.find(operator[](beg)) == -1)
+		if (p_chars.find(&ptr()[beg]) == -1)
 			break;
 			break;
 	}
 	}
 
 
@@ -3049,14 +3059,14 @@ String String::lstrip(const Vector<CharType> &p_chars) const {
 	return substr(beg, len - beg);
 	return substr(beg, len - beg);
 }
 }
 
 
-String String::rstrip(const Vector<CharType> &p_chars) const {
+String String::rstrip(const String &p_chars) const {
 
 
 	int len = length();
 	int len = length();
 	int end;
 	int end;
 
 
 	for (end = len - 1; end >= 0; end--) {
 	for (end = len - 1; end >= 0; end--) {
 
 
-		if (p_chars.find(operator[](end)) == -1)
+		if (p_chars.find(&ptr()[end]) == -1)
 			break;
 			break;
 	}
 	}
 
 
@@ -3868,10 +3878,10 @@ String String::percent_decode() const {
 			c += d;
 			c += d;
 			i += 2;
 			i += 2;
 		}
 		}
-		pe.push_back(c);
+		pe += c;
 	}
 	}
 
 
-	pe.push_back(0);
+	pe += '0';
 
 
 	return String::utf8(pe.ptr());
 	return String::utf8(pe.ptr());
 }
 }

+ 44 - 7
core/ustring.h

@@ -32,6 +32,7 @@
 #define RSTRING_H
 #define RSTRING_H
 
 
 #include "array.h"
 #include "array.h"
+#include "cowdata.h"
 #include "typedefs.h"
 #include "typedefs.h"
 #include "vector.h"
 #include "vector.h"
 
 
@@ -39,9 +40,27 @@
 	@author red <red@killy>
 	@author red <red@killy>
 */
 */
 
 
-class CharString : public Vector<char> {
+class CharString {
+
+	CowData<char> _cowdata;
+
 public:
 public:
+	_FORCE_INLINE_ char *ptrw() { return _cowdata.ptrw(); }
+	_FORCE_INLINE_ const char *ptr() const { return _cowdata.ptr(); }
+	_FORCE_INLINE_ int size() const { return _cowdata.size(); }
+	Error resize(int p_size) { return _cowdata.resize(p_size); }
+
+	_FORCE_INLINE_ char get(int p_index) { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ const char get(int p_index) const { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ void set(int p_index, const char &p_elem) { _cowdata.set(p_index, p_elem); }
+	_FORCE_INLINE_ char &operator[](int p_index) { return _cowdata.get_m(p_index); }
+	_FORCE_INLINE_ const char &operator[](int p_index) const { return _cowdata.get(p_index); }
+
+	_FORCE_INLINE_ CharString() {}
+	_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
+
 	bool operator<(const CharString &p_right) const;
 	bool operator<(const CharString &p_right) const;
+	CharString &operator+=(char p_char);
 	int length() const { return size() ? size() - 1 : 0; }
 	int length() const { return size() ? size() - 1 : 0; }
 	const char *get_data() const;
 	const char *get_data() const;
 	operator const char *() { return get_data(); };
 	operator const char *() { return get_data(); };
@@ -60,7 +79,9 @@ struct StrRange {
 	}
 	}
 };
 };
 
 
-class String : public Vector<CharType> {
+class String {
+
+	CowData<CharType> _cowdata;
 
 
 	void copy_from(const char *p_cstr);
 	void copy_from(const char *p_cstr);
 	void copy_from(const CharType *p_cstr, int p_clip_to = -1);
 	void copy_from(const CharType *p_cstr, int p_clip_to = -1);
@@ -74,6 +95,21 @@ public:
 		npos = -1 ///<for "some" compatibility with std::string (npos is a huge value in std::string)
 		npos = -1 ///<for "some" compatibility with std::string (npos is a huge value in std::string)
 	};
 	};
 
 
+	_FORCE_INLINE_ CharType *ptrw() { return _cowdata.ptrw(); }
+	_FORCE_INLINE_ const CharType *ptr() const { return _cowdata.ptr(); }
+
+	void remove(int p_index) { _cowdata.remove(p_index); }
+
+	_FORCE_INLINE_ void clear() { resize(0); }
+
+	_FORCE_INLINE_ CharType get(int p_index) { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ const CharType get(int p_index) const { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ void set(int p_index, const CharType &p_elem) { _cowdata.set(p_index, p_elem); }
+	_FORCE_INLINE_ int size() const { return _cowdata.size(); }
+	Error resize(int p_size) { return _cowdata.resize(p_size); }
+	_FORCE_INLINE_ CharType &operator[](int p_index) { return _cowdata.get_m(p_index); }
+	_FORCE_INLINE_ const CharType &operator[](int p_index) const { return _cowdata.get(p_index); }
+
 	bool operator==(const String &p_str) const;
 	bool operator==(const String &p_str) const;
 	bool operator!=(const String &p_str) const;
 	bool operator!=(const String &p_str) const;
 	String operator+(const String &p_str) const;
 	String operator+(const String &p_str) const;
@@ -192,8 +228,8 @@ public:
 	String dedent() const;
 	String dedent() const;
 	String strip_edges(bool left = true, bool right = true) const;
 	String strip_edges(bool left = true, bool right = true) const;
 	String strip_escapes() const;
 	String strip_escapes() const;
-	String lstrip(const Vector<CharType> &p_chars) const;
-	String rstrip(const Vector<CharType> &p_chars) const;
+	String lstrip(const String &p_chars) const;
+	String rstrip(const String &p_chars) const;
 	String get_extension() const;
 	String get_extension() const;
 	String get_basename() const;
 	String get_basename() const;
 	String plus_file(const String &p_file) const;
 	String plus_file(const String &p_file) const;
@@ -254,9 +290,10 @@ public:
 	 * The constructors must not depend on other overloads
 	 * The constructors must not depend on other overloads
 	 */
 	 */
 	/*	String(CharType p_char);*/
 	/*	String(CharType p_char);*/
-	inline String() {}
-	inline String(const String &p_str) :
-			Vector(p_str) {}
+
+	_FORCE_INLINE_ String() {}
+	_FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); }
+
 	String(const char *p_str);
 	String(const char *p_str);
 	String(const CharType *p_str, int p_clip_to_len = -1);
 	String(const CharType *p_str, int p_clip_to_len = -1);
 	String(const StrRange &p_range);
 	String(const StrRange &p_range);

+ 11 - 11
core/variant.cpp

@@ -1878,7 +1878,7 @@ Variant::operator Vector<RID>() const {
 	Vector<RID> rids;
 	Vector<RID> rids;
 	rids.resize(va.size());
 	rids.resize(va.size());
 	for (int i = 0; i < rids.size(); i++)
 	for (int i = 0; i < rids.size(); i++)
-		rids[i] = va[i];
+		rids.write[i] = va[i];
 	return rids;
 	return rids;
 }
 }
 
 
@@ -1891,7 +1891,7 @@ Variant::operator Vector<Vector2>() const {
 		return Vector<Vector2>();
 		return Vector<Vector2>();
 	to.resize(len);
 	to.resize(len);
 	PoolVector<Vector2>::Read r = from.read();
 	PoolVector<Vector2>::Read r = from.read();
-	Vector2 *w = &to[0];
+	Vector2 *w = to.ptrw();
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
 		w[i] = r[i];
 		w[i] = r[i];
@@ -1945,7 +1945,7 @@ Variant::operator Vector<Plane>() const {
 	planes.resize(va_size);
 	planes.resize(va_size);
 
 
 	for (int i = 0; i < va_size; i++)
 	for (int i = 0; i < va_size; i++)
-		planes[i] = va[i];
+		planes.write[i] = va[i];
 
 
 	return planes;
 	return planes;
 }
 }
@@ -1958,7 +1958,7 @@ Variant::operator Vector<Variant>() const {
 	to.resize(len);
 	to.resize(len);
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
-		to[i] = from[i];
+		to.write[i] = from[i];
 	}
 	}
 	return to;
 	return to;
 }
 }
@@ -1971,7 +1971,7 @@ Variant::operator Vector<uint8_t>() const {
 	to.resize(len);
 	to.resize(len);
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
-		to[i] = from[i];
+		to.write[i] = from[i];
 	}
 	}
 	return to;
 	return to;
 }
 }
@@ -1983,7 +1983,7 @@ Variant::operator Vector<int>() const {
 	to.resize(len);
 	to.resize(len);
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
-		to[i] = from[i];
+		to.write[i] = from[i];
 	}
 	}
 	return to;
 	return to;
 }
 }
@@ -1995,7 +1995,7 @@ Variant::operator Vector<real_t>() const {
 	to.resize(len);
 	to.resize(len);
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
-		to[i] = from[i];
+		to.write[i] = from[i];
 	}
 	}
 	return to;
 	return to;
 }
 }
@@ -2008,7 +2008,7 @@ Variant::operator Vector<String>() const {
 	to.resize(len);
 	to.resize(len);
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
-		to[i] = from[i];
+		to.write[i] = from[i];
 	}
 	}
 	return to;
 	return to;
 }
 }
@@ -2020,7 +2020,7 @@ Variant::operator Vector<StringName>() const {
 	to.resize(len);
 	to.resize(len);
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
-		to[i] = from[i];
+		to.write[i] = from[i];
 	}
 	}
 	return to;
 	return to;
 }
 }
@@ -2034,7 +2034,7 @@ Variant::operator Vector<Vector3>() const {
 		return Vector<Vector3>();
 		return Vector<Vector3>();
 	to.resize(len);
 	to.resize(len);
 	PoolVector<Vector3>::Read r = from.read();
 	PoolVector<Vector3>::Read r = from.read();
-	Vector3 *w = &to[0];
+	Vector3 *w = to.ptrw();
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
 		w[i] = r[i];
 		w[i] = r[i];
@@ -2050,7 +2050,7 @@ Variant::operator Vector<Color>() const {
 		return Vector<Color>();
 		return Vector<Color>();
 	to.resize(len);
 	to.resize(len);
 	PoolVector<Color>::Read r = from.read();
 	PoolVector<Color>::Read r = from.read();
-	Color *w = &to[0];
+	Color *w = to.ptrw();
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
 
 
 		w[i] = r[i];
 		w[i] = r[i];

+ 1 - 1
core/variant_call.cpp

@@ -64,7 +64,7 @@ struct _VariantCall {
 			if (arg_count == 0)
 			if (arg_count == 0)
 				return true;
 				return true;
 
 
-			Variant::Type *tptr = &arg_types[0];
+			const Variant::Type *tptr = &arg_types[0];
 
 
 			for (int i = 0; i < arg_count; i++) {
 			for (int i = 0; i < arg_count; i++) {
 
 

+ 59 - 323
core/vector.h

@@ -36,131 +36,69 @@
  * @author Juan Linietsky
  * @author Juan Linietsky
  * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use PoolVector for large arrays.
  * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use PoolVector for large arrays.
 */
 */
+#include "cowdata.h"
 #include "error_macros.h"
 #include "error_macros.h"
 #include "os/memory.h"
 #include "os/memory.h"
-#include "safe_refcount.h"
 #include "sort.h"
 #include "sort.h"
 
 
 template <class T>
 template <class T>
-class Vector {
-
-	mutable T *_ptr;
-
-	// internal helpers
-
-	_FORCE_INLINE_ uint32_t *_get_refcount() const {
-
-		if (!_ptr)
-			return NULL;
+class VectorWriteProxy {
+	friend class Vector<T>;
+	Vector<T> &_parent;
 
 
-		return reinterpret_cast<uint32_t *>(_ptr) - 2;
-	}
-
-	_FORCE_INLINE_ uint32_t *_get_size() const {
-
-		if (!_ptr)
-			return NULL;
-
-		return reinterpret_cast<uint32_t *>(_ptr) - 1;
-	}
-	_FORCE_INLINE_ T *_get_data() const {
+	_FORCE_INLINE_ VectorWriteProxy(Vector<T> &parent) :
+			_parent(parent){};
+	VectorWriteProxy(const VectorWriteProxy<T> &p_other);
 
 
-		if (!_ptr)
-			return NULL;
-		return reinterpret_cast<T *>(_ptr);
-	}
-
-	_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
-		//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
-		return next_power_of_2(p_elements * sizeof(T));
-	}
+public:
+	_FORCE_INLINE_ T &operator[](int p_index) {
+		CRASH_BAD_INDEX(p_index, _parent.size());
 
 
-	_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
-#if defined(_add_overflow) && defined(_mul_overflow)
-		size_t o;
-		size_t p;
-		if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
-		*out = next_power_of_2(o);
-		if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
-		return true;
-#else
-		// Speed is more important than correctness here, do the operations unchecked
-		// and hope the best
-		*out = _get_alloc_size(p_elements);
-		return true;
-#endif
+		return _parent.ptrw()[p_index];
 	}
 	}
+};
 
 
-	void _unref(void *p_data);
+template <class T>
+class Vector {
+	friend class VectorWriteProxy<T>;
 
 
-	void _copy_from(const Vector &p_from);
-	void _copy_on_write();
+	CowData<T> _cowdata;
 
 
 public:
 public:
-	_FORCE_INLINE_ T *ptrw() {
-		if (!_ptr) return NULL;
-		_copy_on_write();
-		return (T *)_get_data();
-	}
-	_FORCE_INLINE_ const T *ptr() const {
-		if (!_ptr) return NULL;
-		return _get_data();
-	}
-
-	_FORCE_INLINE_ void clear() { resize(0); }
+	VectorWriteProxy<T> write;
 
 
-	_FORCE_INLINE_ int size() const {
-		uint32_t *size = (uint32_t *)_get_size();
-		if (size)
-			return *size;
-		else
-			return 0;
-	}
-	_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
-	Error resize(int p_size);
 	bool push_back(const T &p_elem);
 	bool push_back(const T &p_elem);
 
 
-	void remove(int p_index);
+	void remove(int p_index) { _cowdata.remove(p_index); }
 	void erase(const T &p_val) {
 	void erase(const T &p_val) {
 		int idx = find(p_val);
 		int idx = find(p_val);
 		if (idx >= 0) remove(idx);
 		if (idx >= 0) remove(idx);
 	};
 	};
 	void invert();
 	void invert();
 
 
-	template <class T_val>
-	int find(const T_val &p_val, int p_from = 0) const;
-
-	void set(int p_index, const T &p_elem);
-	T get(int p_index) const;
-
-	inline T &operator[](int p_index) {
-
-		CRASH_BAD_INDEX(p_index, size());
-
-		_copy_on_write(); // wants to write, so copy on write.
-
-		return _get_data()[p_index];
-	}
-
-	inline const T &operator[](int p_index) const {
-
-		CRASH_BAD_INDEX(p_index, size());
-
-		// no cow needed, since it's reading
-		return _get_data()[p_index];
-	}
+	_FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
+	_FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
+	_FORCE_INLINE_ void clear() { resize(0); }
+	_FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
 
 
-	Error insert(int p_pos, const T &p_val);
+	_FORCE_INLINE_ T get(int p_index) { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ const T get(int p_index) const { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
+	_FORCE_INLINE_ int size() const { return _cowdata.size(); }
+	Error resize(int p_size) { return _cowdata.resize(p_size); }
+	_FORCE_INLINE_ const T &operator[](int p_index) const { return _cowdata.get(p_index); }
+	Error insert(int p_pos, const T &p_val) { return _cowdata.insert(p_pos, p_val); }
 
 
 	void append_array(const Vector<T> &p_other);
 	void append_array(const Vector<T> &p_other);
 
 
 	template <class C>
 	template <class C>
 	void sort_custom() {
 	void sort_custom() {
 
 
-		int len = size();
+		int len = _cowdata.size();
 		if (len == 0)
 		if (len == 0)
 			return;
 			return;
-		T *data = &operator[](0);
+
+		T *data = ptrw();
 		SortArray<T, C> sorter;
 		SortArray<T, C> sorter;
 		sorter.sort(data, len);
 		sorter.sort(data, len);
 	}
 	}
@@ -172,7 +110,7 @@ public:
 
 
 	void ordered_insert(const T &p_val) {
 	void ordered_insert(const T &p_val) {
 		int i;
 		int i;
-		for (i = 0; i < size(); i++) {
+		for (i = 0; i < _cowdata.size(); i++) {
 
 
 			if (p_val < operator[](i)) {
 			if (p_val < operator[](i)) {
 				break;
 				break;
@@ -181,234 +119,41 @@ public:
 		insert(i, p_val);
 		insert(i, p_val);
 	}
 	}
 
 
-	void operator=(const Vector &p_from);
-	Vector(const Vector &p_from);
-
-	_FORCE_INLINE_ Vector();
-	_FORCE_INLINE_ ~Vector();
-};
+	int find(const T &p_val, int p_from = 0) const {
+		int ret = -1;
+		if (p_from < 0 || size() == 0)
+			return ret;
 
 
-template <class T>
-void Vector<T>::_unref(void *p_data) {
+		for (int i = p_from; i < size(); i++) {
 
 
-	if (!p_data)
-		return;
-
-	uint32_t *refc = _get_refcount();
-
-	if (atomic_decrement(refc) > 0)
-		return; // still in use
-	// clean up
-
-	uint32_t *count = _get_size();
-	T *data = (T *)(count + 1);
-
-	for (uint32_t i = 0; i < *count; i++) {
-		// call destructors
-		data[i].~T();
-	}
-
-	// free mem
-	Memory::free_static((uint8_t *)p_data, true);
-}
-
-template <class T>
-void Vector<T>::_copy_on_write() {
-
-	if (!_ptr)
-		return;
-
-	uint32_t *refc = _get_refcount();
-
-	if (*refc > 1) {
-		/* in use by more than me */
-		uint32_t current_size = *_get_size();
-
-		uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
-
-		*(mem_new - 2) = 1; //refcount
-		*(mem_new - 1) = current_size; //size
-
-		T *_data = (T *)(mem_new);
-
-		// initialize new elements
-		for (uint32_t i = 0; i < current_size; i++) {
-
-			memnew_placement(&_data[i], T(_get_data()[i]));
-		}
-
-		_unref(_ptr);
-		_ptr = _data;
-	}
-}
-
-template <class T>
-template <class T_val>
-int Vector<T>::find(const T_val &p_val, int p_from) const {
-
-	int ret = -1;
-	if (p_from < 0 || size() == 0)
-		return ret;
-
-	for (int i = p_from; i < size(); i++) {
-
-		if (operator[](i) == p_val) {
-			ret = i;
-			break;
+			if (ptr()[i] == p_val) {
+				ret = i;
+				break;
+			};
 		};
 		};
-	};
-
-	return ret;
-}
-
-template <class T>
-Error Vector<T>::resize(int p_size) {
-
-	ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
-
-	if (p_size == size())
-		return OK;
 
 
-	if (p_size == 0) {
-		// wants to clean up
-		_unref(_ptr);
-		_ptr = NULL;
-		return OK;
+		return ret;
 	}
 	}
 
 
-	// possibly changing size, copy on write
-	_copy_on_write();
-
-	size_t alloc_size;
-	ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
-
-	if (p_size > size()) {
-
-		if (size() == 0) {
-			// alloc from scratch
-			uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
-			ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
-			*(ptr - 1) = 0; //size, currently none
-			*(ptr - 2) = 1; //refcount
-
-			_ptr = (T *)ptr;
-
-		} else {
-			void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
-			ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
-			_ptr = (T *)(_ptrnew);
-		}
-
-		// construct the newly created elements
-		T *elems = _get_data();
-
-		for (int i = *_get_size(); i < p_size; i++) {
-
-			memnew_placement(&elems[i], T);
-		}
-
-		*_get_size() = p_size;
-
-	} else if (p_size < size()) {
-
-		// deinitialize no longer needed elements
-		for (uint32_t i = p_size; i < *_get_size(); i++) {
-
-			T *t = &_get_data()[i];
-			t->~T();
-		}
-
-		void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
-		ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
-
-		_ptr = (T *)(_ptrnew);
-
-		*_get_size() = p_size;
+	_FORCE_INLINE_ Vector() :
+			write(VectorWriteProxy<T>(*this)) {}
+	_FORCE_INLINE_ Vector(const Vector &p_from) :
+			write(VectorWriteProxy<T>(*this)) { _cowdata._ref(p_from._cowdata); }
+	inline Vector &operator=(const Vector &p_from) {
+		_cowdata._ref(p_from._cowdata);
+		return *this;
 	}
 	}
-
-	return OK;
-}
+};
 
 
 template <class T>
 template <class T>
 void Vector<T>::invert() {
 void Vector<T>::invert() {
 
 
 	for (int i = 0; i < size() / 2; i++) {
 	for (int i = 0; i < size() / 2; i++) {
-
-		SWAP(operator[](i), operator[](size() - i - 1));
-	}
-}
-
-template <class T>
-void Vector<T>::set(int p_index, const T &p_elem) {
-
-	operator[](p_index) = p_elem;
-}
-
-template <class T>
-T Vector<T>::get(int p_index) const {
-
-	return operator[](p_index);
-}
-
-template <class T>
-bool Vector<T>::push_back(const T &p_elem) {
-
-	Error err = resize(size() + 1);
-	ERR_FAIL_COND_V(err, true)
-	set(size() - 1, p_elem);
-
-	return false;
-}
-
-template <class T>
-void Vector<T>::remove(int p_index) {
-
-	ERR_FAIL_INDEX(p_index, size());
-	T *p = ptrw();
-	int len = size();
-	for (int i = p_index; i < len - 1; i++) {
-
-		p[i] = p[i + 1];
-	};
-
-	resize(len - 1);
-};
-
-template <class T>
-void Vector<T>::_copy_from(const Vector &p_from) {
-
-	if (_ptr == p_from._ptr)
-		return; // self assign, do nothing.
-
-	_unref(_ptr);
-	_ptr = NULL;
-
-	if (!p_from._ptr)
-		return; //nothing to do
-
-	if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
-		_ptr = p_from._ptr;
+		T *p = ptrw();
+		SWAP(p[i], p[size() - i - 1]);
 	}
 	}
 }
 }
 
 
-template <class T>
-void Vector<T>::operator=(const Vector &p_from) {
-
-	_copy_from(p_from);
-}
-
-template <class T>
-Error Vector<T>::insert(int p_pos, const T &p_val) {
-
-	ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
-	resize(size() + 1);
-	for (int i = (size() - 1); i > p_pos; i--)
-		set(i, get(i - 1));
-	set(p_pos, p_val);
-
-	return OK;
-}
-
 template <class T>
 template <class T>
 void Vector<T>::append_array(const Vector<T> &p_other) {
 void Vector<T>::append_array(const Vector<T> &p_other) {
 	const int ds = p_other.size();
 	const int ds = p_other.size();
@@ -417,26 +162,17 @@ void Vector<T>::append_array(const Vector<T> &p_other) {
 	const int bs = size();
 	const int bs = size();
 	resize(bs + ds);
 	resize(bs + ds);
 	for (int i = 0; i < ds; ++i)
 	for (int i = 0; i < ds; ++i)
-		operator[](bs + i) = p_other[i];
-}
-
-template <class T>
-Vector<T>::Vector(const Vector &p_from) {
-
-	_ptr = NULL;
-	_copy_from(p_from);
+		ptrw()[bs + i] = p_other[i];
 }
 }
 
 
 template <class T>
 template <class T>
-Vector<T>::Vector() {
-
-	_ptr = NULL;
-}
+bool Vector<T>::push_back(const T &p_elem) {
 
 
-template <class T>
-Vector<T>::~Vector() {
+	Error err = resize(size() + 1);
+	ERR_FAIL_COND_V(err, true)
+	set(size() - 1, p_elem);
 
 
-	_unref(_ptr);
+	return false;
 }
 }
 
 
 #endif
 #endif

+ 28 - 21
core/vmap.h

@@ -31,8 +31,8 @@
 #ifndef VMAP_H
 #ifndef VMAP_H
 #define VMAP_H
 #define VMAP_H
 
 
+#include "cowdata.h"
 #include "typedefs.h"
 #include "typedefs.h"
-#include "vector.h"
 
 
 template <class T, class V>
 template <class T, class V>
 class VMap {
 class VMap {
@@ -51,17 +51,17 @@ class VMap {
 		}
 		}
 	};
 	};
 
 
-	Vector<_Pair> _data;
+	CowData<_Pair> _cowdata;
 
 
 	_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
 	_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
 
 
 		r_exact = false;
 		r_exact = false;
-		if (_data.empty())
+		if (_cowdata.empty())
 			return 0;
 			return 0;
 
 
 		int low = 0;
 		int low = 0;
-		int high = _data.size() - 1;
-		const _Pair *a = &_data[0];
+		int high = _cowdata.size() - 1;
+		const _Pair *a = _cowdata.ptr();
 		int middle = 0;
 		int middle = 0;
 
 
 #if DEBUG_ENABLED
 #if DEBUG_ENABLED
@@ -89,13 +89,13 @@ class VMap {
 
 
 	_FORCE_INLINE_ int _find_exact(const T &p_val) const {
 	_FORCE_INLINE_ int _find_exact(const T &p_val) const {
 
 
-		if (_data.empty())
+		if (_cowdata.empty())
 			return -1;
 			return -1;
 
 
 		int low = 0;
 		int low = 0;
-		int high = _data.size() - 1;
+		int high = _cowdata.size() - 1;
 		int middle;
 		int middle;
-		const _Pair *a = &_data[0];
+		const _Pair *a = _cowdata.ptr();
 
 
 		while (low <= high) {
 		while (low <= high) {
 			middle = (low + high) / 2;
 			middle = (low + high) / 2;
@@ -118,10 +118,10 @@ public:
 		bool exact;
 		bool exact;
 		int pos = _find(p_key, exact);
 		int pos = _find(p_key, exact);
 		if (exact) {
 		if (exact) {
-			_data[pos].value = p_val;
+			_cowdata.get_m(pos).value = p_val;
 			return pos;
 			return pos;
 		}
 		}
-		_data.insert(pos, _Pair(p_key, p_val));
+		_cowdata.insert(pos, _Pair(p_key, p_val));
 		return pos;
 		return pos;
 	}
 	}
 
 
@@ -135,7 +135,7 @@ public:
 		int pos = _find_exact(p_val);
 		int pos = _find_exact(p_val);
 		if (pos < 0)
 		if (pos < 0)
 			return;
 			return;
-		_data.remove(pos);
+		_cowdata.remove(pos);
 	}
 	}
 
 
 	int find(const T &p_val) const {
 	int find(const T &p_val) const {
@@ -149,37 +149,37 @@ public:
 		return _find(p_val, exact);
 		return _find(p_val, exact);
 	}
 	}
 
 
-	_FORCE_INLINE_ int size() const { return _data.size(); }
-	_FORCE_INLINE_ bool empty() const { return _data.empty(); }
+	_FORCE_INLINE_ int size() const { return _cowdata.size(); }
+	_FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
 
 
 	const _Pair *get_array() const {
 	const _Pair *get_array() const {
 
 
-		return _data.ptr();
+		return _cowdata.ptr();
 	}
 	}
 
 
 	_Pair *get_array() {
 	_Pair *get_array() {
 
 
-		return _data.ptr();
+		return _cowdata.ptrw();
 	}
 	}
 
 
 	const V &getv(int p_index) const {
 	const V &getv(int p_index) const {
 
 
-		return _data[p_index].value;
+		return _cowdata.get(p_index).value;
 	}
 	}
 
 
 	V &getv(int p_index) {
 	V &getv(int p_index) {
 
 
-		return _data[p_index].value;
+		return _cowdata.get_m(p_index).value;
 	}
 	}
 
 
 	const T &getk(int p_index) const {
 	const T &getk(int p_index) const {
 
 
-		return _data[p_index].key;
+		return _cowdata.get(p_index).key;
 	}
 	}
 
 
 	T &getk(int p_index) {
 	T &getk(int p_index) {
 
 
-		return _data[p_index].key;
+		return _cowdata.get_m(p_index).key;
 	}
 	}
 
 
 	inline const V &operator[](const T &p_key) const {
 	inline const V &operator[](const T &p_key) const {
@@ -188,7 +188,7 @@ public:
 
 
 		CRASH_COND(pos < 0);
 		CRASH_COND(pos < 0);
 
 
-		return _data[pos].value;
+		return _cowdata.get(pos).value;
 	}
 	}
 
 
 	inline V &operator[](const T &p_key) {
 	inline V &operator[](const T &p_key) {
@@ -199,7 +199,14 @@ public:
 			pos = insert(p_key, val);
 			pos = insert(p_key, val);
 		}
 		}
 
 
-		return _data[pos].value;
+		return _cowdata.get_m(pos).value;
+	}
+
+	_FORCE_INLINE_ VMap(){};
+	_FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
+	inline VMap &operator=(const VMap &p_from) {
+		_cowdata._ref(p_from._cowdata);
+		return *this;
 	}
 	}
 };
 };
 #endif // VMAP_H
 #endif // VMAP_H

+ 1 - 1
core/vset.h

@@ -133,7 +133,7 @@ public:
 
 
 	inline T &operator[](int p_index) {
 	inline T &operator[](int p_index) {
 
 
-		return _data[p_index];
+		return _data.write[p_index];
 	}
 	}
 
 
 	inline const T &operator[](int p_index) const {
 	inline const T &operator[](int p_index) const {

+ 2 - 2
drivers/alsa/audio_driver_alsa.cpp

@@ -174,14 +174,14 @@ void AudioDriverALSA::thread_func(void *p_udata) {
 
 
 		if (!ad->active) {
 		if (!ad->active) {
 			for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
 			for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
-				ad->samples_out[i] = 0;
+				ad->samples_out.write[i] = 0;
 			}
 			}
 
 
 		} else {
 		} else {
 			ad->audio_server_process(ad->period_size, ad->samples_in.ptrw());
 			ad->audio_server_process(ad->period_size, ad->samples_in.ptrw());
 
 
 			for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
 			for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
-				ad->samples_out[i] = ad->samples_in[i] >> 16;
+				ad->samples_out.write[i] = ad->samples_in[i] >> 16;
 			}
 			}
 		}
 		}
 
 

+ 1 - 1
drivers/dummy/rasterizer_dummy.h

@@ -289,7 +289,7 @@ public:
 		ERR_FAIL_COND(!m);
 		ERR_FAIL_COND(!m);
 
 
 		m->surfaces.push_back(DummySurface());
 		m->surfaces.push_back(DummySurface());
-		DummySurface *s = &m->surfaces[m->surfaces.size() - 1];
+		DummySurface *s = &m->surfaces.write[m->surfaces.size() - 1];
 		s->format = p_format;
 		s->format = p_format;
 		s->primitive = p_primitive;
 		s->primitive = p_primitive;
 		s->array = p_array;
 		s->array = p_array;

+ 3 - 3
drivers/gles2/shader_compiler_gles2.cpp

@@ -325,10 +325,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
 				uniform_code += ";\n";
 				uniform_code += ";\n";
 
 
 				if (SL::is_sampler_type(E->get().type)) {
 				if (SL::is_sampler_type(E->get().type)) {
-					r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key());
-					r_gen_code.texture_hints[E->get().texture_order] = E->get().hint;
+					r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key());
+					r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
 				} else {
 				} else {
-					r_gen_code.uniforms[E->get().order] = E->key();
+					r_gen_code.uniforms.write[E->get().order] = E->key();
 				}
 				}
 
 
 				vertex_global += uniform_code.as_string();
 				vertex_global += uniform_code.as_string();

+ 2 - 2
drivers/gles2/shader_gles2.cpp

@@ -288,7 +288,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
 
 
 	if (cc) {
 	if (cc) {
 		for (int i = 0; i < cc->custom_defines.size(); i++) {
 		for (int i = 0; i < cc->custom_defines.size(); i++) {
-			strings.push_back(cc->custom_defines[i]);
+			strings.push_back(cc->custom_defines.write[i]);
 			DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i]));
 			DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i]));
 		}
 		}
 	}
 	}
@@ -502,7 +502,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
 	if (cc) {
 	if (cc) {
 		v.custom_uniform_locations.resize(cc->custom_uniforms.size());
 		v.custom_uniform_locations.resize(cc->custom_uniforms.size());
 		for (int i = 0; i < cc->custom_uniforms.size(); i++) {
 		for (int i = 0; i < cc->custom_uniforms.size(); i++) {
-			v.custom_uniform_locations[i] = glGetUniformLocation(v.id, String(cc->custom_uniforms[i]).ascii().get_data());
+			v.custom_uniform_locations.write[i] = glGetUniformLocation(v.id, String(cc->custom_uniforms[i]).ascii().get_data());
 		}
 		}
 	}
 	}
 
 

+ 14 - 14
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -355,7 +355,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
 		bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version;
 		bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version;
 
 
 		if (!should_realloc) {
 		if (!should_realloc) {
-			shadow_atlas->quadrants[q].shadows[s].version = p_light_version;
+			shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version;
 			//already existing, see if it should redraw or it's just OK
 			//already existing, see if it should redraw or it's just OK
 			return should_redraw;
 			return should_redraw;
 		}
 		}
@@ -365,7 +365,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
 		//find a better place
 		//find a better place
 		if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) {
 		if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) {
 			//found a better place!
 			//found a better place!
-			ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows[new_shadow];
+			ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
 			if (sh->owner.is_valid()) {
 			if (sh->owner.is_valid()) {
 				//is taken, but is invalid, erasing it
 				//is taken, but is invalid, erasing it
 				shadow_atlas->shadow_owners.erase(sh->owner);
 				shadow_atlas->shadow_owners.erase(sh->owner);
@@ -374,8 +374,8 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
 			}
 			}
 
 
 			//erase previous
 			//erase previous
-			shadow_atlas->quadrants[q].shadows[s].version = 0;
-			shadow_atlas->quadrants[q].shadows[s].owner = RID();
+			shadow_atlas->quadrants[q].shadows.write[s].version = 0;
+			shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
 
 
 			sh->owner = p_light_intance;
 			sh->owner = p_light_intance;
 			sh->alloc_tick = tick;
 			sh->alloc_tick = tick;
@@ -395,7 +395,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
 
 
 		//already existing, see if it should redraw or it's just OK
 		//already existing, see if it should redraw or it's just OK
 
 
-		shadow_atlas->quadrants[q].shadows[s].version = p_light_version;
+		shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version;
 
 
 		return should_redraw;
 		return should_redraw;
 	}
 	}
@@ -405,7 +405,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
 	//find a better place
 	//find a better place
 	if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) {
 	if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) {
 		//found a better place!
 		//found a better place!
-		ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows[new_shadow];
+		ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
 		if (sh->owner.is_valid()) {
 		if (sh->owner.is_valid()) {
 			//is taken, but is invalid, erasing it
 			//is taken, but is invalid, erasing it
 			shadow_atlas->shadow_owners.erase(sh->owner);
 			shadow_atlas->shadow_owners.erase(sh->owner);
@@ -502,7 +502,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size
 		//erase probes reference to this
 		//erase probes reference to this
 		if (reflection_atlas->reflections[i].owner.is_valid()) {
 		if (reflection_atlas->reflections[i].owner.is_valid()) {
 			ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner);
 			ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner);
-			reflection_atlas->reflections[i].owner = RID();
+			reflection_atlas->reflections.write[i].owner = RID();
 
 
 			ERR_CONTINUE(!reflection_probe_instance);
 			ERR_CONTINUE(!reflection_probe_instance);
 			reflection_probe_instance->reflection_atlas_index = -1;
 			reflection_probe_instance->reflection_atlas_index = -1;
@@ -574,7 +574,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int
 			//erase probes reference to this
 			//erase probes reference to this
 			if (reflection_atlas->reflections[i].owner.is_valid()) {
 			if (reflection_atlas->reflections[i].owner.is_valid()) {
 				ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner);
 				ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner);
-				reflection_atlas->reflections[i].owner = RID();
+				reflection_atlas->reflections.write[i].owner = RID();
 
 
 				ERR_CONTINUE(!reflection_probe_instance);
 				ERR_CONTINUE(!reflection_probe_instance);
 				reflection_probe_instance->reflection_atlas_index = -1;
 				reflection_probe_instance->reflection_atlas_index = -1;
@@ -629,7 +629,7 @@ void RasterizerSceneGLES3::reflection_probe_release_atlas_index(RID p_instance)
 
 
 	ERR_FAIL_COND(reflection_atlas->reflections[rpi->reflection_atlas_index].owner != rpi->self);
 	ERR_FAIL_COND(reflection_atlas->reflections[rpi->reflection_atlas_index].owner != rpi->self);
 
 
-	reflection_atlas->reflections[rpi->reflection_atlas_index].owner = RID();
+	reflection_atlas->reflections.write[rpi->reflection_atlas_index].owner = RID();
 
 
 	rpi->reflection_atlas_index = -1;
 	rpi->reflection_atlas_index = -1;
 	rpi->atlas = RID();
 	rpi->atlas = RID();
@@ -701,8 +701,8 @@ bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance
 		victim_rpi->reflection_atlas_index = -1;
 		victim_rpi->reflection_atlas_index = -1;
 	}
 	}
 
 
-	reflection_atlas->reflections[best_free].owner = p_instance;
-	reflection_atlas->reflections[best_free].last_frame = storage->frame.count;
+	reflection_atlas->reflections.write[best_free].owner = p_instance;
+	reflection_atlas->reflections.write[best_free].last_frame = storage->frame.count;
 
 
 	rpi->reflection_atlas_index = best_free;
 	rpi->reflection_atlas_index = best_free;
 	rpi->atlas = p_reflection_atlas;
 	rpi->atlas = p_reflection_atlas;
@@ -3848,8 +3848,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
 		state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_END, false);
 		state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_END, false);
 
 
 		//last step, swap with the framebuffer exposure, so the right exposure is kept int he framebuffer
 		//last step, swap with the framebuffer exposure, so the right exposure is kept int he framebuffer
-		SWAP(exposure_shrink[exposure_shrink.size() - 1].fbo, storage->frame.current_rt->exposure.fbo);
-		SWAP(exposure_shrink[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color);
+		SWAP(exposure_shrink.write[exposure_shrink.size() - 1].fbo, storage->frame.current_rt->exposure.fbo);
+		SWAP(exposure_shrink.write[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color);
 
 
 		glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
 		glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
 
 
@@ -4778,7 +4778,7 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
 			uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
 			uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
 			uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK;
 			uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK;
 
 
-			shadow_atlas->quadrants[q].shadows[s].owner = RID();
+			shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
 			shadow_atlas->shadow_owners.erase(p_rid);
 			shadow_atlas->shadow_owners.erase(p_rid);
 		}
 		}
 
 

+ 44 - 44
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -2670,7 +2670,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
 				}
 				}
 			}
 			}
 
 
-			material->textures[E->get().texture_order] = texture;
+			material->textures.write[E->get().texture_order] = texture;
 		}
 		}
 
 
 	} else {
 	} else {
@@ -2975,9 +2975,9 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
 
 
 	for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
 	for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
 		if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) {
 		if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) {
-			surface->skeleton_bone_used[i] = false;
+			surface->skeleton_bone_used.write[i] = false;
 		} else {
 		} else {
-			surface->skeleton_bone_used[i] = true;
+			surface->skeleton_bone_used.write[i] = true;
 		}
 		}
 	}
 	}
 
 
@@ -3878,29 +3878,29 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
 			int custom_data_from = 0;
 			int custom_data_from = 0;
 
 
 			if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) {
 			if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) {
-				multimesh->data[i + 0] = 1.0;
-				multimesh->data[i + 1] = 0.0;
-				multimesh->data[i + 2] = 0.0;
-				multimesh->data[i + 3] = 0.0;
-				multimesh->data[i + 4] = 0.0;
-				multimesh->data[i + 5] = 1.0;
-				multimesh->data[i + 6] = 0.0;
-				multimesh->data[i + 7] = 0.0;
+				multimesh->data.write[i + 0] = 1.0;
+				multimesh->data.write[i + 1] = 0.0;
+				multimesh->data.write[i + 2] = 0.0;
+				multimesh->data.write[i + 3] = 0.0;
+				multimesh->data.write[i + 4] = 0.0;
+				multimesh->data.write[i + 5] = 1.0;
+				multimesh->data.write[i + 6] = 0.0;
+				multimesh->data.write[i + 7] = 0.0;
 				color_from = 8;
 				color_from = 8;
 				custom_data_from = 8;
 				custom_data_from = 8;
 			} else {
 			} else {
-				multimesh->data[i + 0] = 1.0;
-				multimesh->data[i + 1] = 0.0;
-				multimesh->data[i + 2] = 0.0;
-				multimesh->data[i + 3] = 0.0;
-				multimesh->data[i + 4] = 0.0;
-				multimesh->data[i + 5] = 1.0;
-				multimesh->data[i + 6] = 0.0;
-				multimesh->data[i + 7] = 0.0;
-				multimesh->data[i + 8] = 0.0;
-				multimesh->data[i + 9] = 0.0;
-				multimesh->data[i + 10] = 1.0;
-				multimesh->data[i + 11] = 0.0;
+				multimesh->data.write[i + 0] = 1.0;
+				multimesh->data.write[i + 1] = 0.0;
+				multimesh->data.write[i + 2] = 0.0;
+				multimesh->data.write[i + 3] = 0.0;
+				multimesh->data.write[i + 4] = 0.0;
+				multimesh->data.write[i + 5] = 1.0;
+				multimesh->data.write[i + 6] = 0.0;
+				multimesh->data.write[i + 7] = 0.0;
+				multimesh->data.write[i + 8] = 0.0;
+				multimesh->data.write[i + 9] = 0.0;
+				multimesh->data.write[i + 10] = 1.0;
+				multimesh->data.write[i + 11] = 0.0;
 				color_from = 12;
 				color_from = 12;
 				custom_data_from = 12;
 				custom_data_from = 12;
 			}
 			}
@@ -3915,14 +3915,14 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
 				} cu;
 				} cu;
 
 
 				cu.colu = 0xFFFFFFFF;
 				cu.colu = 0xFFFFFFFF;
-				multimesh->data[i + color_from + 0] = cu.colf;
+				multimesh->data.write[i + color_from + 0] = cu.colf;
 				custom_data_from = color_from + 1;
 				custom_data_from = color_from + 1;
 
 
 			} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
 			} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
-				multimesh->data[i + color_from + 0] = 1.0;
-				multimesh->data[i + color_from + 1] = 1.0;
-				multimesh->data[i + color_from + 2] = 1.0;
-				multimesh->data[i + color_from + 3] = 1.0;
+				multimesh->data.write[i + color_from + 0] = 1.0;
+				multimesh->data.write[i + color_from + 1] = 1.0;
+				multimesh->data.write[i + color_from + 2] = 1.0;
+				multimesh->data.write[i + color_from + 3] = 1.0;
 				custom_data_from = color_from + 4;
 				custom_data_from = color_from + 4;
 			}
 			}
 
 
@@ -3936,13 +3936,13 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
 				} cu;
 				} cu;
 
 
 				cu.colu = 0;
 				cu.colu = 0;
-				multimesh->data[i + custom_data_from + 0] = cu.colf;
+				multimesh->data.write[i + custom_data_from + 0] = cu.colf;
 
 
 			} else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) {
 			} else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) {
-				multimesh->data[i + custom_data_from + 0] = 0.0;
-				multimesh->data[i + custom_data_from + 1] = 0.0;
-				multimesh->data[i + custom_data_from + 2] = 0.0;
-				multimesh->data[i + custom_data_from + 3] = 0.0;
+				multimesh->data.write[i + custom_data_from + 0] = 0.0;
+				multimesh->data.write[i + custom_data_from + 1] = 0.0;
+				multimesh->data.write[i + custom_data_from + 2] = 0.0;
+				multimesh->data.write[i + custom_data_from + 3] = 0.0;
 			}
 			}
 		}
 		}
 
 
@@ -4004,7 +4004,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform(RID p_multimesh, i
 	ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D);
 	ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D);
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index];
+	float *dataptr = &multimesh->data.write[stride * p_index];
 
 
 	dataptr[0] = p_transform.basis.elements[0][0];
 	dataptr[0] = p_transform.basis.elements[0][0];
 	dataptr[1] = p_transform.basis.elements[0][1];
 	dataptr[1] = p_transform.basis.elements[0][1];
@@ -4035,7 +4035,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform_2d(RID p_multimesh
 	ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D);
 	ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D);
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index];
+	float *dataptr = &multimesh->data.write[stride * p_index];
 
 
 	dataptr[0] = p_transform.elements[0][0];
 	dataptr[0] = p_transform.elements[0][0];
 	dataptr[1] = p_transform.elements[1][0];
 	dataptr[1] = p_transform.elements[1][0];
@@ -4061,7 +4061,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p
 	ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE);
 	ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE);
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats];
+	float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
 
 
 	if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
 	if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
 
 
@@ -4094,7 +4094,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_custom_data(RID p_multimesh,
 	ERR_FAIL_COND(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE);
 	ERR_FAIL_COND(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE);
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
+	float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
 
 
 	if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
 	if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
 
 
@@ -4134,7 +4134,7 @@ Transform RasterizerStorageGLES3::multimesh_instance_get_transform(RID p_multime
 	ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D, Transform());
 	ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D, Transform());
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index];
+	float *dataptr = &multimesh->data.write[stride * p_index];
 
 
 	Transform xform;
 	Transform xform;
 
 
@@ -4161,7 +4161,7 @@ Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_mu
 	ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D, Transform2D());
 	ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D, Transform2D());
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index];
+	float *dataptr = &multimesh->data.write[stride * p_index];
 
 
 	Transform2D xform;
 	Transform2D xform;
 
 
@@ -4183,7 +4183,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int
 	ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color());
 	ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color());
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats];
+	float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
 
 
 	if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
 	if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
 		union {
 		union {
@@ -4216,7 +4216,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_custom_data(RID p_multimesh
 	ERR_FAIL_COND_V(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE, Color());
 	ERR_FAIL_COND_V(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE, Color());
 
 
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
 	int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
-	float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
+	float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
 
 
 	if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
 	if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
 		union {
 		union {
@@ -5772,7 +5772,7 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p
 	Particles *particles = particles_owner.getornull(p_particles);
 	Particles *particles = particles_owner.getornull(p_particles);
 	ERR_FAIL_COND(!particles);
 	ERR_FAIL_COND(!particles);
 	ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
 	ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
-	particles->draw_passes[p_pass] = p_mesh;
+	particles->draw_passes.write[p_pass] = p_mesh;
 }
 }
 
 
 void RasterizerStorageGLES3::particles_restart(RID p_particles) {
 void RasterizerStorageGLES3::particles_restart(RID p_particles) {
@@ -6646,7 +6646,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
 
 
 			for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) {
 			for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) {
 
 
-				RenderTarget::Effects::MipMaps::Size &mm = rt->effects.mip_maps[i].sizes[j];
+				RenderTarget::Effects::MipMaps::Size &mm = rt->effects.mip_maps[i].sizes.write[j];
 
 
 				glGenFramebuffers(1, &mm.fbo);
 				glGenFramebuffers(1, &mm.fbo);
 				glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
 				glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
@@ -7058,7 +7058,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
 
 
 			for (int i = 0; i < ins->materials.size(); i++) {
 			for (int i = 0; i < ins->materials.size(); i++) {
 				if (ins->materials[i] == p_rid) {
 				if (ins->materials[i] == p_rid) {
-					ins->materials[i] = RID();
+					ins->materials.write[i] = RID();
 				}
 				}
 			}
 			}
 		}
 		}

+ 5 - 5
drivers/gles3/shader_compiler_gles3.cpp

@@ -365,17 +365,17 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
 				if (SL::is_sampler_type(E->get().type)) {
 				if (SL::is_sampler_type(E->get().type)) {
 					r_gen_code.vertex_global += ucode;
 					r_gen_code.vertex_global += ucode;
 					r_gen_code.fragment_global += ucode;
 					r_gen_code.fragment_global += ucode;
-					r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key());
-					r_gen_code.texture_hints[E->get().texture_order] = E->get().hint;
+					r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key());
+					r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
 				} else {
 				} else {
 					if (!uses_uniforms) {
 					if (!uses_uniforms) {
 
 
 						r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
 						r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
 						uses_uniforms = true;
 						uses_uniforms = true;
 					}
 					}
-					uniform_defines[E->get().order] = ucode;
-					uniform_sizes[E->get().order] = _get_datatype_size(E->get().type);
-					uniform_alignments[E->get().order] = _get_datatype_alignment(E->get().type);
+					uniform_defines.write[E->get().order] = ucode;
+					uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type);
+					uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type);
 				}
 				}
 
 
 				p_actions.uniforms->insert(E->key(), E->get());
 				p_actions.uniforms->insert(E->key(), E->get());

+ 1 - 1
drivers/gles3/shader_gles3.cpp

@@ -554,7 +554,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
 		v.texture_uniform_locations.resize(cc->texture_uniforms.size());
 		v.texture_uniform_locations.resize(cc->texture_uniforms.size());
 		for (int i = 0; i < cc->texture_uniforms.size(); i++) {
 		for (int i = 0; i < cc->texture_uniforms.size(); i++) {
 
 
-			v.texture_uniform_locations[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data());
+			v.texture_uniform_locations.write[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data());
 			glUniform1i(v.texture_uniform_locations[i], i + base_material_tex_index);
 			glUniform1i(v.texture_uniform_locations[i], i + base_material_tex_index);
 		}
 		}
 	}
 	}

+ 4 - 4
drivers/pulseaudio/audio_driver_pulseaudio.cpp

@@ -295,7 +295,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 
 
 		if (!ad->active) {
 		if (!ad->active) {
 			for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
 			for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
-				ad->samples_out[i] = 0;
+				ad->samples_out.write[i] = 0;
 			}
 			}
 
 
 		} else {
 		} else {
@@ -303,7 +303,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 
 
 			if (ad->channels == ad->pa_map.channels) {
 			if (ad->channels == ad->pa_map.channels) {
 				for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
 				for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
-					ad->samples_out[i] = ad->samples_in[i] >> 16;
+					ad->samples_out.write[i] = ad->samples_in[i] >> 16;
 				}
 				}
 			} else {
 			} else {
 				// Uneven amount of channels
 				// Uneven amount of channels
@@ -312,11 +312,11 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 
 
 				for (unsigned int i = 0; i < ad->buffer_frames; i++) {
 				for (unsigned int i = 0; i < ad->buffer_frames; i++) {
 					for (unsigned int j = 0; j < ad->pa_map.channels - 1; j++) {
 					for (unsigned int j = 0; j < ad->pa_map.channels - 1; j++) {
-						ad->samples_out[out_idx++] = ad->samples_in[in_idx++] >> 16;
+						ad->samples_out.write[out_idx++] = ad->samples_in[in_idx++] >> 16;
 					}
 					}
 					uint32_t l = ad->samples_in[in_idx++];
 					uint32_t l = ad->samples_in[in_idx++];
 					uint32_t r = ad->samples_in[in_idx++];
 					uint32_t r = ad->samples_in[in_idx++];
-					ad->samples_out[out_idx++] = (l >> 1 + r >> 1) >> 16;
+					ad->samples_out.write[out_idx++] = (l >> 1 + r >> 1) >> 16;
 				}
 				}
 			}
 			}
 		}
 		}

+ 1 - 1
drivers/wasapi/audio_driver_wasapi.cpp

@@ -447,7 +447,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
 			ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
 			ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
 		} else {
 		} else {
 			for (unsigned int i = 0; i < ad->buffer_size; i++) {
 			for (unsigned int i = 0; i < ad->buffer_size; i++) {
-				ad->samples_in[i] = 0;
+				ad->samples_in.write[i] = 0;
 			}
 			}
 		}
 		}
 
 

+ 6 - 6
editor/animation_track_editor.cpp

@@ -231,10 +231,10 @@ public:
 							if (Variant::can_convert(args[idx].get_type(), t)) {
 							if (Variant::can_convert(args[idx].get_type(), t)) {
 								Variant old = args[idx];
 								Variant old = args[idx];
 								Variant *ptrs[1] = { &old };
 								Variant *ptrs[1] = { &old };
-								args[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
+								args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
 							} else {
 							} else {
 
 
-								args[idx] = Variant::construct(t, NULL, 0, err);
+								args.write[idx] = Variant::construct(t, NULL, 0, err);
 							}
 							}
 							change_notify_deserved = true;
 							change_notify_deserved = true;
 							d_new["args"] = args;
 							d_new["args"] = args;
@@ -248,7 +248,7 @@ public:
 							_fix_node_path(value);
 							_fix_node_path(value);
 						}
 						}
 
 
-						args[idx] = value;
+						args.write[idx] = value;
 						d_new["args"] = args;
 						d_new["args"] = args;
 						mergeable = true;
 						mergeable = true;
 					}
 					}
@@ -3316,7 +3316,7 @@ void AnimationTrackEditor::_update_tracks() {
 					}
 					}
 
 
 					for (int j = 0; j < track_edit_plugins.size(); j++) {
 					for (int j = 0; j < track_edit_plugins.size(); j++) {
-						track_edit = track_edit_plugins[j]->create_value_track_edit(object, pinfo.type, pinfo.name, pinfo.hint, pinfo.hint_string, pinfo.usage);
+						track_edit = track_edit_plugins.write[j]->create_value_track_edit(object, pinfo.type, pinfo.name, pinfo.hint, pinfo.hint_string, pinfo.usage);
 						if (track_edit) {
 						if (track_edit) {
 							break;
 							break;
 						}
 						}
@@ -3327,7 +3327,7 @@ void AnimationTrackEditor::_update_tracks() {
 		if (animation->track_get_type(i) == Animation::TYPE_AUDIO) {
 		if (animation->track_get_type(i) == Animation::TYPE_AUDIO) {
 
 
 			for (int j = 0; j < track_edit_plugins.size(); j++) {
 			for (int j = 0; j < track_edit_plugins.size(); j++) {
-				track_edit = track_edit_plugins[j]->create_audio_track_edit();
+				track_edit = track_edit_plugins.write[j]->create_audio_track_edit();
 				if (track_edit) {
 				if (track_edit) {
 					break;
 					break;
 				}
 				}
@@ -3344,7 +3344,7 @@ void AnimationTrackEditor::_update_tracks() {
 
 
 			if (node && Object::cast_to<AnimationPlayer>(node)) {
 			if (node && Object::cast_to<AnimationPlayer>(node)) {
 				for (int j = 0; j < track_edit_plugins.size(); j++) {
 				for (int j = 0; j < track_edit_plugins.size(); j++) {
-					track_edit = track_edit_plugins[j]->create_animation_track_edit(node);
+					track_edit = track_edit_plugins.write[j]->create_animation_track_edit(node);
 					if (track_edit) {
 					if (track_edit) {
 						break;
 						break;
 					}
 					}

+ 4 - 4
editor/animation_track_editor_plugins.cpp

@@ -271,8 +271,8 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
 			float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
 			float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
 
 
 			int idx = i - from_x;
 			int idx = i - from_x;
-			lines[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
-			lines[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
+			lines.write[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
+			lines.write[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
 		}
 		}
 
 
 		Vector<Color> color;
 		Vector<Color> color;
@@ -883,8 +883,8 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
 		float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
 		float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
 
 
 		int idx = i - from_x;
 		int idx = i - from_x;
-		lines[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
-		lines[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
+		lines.write[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
+		lines.write[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
 	}
 	}
 
 
 	Vector<Color> color;
 	Vector<Color> color;

+ 2 - 2
editor/audio_stream_preview.cpp

@@ -118,8 +118,8 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
 			uint8_t pfrom = CLAMP((min * 0.5 + 0.5) * 255, 0, 255);
 			uint8_t pfrom = CLAMP((min * 0.5 + 0.5) * 255, 0, 255);
 			uint8_t pto = CLAMP((max * 0.5 + 0.5) * 255, 0, 255);
 			uint8_t pto = CLAMP((max * 0.5 + 0.5) * 255, 0, 255);
 
 
-			preview->preview->preview[(ofs_write + i) * 2 + 0] = pfrom;
-			preview->preview->preview[(ofs_write + i) * 2 + 1] = pto;
+			preview->preview->preview.write[(ofs_write + i) * 2 + 0] = pfrom;
+			preview->preview->preview.write[(ofs_write + i) * 2 + 1] = pto;
 		}
 		}
 
 
 		frames_todo -= to_read;
 		frames_todo -= to_read;

+ 1 - 1
editor/code_editor.cpp

@@ -725,7 +725,7 @@ void CodeTextEditor::_complete_request() {
 	int i = 0;
 	int i = 0;
 	for (List<String>::Element *E = entries.front(); E; E = E->next()) {
 	for (List<String>::Element *E = entries.front(); E; E = E->next()) {
 
 
-		strs[i++] = E->get();
+		strs.write[i++] = E->get();
 	}
 	}
 
 
 	text_editor->code_complete(strs, forced);
 	text_editor->code_complete(strs, forced);

+ 32 - 32
editor/collada/collada.cpp

@@ -191,7 +191,7 @@ Transform Collada::Node::get_global_transform() const {
 		return default_transform;
 		return default_transform;
 }
 }
 
 
-Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
+Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
 
 
 	ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
 	ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
 	int i = 0;
 	int i = 0;
@@ -225,22 +225,22 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
 				ret.resize(16);
 				ret.resize(16);
 				Transform tr;
 				Transform tr;
 				// i wonder why collada matrices are transposed, given that's opposed to opengl..
 				// i wonder why collada matrices are transposed, given that's opposed to opengl..
-				ret[0] = interp.basis.elements[0][0];
-				ret[1] = interp.basis.elements[0][1];
-				ret[2] = interp.basis.elements[0][2];
-				ret[4] = interp.basis.elements[1][0];
-				ret[5] = interp.basis.elements[1][1];
-				ret[6] = interp.basis.elements[1][2];
-				ret[8] = interp.basis.elements[2][0];
-				ret[9] = interp.basis.elements[2][1];
-				ret[10] = interp.basis.elements[2][2];
-				ret[3] = interp.origin.x;
-				ret[7] = interp.origin.y;
-				ret[11] = interp.origin.z;
-				ret[12] = 0;
-				ret[13] = 0;
-				ret[14] = 0;
-				ret[15] = 1;
+				ret.write[0] = interp.basis.elements[0][0];
+				ret.write[1] = interp.basis.elements[0][1];
+				ret.write[2] = interp.basis.elements[0][2];
+				ret.write[4] = interp.basis.elements[1][0];
+				ret.write[5] = interp.basis.elements[1][1];
+				ret.write[6] = interp.basis.elements[1][2];
+				ret.write[8] = interp.basis.elements[2][0];
+				ret.write[9] = interp.basis.elements[2][1];
+				ret.write[10] = interp.basis.elements[2][2];
+				ret.write[3] = interp.origin.x;
+				ret.write[7] = interp.origin.y;
+				ret.write[11] = interp.origin.z;
+				ret.write[12] = 0;
+				ret.write[13] = 0;
+				ret.write[14] = 0;
+				ret.write[15] = 1;
 
 
 				return ret;
 				return ret;
 			} else {
 			} else {
@@ -249,7 +249,7 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
 				dest.resize(keys[i].data.size());
 				dest.resize(keys[i].data.size());
 				for (int j = 0; j < dest.size(); j++) {
 				for (int j = 0; j < dest.size(); j++) {
 
 
-					dest[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
+					dest.write[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
 				}
 				}
 				return dest;
 				return dest;
 				//interpolate one by one
 				//interpolate one by one
@@ -452,7 +452,7 @@ Transform Collada::_read_transform(XMLParser &parser) {
 	Vector<float> farr;
 	Vector<float> farr;
 	farr.resize(16);
 	farr.resize(16);
 	for (int i = 0; i < 16; i++) {
 	for (int i = 0; i < 16; i++) {
-		farr[i] = array[i].to_double();
+		farr.write[i] = array[i].to_double();
 	}
 	}
 
 
 	return _read_transform_from_array(farr);
 	return _read_transform_from_array(farr);
@@ -1104,7 +1104,7 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
 								int from = prim.indices.size();
 								int from = prim.indices.size();
 								prim.indices.resize(from + values.size());
 								prim.indices.resize(from + values.size());
 								for (int i = 0; i < values.size(); i++)
 								for (int i = 0; i < values.size(); i++)
-									prim.indices[from + i] = values[i];
+									prim.indices.write[from + i] = values[i];
 
 
 							} else if (prim.vertex_size > 0) {
 							} else if (prim.vertex_size > 0) {
 								prim.indices = values;
 								prim.indices = values;
@@ -1884,7 +1884,7 @@ void Collada::_parse_animation(XMLParser &parser) {
 			track.keys.resize(key_count);
 			track.keys.resize(key_count);
 
 
 			for (int j = 0; j < key_count; j++) {
 			for (int j = 0; j < key_count; j++) {
-				track.keys[j].time = time_keys[j];
+				track.keys.write[j].time = time_keys[j];
 				state.animation_length = MAX(state.animation_length, time_keys[j]);
 				state.animation_length = MAX(state.animation_length, time_keys[j]);
 			}
 			}
 
 
@@ -1905,9 +1905,9 @@ void Collada::_parse_animation(XMLParser &parser) {
 			ERR_CONTINUE((output.size() / stride) != key_count);
 			ERR_CONTINUE((output.size() / stride) != key_count);
 
 
 			for (int j = 0; j < key_count; j++) {
 			for (int j = 0; j < key_count; j++) {
-				track.keys[j].data.resize(output_len);
+				track.keys.write[j].data.resize(output_len);
 				for (int k = 0; k < output_len; k++)
 				for (int k = 0; k < output_len; k++)
-					track.keys[j].data[k] = output[l + j * stride + k]; //super weird but should work:
+					track.keys.write[j].data.write[k] = output[l + j * stride + k]; //super weird but should work:
 			}
 			}
 
 
 			if (sampler.has("INTERPOLATION")) {
 			if (sampler.has("INTERPOLATION")) {
@@ -1919,9 +1919,9 @@ void Collada::_parse_animation(XMLParser &parser) {
 
 
 				for (int j = 0; j < key_count; j++) {
 				for (int j = 0; j < key_count; j++) {
 					if (interps[j] == "BEZIER")
 					if (interps[j] == "BEZIER")
-						track.keys[j].interp_type = AnimationTrack::INTERP_BEZIER;
+						track.keys.write[j].interp_type = AnimationTrack::INTERP_BEZIER;
 					else
 					else
-						track.keys[j].interp_type = AnimationTrack::INTERP_LINEAR;
+						track.keys.write[j].interp_type = AnimationTrack::INTERP_LINEAR;
 				}
 				}
 			}
 			}
 
 
@@ -1939,8 +1939,8 @@ void Collada::_parse_animation(XMLParser &parser) {
 				ERR_CONTINUE(outangents.size() != key_count * 2 * names.size());
 				ERR_CONTINUE(outangents.size() != key_count * 2 * names.size());
 
 
 				for (int j = 0; j < key_count; j++) {
 				for (int j = 0; j < key_count; j++) {
-					track.keys[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
-					track.keys[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
+					track.keys.write[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
+					track.keys.write[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
 				}
 				}
 			}
 			}
 
 
@@ -2118,7 +2118,7 @@ void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
 
 
 		for (int i = 0; i < nj->children.size(); i++) {
 		for (int i = 0; i < nj->children.size(); i++) {
 
 
-			_joint_set_owner(nj->children[i], p_owner);
+			_joint_set_owner(nj->children.write[i], p_owner);
 		}
 		}
 	}
 	}
 }
 }
@@ -2147,7 +2147,7 @@ void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton
 	}
 	}
 
 
 	for (int i = 0; i < node->children.size(); i++) {
 	for (int i = 0; i < node->children.size(); i++) {
-		_create_skeletons(&node->children[i], p_skeleton);
+		_create_skeletons(&node->children.write[i], p_skeleton);
 	}
 	}
 }
 }
 
 
@@ -2314,7 +2314,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
 			for (int i = 0; i < gp->children.size(); i++) {
 			for (int i = 0; i < gp->children.size(); i++) {
 
 
 				if (gp->children[i] == parent) {
 				if (gp->children[i] == parent) {
-					gp->children[i] = node;
+					gp->children.write[i] = node;
 					found = true;
 					found = true;
 					break;
 					break;
 				}
 				}
@@ -2330,7 +2330,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
 
 
 				if (p_vscene->root_nodes[i] == parent) {
 				if (p_vscene->root_nodes[i] == parent) {
 
 
-					p_vscene->root_nodes[i] = node;
+					p_vscene->root_nodes.write[i] = node;
 					found = true;
 					found = true;
 					break;
 					break;
 				}
 				}
@@ -2466,7 +2466,7 @@ void Collada::_optimize() {
 
 
 		VisualScene &vs = E->get();
 		VisualScene &vs = E->get();
 		for (int i = 0; i < vs.root_nodes.size(); i++) {
 		for (int i = 0; i < vs.root_nodes.size(); i++) {
-			_create_skeletons(&vs.root_nodes[i]);
+			_create_skeletons(&vs.root_nodes.write[i]);
 		}
 		}
 
 
 		for (int i = 0; i < vs.root_nodes.size(); i++) {
 		for (int i = 0; i < vs.root_nodes.size(); i++) {

+ 2 - 2
editor/collada/collada.h

@@ -312,7 +312,7 @@ public:
 					total += weights[i].weight;
 					total += weights[i].weight;
 				if (total)
 				if (total)
 					for (int i = 0; i < 4; i++)
 					for (int i = 0; i < 4; i++)
-						weights[i].weight /= total;
+						weights.write[i].weight /= total;
 			}
 			}
 		}
 		}
 
 
@@ -515,7 +515,7 @@ public:
 			Key() { interp_type = INTERP_LINEAR; }
 			Key() { interp_type = INTERP_LINEAR; }
 		};
 		};
 
 
-		Vector<float> get_value_at_time(float p_time);
+		Vector<float> get_value_at_time(float p_time) const;
 
 
 		Vector<Key> keys;
 		Vector<Key> keys;
 
 

+ 1 - 1
editor/connections_dialog.cpp

@@ -51,7 +51,7 @@ public:
 		if (name.begins_with("bind/")) {
 		if (name.begins_with("bind/")) {
 			int which = name.get_slice("/", 1).to_int() - 1;
 			int which = name.get_slice("/", 1).to_int() - 1;
 			ERR_FAIL_INDEX_V(which, params.size(), false);
 			ERR_FAIL_INDEX_V(which, params.size(), false);
-			params[which] = p_value;
+			params.write[which] = p_value;
 		} else
 		} else
 			return false;
 			return false;
 
 

+ 14 - 14
editor/doc/doc_data.cpp

@@ -58,7 +58,7 @@ void DocData::merge_from(const DocData &p_data) {
 
 
 		for (int i = 0; i < c.methods.size(); i++) {
 		for (int i = 0; i < c.methods.size(); i++) {
 
 
-			MethodDoc &m = c.methods[i];
+			MethodDoc &m = c.methods.write[i];
 
 
 			for (int j = 0; j < cf.methods.size(); j++) {
 			for (int j = 0; j < cf.methods.size(); j++) {
 
 
@@ -72,13 +72,13 @@ void DocData::merge_from(const DocData &p_data) {
 				Vector<bool> arg_used;
 				Vector<bool> arg_used;
 				arg_used.resize(arg_count);
 				arg_used.resize(arg_count);
 				for (int l = 0; l < arg_count; ++l)
 				for (int l = 0; l < arg_count; ++l)
-					arg_used[l] = false;
+					arg_used.write[l] = false;
 				// also there is no guarantee that argument ordering will match, so we
 				// also there is no guarantee that argument ordering will match, so we
 				// have to check one by one so we make sure we have an exact match
 				// have to check one by one so we make sure we have an exact match
 				for (int k = 0; k < arg_count; ++k) {
 				for (int k = 0; k < arg_count; ++k) {
 					for (int l = 0; l < arg_count; ++l)
 					for (int l = 0; l < arg_count; ++l)
 						if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
 						if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
-							arg_used[l] = true;
+							arg_used.write[l] = true;
 							break;
 							break;
 						}
 						}
 				}
 				}
@@ -98,7 +98,7 @@ void DocData::merge_from(const DocData &p_data) {
 
 
 		for (int i = 0; i < c.signals.size(); i++) {
 		for (int i = 0; i < c.signals.size(); i++) {
 
 
-			MethodDoc &m = c.signals[i];
+			MethodDoc &m = c.signals.write[i];
 
 
 			for (int j = 0; j < cf.signals.size(); j++) {
 			for (int j = 0; j < cf.signals.size(); j++) {
 
 
@@ -113,7 +113,7 @@ void DocData::merge_from(const DocData &p_data) {
 
 
 		for (int i = 0; i < c.constants.size(); i++) {
 		for (int i = 0; i < c.constants.size(); i++) {
 
 
-			ConstantDoc &m = c.constants[i];
+			ConstantDoc &m = c.constants.write[i];
 
 
 			for (int j = 0; j < cf.constants.size(); j++) {
 			for (int j = 0; j < cf.constants.size(); j++) {
 
 
@@ -128,7 +128,7 @@ void DocData::merge_from(const DocData &p_data) {
 
 
 		for (int i = 0; i < c.properties.size(); i++) {
 		for (int i = 0; i < c.properties.size(); i++) {
 
 
-			PropertyDoc &p = c.properties[i];
+			PropertyDoc &p = c.properties.write[i];
 
 
 			for (int j = 0; j < cf.properties.size(); j++) {
 			for (int j = 0; j < cf.properties.size(); j++) {
 
 
@@ -146,7 +146,7 @@ void DocData::merge_from(const DocData &p_data) {
 
 
 		for (int i = 0; i < c.theme_properties.size(); i++) {
 		for (int i = 0; i < c.theme_properties.size(); i++) {
 
 
-			PropertyDoc &p = c.theme_properties[i];
+			PropertyDoc &p = c.theme_properties.write[i];
 
 
 			for (int j = 0; j < cf.theme_properties.size(); j++) {
 			for (int j = 0; j < cf.theme_properties.size(); j++) {
 
 
@@ -1020,7 +1020,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
 
 
 		for (int i = 0; i < c.methods.size(); i++) {
 		for (int i = 0; i < c.methods.size(); i++) {
 
 
-			MethodDoc &m = c.methods[i];
+			const MethodDoc &m = c.methods[i];
 
 
 			String qualifiers;
 			String qualifiers;
 			if (m.qualifiers != "")
 			if (m.qualifiers != "")
@@ -1040,7 +1040,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
 
 
 			for (int j = 0; j < m.arguments.size(); j++) {
 			for (int j = 0; j < m.arguments.size(); j++) {
 
 
-				ArgumentDoc &a = m.arguments[j];
+				const ArgumentDoc &a = m.arguments[j];
 
 
 				String enum_text;
 				String enum_text;
 				if (a.enumeration != String()) {
 				if (a.enumeration != String()) {
@@ -1075,7 +1075,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
 				if (c.properties[i].enumeration != String()) {
 				if (c.properties[i].enumeration != String()) {
 					enum_text = " enum=\"" + c.properties[i].enumeration + "\"";
 					enum_text = " enum=\"" + c.properties[i].enumeration + "\"";
 				}
 				}
-				PropertyDoc &p = c.properties[i];
+				const PropertyDoc &p = c.properties[i];
 				_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + enum_text + ">");
 				_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + enum_text + ">");
 				_write_string(f, 3, p.description.strip_edges().xml_escape());
 				_write_string(f, 3, p.description.strip_edges().xml_escape());
 				_write_string(f, 2, "</member>");
 				_write_string(f, 2, "</member>");
@@ -1090,11 +1090,11 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
 			_write_string(f, 1, "<signals>");
 			_write_string(f, 1, "<signals>");
 			for (int i = 0; i < c.signals.size(); i++) {
 			for (int i = 0; i < c.signals.size(); i++) {
 
 
-				MethodDoc &m = c.signals[i];
+				const MethodDoc &m = c.signals[i];
 				_write_string(f, 2, "<signal name=\"" + m.name + "\">");
 				_write_string(f, 2, "<signal name=\"" + m.name + "\">");
 				for (int j = 0; j < m.arguments.size(); j++) {
 				for (int j = 0; j < m.arguments.size(); j++) {
 
 
-					ArgumentDoc &a = m.arguments[j];
+					const ArgumentDoc &a = m.arguments[j];
 					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">");
 					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">");
 					_write_string(f, 3, "</argument>");
 					_write_string(f, 3, "</argument>");
 				}
 				}
@@ -1113,7 +1113,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
 
 
 		for (int i = 0; i < c.constants.size(); i++) {
 		for (int i = 0; i < c.constants.size(); i++) {
 
 
-			ConstantDoc &k = c.constants[i];
+			const ConstantDoc &k = c.constants[i];
 			if (k.enumeration != String()) {
 			if (k.enumeration != String()) {
 				_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
 				_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
 			} else {
 			} else {
@@ -1132,7 +1132,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
 			_write_string(f, 1, "<theme_items>");
 			_write_string(f, 1, "<theme_items>");
 			for (int i = 0; i < c.theme_properties.size(); i++) {
 			for (int i = 0; i < c.theme_properties.size(); i++) {
 
 
-				PropertyDoc &p = c.theme_properties[i];
+				const PropertyDoc &p = c.theme_properties[i];
 				_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">");
 				_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">");
 				_write_string(f, 2, "</theme_item>");
 				_write_string(f, 2, "</theme_item>");
 			}
 			}

+ 1 - 1
editor/editor_autoload_settings.cpp

@@ -598,7 +598,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
 	int i = 0;
 	int i = 0;
 
 
 	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
 	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
-		orders[i++] = E->get().order;
+		orders.write[i++] = E->get().order;
 	}
 	}
 
 
 	orders.sort();
 	orders.sort();

+ 14 - 14
editor/editor_data.cpp

@@ -62,7 +62,7 @@ void EditorHistory::cleanup_history() {
 				fail = true;
 				fail = true;
 			} else {
 			} else {
 				//after level, clip
 				//after level, clip
-				history[i].path.resize(j);
+				history.write[i].path.resize(j);
 			}
 			}
 
 
 			break;
 			break;
@@ -100,14 +100,14 @@ void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int
 
 
 	if (p_property != "" && has_prev) {
 	if (p_property != "" && has_prev) {
 		//add a sub property
 		//add a sub property
-		History &pr = history[current];
+		History &pr = history.write[current];
 		h = pr;
 		h = pr;
 		h.path.resize(h.level + 1);
 		h.path.resize(h.level + 1);
 		h.path.push_back(o);
 		h.path.push_back(o);
 		h.level++;
 		h.level++;
 	} else if (p_level_change != -1 && has_prev) {
 	} else if (p_level_change != -1 && has_prev) {
 		//add a sub property
 		//add a sub property
-		History &pr = history[current];
+		History &pr = history.write[current];
 		h = pr;
 		h = pr;
 		ERR_FAIL_INDEX(p_level_change, h.path.size());
 		ERR_FAIL_INDEX(p_level_change, h.path.size());
 		h.level = p_level_change;
 		h.level = p_level_change;
@@ -206,7 +206,7 @@ ObjectID EditorHistory::get_current() {
 	if (current < 0 || current >= history.size())
 	if (current < 0 || current >= history.size())
 		return 0;
 		return 0;
 
 
-	History &h = history[current];
+	History &h = history.write[current];
 	Object *obj = ObjectDB::get_instance(h.path[h.level].object);
 	Object *obj = ObjectDB::get_instance(h.path[h.level].object);
 	if (!obj)
 	if (!obj)
 		return 0;
 		return 0;
@@ -558,7 +558,7 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
 
 
 	ERR_FAIL_INDEX(p_idx, edited_scene.size());
 	ERR_FAIL_INDEX(p_idx, edited_scene.size());
 	ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
 	ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
-	SWAP(edited_scene[p_idx], edited_scene[p_to_idx]);
+	SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]);
 }
 }
 void EditorData::remove_scene(int p_idx) {
 void EditorData::remove_scene(int p_idx) {
 	ERR_FAIL_INDEX(p_idx, edited_scene.size());
 	ERR_FAIL_INDEX(p_idx, edited_scene.size());
@@ -644,7 +644,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
 
 
 		//transfer selection
 		//transfer selection
 		List<Node *> new_selection;
 		List<Node *> new_selection;
-		for (List<Node *>::Element *E = edited_scene[p_idx].selection.front(); E; E = E->next()) {
+		for (List<Node *>::Element *E = edited_scene.write[p_idx].selection.front(); E; E = E->next()) {
 			NodePath p = edited_scene[p_idx].root->get_path_to(E->get());
 			NodePath p = edited_scene[p_idx].root->get_path_to(E->get());
 			Node *new_node = new_scene->get_node(p);
 			Node *new_node = new_scene->get_node(p);
 			if (new_node)
 			if (new_node)
@@ -654,8 +654,8 @@ bool EditorData::check_and_update_scene(int p_idx) {
 		new_scene->set_filename(edited_scene[p_idx].root->get_filename());
 		new_scene->set_filename(edited_scene[p_idx].root->get_filename());
 
 
 		memdelete(edited_scene[p_idx].root);
 		memdelete(edited_scene[p_idx].root);
-		edited_scene[p_idx].root = new_scene;
-		edited_scene[p_idx].selection = new_selection;
+		edited_scene.write[p_idx].root = new_scene;
+		edited_scene.write[p_idx].selection = new_selection;
 
 
 		return true;
 		return true;
 	}
 	}
@@ -685,7 +685,7 @@ Node *EditorData::get_edited_scene_root(int p_idx) {
 void EditorData::set_edited_scene_root(Node *p_root) {
 void EditorData::set_edited_scene_root(Node *p_root) {
 
 
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
-	edited_scene[current_edited_scene].root = p_root;
+	edited_scene.write[current_edited_scene].root = p_root;
 }
 }
 
 
 int EditorData::get_edited_scene_count() const {
 int EditorData::get_edited_scene_count() const {
@@ -707,10 +707,10 @@ Vector<EditorData::EditedScene> EditorData::get_edited_scenes() const {
 void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
 void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 	if (p_scene_idx < 0) {
 	if (p_scene_idx < 0) {
-		edited_scene[current_edited_scene].version = version;
+		edited_scene.write[current_edited_scene].version = version;
 	} else {
 	} else {
 		ERR_FAIL_INDEX(p_scene_idx, edited_scene.size());
 		ERR_FAIL_INDEX(p_scene_idx, edited_scene.size());
-		edited_scene[p_scene_idx].version = version;
+		edited_scene.write[p_scene_idx].version = version;
 	}
 	}
 }
 }
 
 
@@ -793,7 +793,7 @@ String EditorData::get_scene_path(int p_idx) const {
 void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
 void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 
 
-	edited_scene[current_edited_scene].live_edit_root = p_root;
+	edited_scene.write[current_edited_scene].live_edit_root = p_root;
 }
 }
 NodePath EditorData::get_edited_scene_live_edit_root() {
 NodePath EditorData::get_edited_scene_live_edit_root() {
 
 
@@ -806,7 +806,7 @@ void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHis
 
 
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 	ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
 
 
-	EditedScene &es = edited_scene[current_edited_scene];
+	EditedScene &es = edited_scene.write[current_edited_scene];
 	es.selection = p_selection->get_selected_node_list();
 	es.selection = p_selection->get_selected_node_list();
 	es.history_current = p_history->current;
 	es.history_current = p_history->current;
 	es.history_stored = p_history->history;
 	es.history_stored = p_history->history;
@@ -817,7 +817,7 @@ void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHis
 Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) {
 Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) {
 	ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary());
 	ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary());
 
 
-	EditedScene &es = edited_scene[current_edited_scene];
+	EditedScene &es = edited_scene.write[current_edited_scene];
 
 
 	p_history->current = es.history_current;
 	p_history->current = es.history_current;
 	p_history->history = es.history_stored;
 	p_history->history = es.history_stored;

+ 12 - 12
editor/editor_export.cpp

@@ -187,7 +187,7 @@ void EditorExportPreset::remove_patch(int p_idx) {
 
 
 void EditorExportPreset::set_patch(int p_index, const String &p_path) {
 void EditorExportPreset::set_patch(int p_index, const String &p_path) {
 	ERR_FAIL_INDEX(p_index, patches.size());
 	ERR_FAIL_INDEX(p_index, patches.size());
-	patches[p_index] = p_path;
+	patches.write[p_index] = p_path;
 	EditorExport::singleton->save_presets();
 	EditorExport::singleton->save_presets();
 }
 }
 String EditorExportPreset::get_patch(int p_index) {
 String EditorExportPreset::get_patch(int p_index) {
@@ -295,7 +295,7 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
 		MD5Final(&ctx);
 		MD5Final(&ctx);
 		sd.md5.resize(16);
 		sd.md5.resize(16);
 		for (int i = 0; i < 16; i++) {
 		for (int i = 0; i < 16; i++) {
-			sd.md5[i] = ctx.digest[i];
+			sd.md5.write[i] = ctx.digest[i];
 		}
 		}
 	}
 	}
 
 
@@ -584,9 +584,9 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla
 	//initial export plugin callback
 	//initial export plugin callback
 	for (int i = 0; i < export_plugins.size(); i++) {
 	for (int i = 0; i < export_plugins.size(); i++) {
 		if (export_plugins[i]->get_script_instance()) { //script based
 		if (export_plugins[i]->get_script_instance()) { //script based
-			export_plugins[i]->_export_begin_script(features.features_pv, p_debug, p_path, p_flags);
+			export_plugins.write[i]->_export_begin_script(features.features_pv, p_debug, p_path, p_flags);
 		} else {
 		} else {
-			export_plugins[i]->_export_begin(features.features, p_debug, p_path, p_flags);
+			export_plugins.write[i]->_export_begin(features.features, p_debug, p_path, p_flags);
 		}
 		}
 	}
 	}
 }
 }
@@ -594,7 +594,7 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla
 EditorExportPlatform::ExportNotifier::~ExportNotifier() {
 EditorExportPlatform::ExportNotifier::~ExportNotifier() {
 	Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
 	Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
 	for (int i = 0; i < export_plugins.size(); i++) {
 	for (int i = 0; i < export_plugins.size(); i++) {
-		export_plugins[i]->_export_end();
+		export_plugins.write[i]->_export_end();
 	}
 	}
 }
 }
 
 
@@ -632,7 +632,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 			p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
 			p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
 		}
 		}
 
 
-		export_plugins[i]->_clear();
+		export_plugins.write[i]->_clear();
 	}
 	}
 
 
 	FeatureContainers feature_containers = get_feature_containers(p_preset);
 	FeatureContainers feature_containers = get_feature_containers(p_preset);
@@ -687,9 +687,9 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 			bool do_export = true;
 			bool do_export = true;
 			for (int i = 0; i < export_plugins.size(); i++) {
 			for (int i = 0; i < export_plugins.size(); i++) {
 				if (export_plugins[i]->get_script_instance()) { //script based
 				if (export_plugins[i]->get_script_instance()) { //script based
-					export_plugins[i]->_export_file_script(path, type, features_pv);
+					export_plugins.write[i]->_export_file_script(path, type, features_pv);
 				} else {
 				} else {
-					export_plugins[i]->_export_file(path, type, features);
+					export_plugins.write[i]->_export_file(path, type, features);
 				}
 				}
 				if (p_so_func) {
 				if (p_so_func) {
 					for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
 					for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
@@ -709,7 +709,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 				if (export_plugins[i]->skipped) {
 				if (export_plugins[i]->skipped) {
 					do_export = false;
 					do_export = false;
 				}
 				}
-				export_plugins[i]->_clear();
+				export_plugins.write[i]->_clear();
 
 
 				if (!do_export)
 				if (!do_export)
 					break; //apologies, not exporting
 					break; //apologies, not exporting
@@ -751,7 +751,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 				Vector<uint8_t> new_file;
 				Vector<uint8_t> new_file;
 				new_file.resize(utf8.length());
 				new_file.resize(utf8.length());
 				for (int j = 0; j < utf8.length(); j++) {
 				for (int j = 0; j < utf8.length(); j++) {
-					new_file[j] = utf8[j];
+					new_file.write[j] = utf8[j];
 				}
 				}
 
 
 				p_func(p_udata, from + ".remap", new_file, idx, total);
 				p_func(p_udata, from + ".remap", new_file, idx, total);
@@ -1130,7 +1130,7 @@ void EditorExport::load_config() {
 
 
 		for (int i = 0; i < export_platforms.size(); i++) {
 		for (int i = 0; i < export_platforms.size(); i++) {
 			if (export_platforms[i]->get_name() == platform) {
 			if (export_platforms[i]->get_name() == platform) {
-				preset = export_platforms[i]->create_preset();
+				preset = export_platforms.write[i]->create_preset();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -1203,7 +1203,7 @@ bool EditorExport::poll_export_platforms() {
 
 
 	bool changed = false;
 	bool changed = false;
 	for (int i = 0; i < export_platforms.size(); i++) {
 	for (int i = 0; i < export_platforms.size(); i++) {
-		if (export_platforms[i]->poll_devices()) {
+		if (export_platforms.write[i]->poll_devices()) {
 			changed = true;
 			changed = true;
 		}
 		}
 	}
 	}

+ 2 - 2
editor/editor_file_dialog.cpp

@@ -1135,7 +1135,7 @@ void EditorFileDialog::_favorite_move_up() {
 
 
 		if (a_idx == -1 || b_idx == -1)
 		if (a_idx == -1 || b_idx == -1)
 			return;
 			return;
-		SWAP(favorited[a_idx], favorited[b_idx]);
+		SWAP(favorited.write[a_idx], favorited.write[b_idx]);
 
 
 		EditorSettings::get_singleton()->set_favorite_dirs(favorited);
 		EditorSettings::get_singleton()->set_favorite_dirs(favorited);
 
 
@@ -1155,7 +1155,7 @@ void EditorFileDialog::_favorite_move_down() {
 
 
 		if (a_idx == -1 || b_idx == -1)
 		if (a_idx == -1 || b_idx == -1)
 			return;
 			return;
-		SWAP(favorited[a_idx], favorited[b_idx]);
+		SWAP(favorited.write[a_idx], favorited.write[b_idx]);
 
 
 		EditorSettings::get_singleton()->set_favorite_dirs(favorited);
 		EditorSettings::get_singleton()->set_favorite_dirs(favorited);
 
 

+ 1 - 1
editor/editor_node.cpp

@@ -3947,7 +3947,7 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
 
 
 		if (bottom_panel_items[i].control == p_item) {
 		if (bottom_panel_items[i].control == p_item) {
 			bottom_panel_items[i].button->raise();
 			bottom_panel_items[i].button->raise();
-			SWAP(bottom_panel_items[i], bottom_panel_items[bottom_panel_items.size() - 1]);
+			SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]);
 			break;
 			break;
 		}
 		}
 	}
 	}

+ 13 - 13
editor/editor_profiler.cpp

@@ -37,9 +37,9 @@
 void EditorProfiler::_make_metric_ptrs(Metric &m) {
 void EditorProfiler::_make_metric_ptrs(Metric &m) {
 
 
 	for (int i = 0; i < m.categories.size(); i++) {
 	for (int i = 0; i < m.categories.size(); i++) {
-		m.category_ptrs[m.categories[i].signature] = &m.categories[i];
+		m.category_ptrs[m.categories[i].signature] = &m.categories.write[i];
 		for (int j = 0; j < m.categories[i].items.size(); j++) {
 		for (int j = 0; j < m.categories[i].items.size(); j++) {
-			m.item_ptrs[m.categories[i].items[j].signature] = &m.categories[i].items[j];
+			m.item_ptrs[m.categories[i].items[j].signature] = &m.categories.write[i].items.write[j];
 		}
 		}
 	}
 	}
 }
 }
@@ -50,8 +50,8 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
 	if (last_metric >= frame_metrics.size())
 	if (last_metric >= frame_metrics.size())
 		last_metric = 0;
 		last_metric = 0;
 
 
-	frame_metrics[last_metric] = p_metric;
-	_make_metric_ptrs(frame_metrics[last_metric]);
+	frame_metrics.write[last_metric] = p_metric;
+	_make_metric_ptrs(frame_metrics.write[last_metric]);
 
 
 	updating_frame = true;
 	updating_frame = true;
 	cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number);
 	cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number);
@@ -108,7 +108,7 @@ static String _get_percent_txt(float p_value, float p_total) {
 	return String::num((p_value / p_total) * 100, 1) + "%";
 	return String::num((p_value / p_total) * 100, 1) + "%";
 }
 }
 
 
-String EditorProfiler::_get_time_as_text(Metric &m, float p_time, int p_calls) {
+String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_calls) {
 
 
 	int dmode = display_mode->get_selected();
 	int dmode = display_mode->get_selected();
 
 
@@ -192,18 +192,18 @@ void EditorProfiler::_update_plot() {
 	float highest = 0;
 	float highest = 0;
 
 
 	for (int i = 0; i < frame_metrics.size(); i++) {
 	for (int i = 0; i < frame_metrics.size(); i++) {
-		Metric &m = frame_metrics[i];
+		const Metric &m = frame_metrics[i];
 		if (!m.valid)
 		if (!m.valid)
 			continue;
 			continue;
 
 
 		for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
 		for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
 
 
-			Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+			const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
 			if (F) {
 			if (F) {
 				highest = MAX(F->get()->total_time, highest);
 				highest = MAX(F->get()->total_time, highest);
 			}
 			}
 
 
-			Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+			const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
 			if (G) {
 			if (G) {
 				if (use_self) {
 				if (use_self) {
 					highest = MAX(G->get()->self, highest);
 					highest = MAX(G->get()->self, highest);
@@ -256,18 +256,18 @@ void EditorProfiler::_update_plot() {
 					}
 					}
 
 
 					//get
 					//get
-					Metric &m = frame_metrics[idx];
+					const Metric &m = frame_metrics[idx];
 					if (m.valid == false)
 					if (m.valid == false)
 						continue; //skip because invalid
 						continue; //skip because invalid
 
 
 					float value = 0;
 					float value = 0;
 
 
-					Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+					const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
 					if (F) {
 					if (F) {
 						value = F->get()->total_time;
 						value = F->get()->total_time;
 					}
 					}
 
 
-					Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+					const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
 					if (G) {
 					if (G) {
 						if (use_self) {
 						if (use_self) {
 							value = G->get()->self;
 							value = G->get()->self;
@@ -375,7 +375,7 @@ void EditorProfiler::_update_frame() {
 	variables->clear();
 	variables->clear();
 
 
 	TreeItem *root = variables->create_item();
 	TreeItem *root = variables->create_item();
-	Metric &m = frame_metrics[cursor_metric];
+	const Metric &m = frame_metrics[cursor_metric];
 
 
 	int dtime = display_time->get_selected();
 	int dtime = display_time->get_selected();
 
 
@@ -394,7 +394,7 @@ void EditorProfiler::_update_frame() {
 		}
 		}
 
 
 		for (int j = 0; j < m.categories[i].items.size(); j++) {
 		for (int j = 0; j < m.categories[i].items.size(); j++) {
-			Metric::Category::Item &it = m.categories[i].items[j];
+			const Metric::Category::Item &it = m.categories[i].items[j];
 
 
 			TreeItem *item = variables->create_item(category);
 			TreeItem *item = variables->create_item(category);
 			item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
 			item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);

+ 1 - 1
editor/editor_profiler.h

@@ -136,7 +136,7 @@ private:
 	void _activate_pressed();
 	void _activate_pressed();
 	void _clear_pressed();
 	void _clear_pressed();
 
 
-	String _get_time_as_text(Metric &m, float p_time, int p_calls);
+	String _get_time_as_text(const Metric &m, float p_time, int p_calls);
 
 
 	void _make_metric_ptrs(Metric &m);
 	void _make_metric_ptrs(Metric &m);
 	void _item_edited();
 	void _item_edited();

+ 2 - 2
editor/editor_resource_preview.cpp

@@ -46,7 +46,7 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
 	ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden");
 	ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden");
 	ERR_FAIL_V(false);
 	ERR_FAIL_V(false);
 }
 }
-Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) {
+Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) const {
 
 
 	if (get_script_instance() && get_script_instance()->has_method("generate")) {
 	if (get_script_instance() && get_script_instance()->has_method("generate")) {
 		return get_script_instance()->call("generate", p_from);
 		return get_script_instance()->call("generate", p_from);
@@ -55,7 +55,7 @@ Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) {
 	ERR_FAIL_V(Ref<Texture>());
 	ERR_FAIL_V(Ref<Texture>());
 }
 }
 
 
-Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) {
+Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) const {
 
 
 	if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) {
 	if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) {
 		return get_script_instance()->call("generate_from_path", p_path);
 		return get_script_instance()->call("generate_from_path", p_path);

+ 2 - 2
editor/editor_resource_preview.h

@@ -63,8 +63,8 @@ protected:
 
 
 public:
 public:
 	virtual bool handles(const String &p_type) const;
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from);
-	virtual Ref<Texture> generate_from_path(const String &p_path);
+	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual Ref<Texture> generate_from_path(const String &p_path) const;
 
 
 	EditorResourcePreviewGenerator();
 	EditorResourcePreviewGenerator();
 };
 };

+ 1 - 1
editor/editor_settings.cpp

@@ -881,7 +881,7 @@ fail:
 		Vector<String> list = extra_config->get_value("init_projects", "list");
 		Vector<String> list = extra_config->get_value("init_projects", "list");
 		for (int i = 0; i < list.size(); i++) {
 		for (int i = 0; i < list.size(); i++) {
 
 
-			list[i] = exe_path + "/" + list[i];
+			list.write[i] = exe_path + "/" + list[i];
 		};
 		};
 		extra_config->set_value("init_projects", "list", list);
 		extra_config->set_value("init_projects", "list", list);
 	};
 	};

+ 2 - 2
editor/fileserver/editor_file_server.cpp

@@ -78,7 +78,7 @@ void EditorFileServer::_subthread_start(void *s) {
 			_close_client(cd);
 			_close_client(cd);
 			ERR_FAIL_COND(err != OK);
 			ERR_FAIL_COND(err != OK);
 		}
 		}
-		passutf8[passlen] = 0;
+		passutf8.write[passlen] = 0;
 		String s;
 		String s;
 		s.parse_utf8(passutf8.ptr());
 		s.parse_utf8(passutf8.ptr());
 		if (s != cd->efs->password) {
 		if (s != cd->efs->password) {
@@ -145,7 +145,7 @@ void EditorFileServer::_subthread_start(void *s) {
 					_close_client(cd);
 					_close_client(cd);
 					ERR_FAIL_COND(err != OK);
 					ERR_FAIL_COND(err != OK);
 				}
 				}
-				fileutf8[namelen] = 0;
+				fileutf8.write[namelen] = 0;
 				String s;
 				String s;
 				s.parse_utf8(fileutf8.ptr());
 				s.parse_utf8(fileutf8.ptr());
 
 

+ 1 - 1
editor/find_in_files.cpp

@@ -143,7 +143,7 @@ void FindInFiles::_iterate() {
 
 
 		// Scan folders first so we can build a list of files and have progress info later
 		// Scan folders first so we can build a list of files and have progress info later
 
 
-		PoolStringArray &folders_to_scan = _folders_stack[_folders_stack.size() - 1];
+		PoolStringArray &folders_to_scan = _folders_stack.write[_folders_stack.size() - 1];
 
 
 		if (folders_to_scan.size() != 0) {
 		if (folders_to_scan.size() != 0) {
 			// Scan one folder below
 			// Scan one folder below

+ 25 - 25
editor/import/editor_import_collada.cpp

@@ -579,12 +579,12 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
 							   .normalized();
 							   .normalized();
 		}
 		}
 
 
-		tangents[index_arrayr[idx * 3 + 0]] += tangent;
-		binormals[index_arrayr[idx * 3 + 0]] += binormal;
-		tangents[index_arrayr[idx * 3 + 1]] += tangent;
-		binormals[index_arrayr[idx * 3 + 1]] += binormal;
-		tangents[index_arrayr[idx * 3 + 2]] += tangent;
-		binormals[index_arrayr[idx * 3 + 2]] += binormal;
+		tangents.write[index_arrayr[idx * 3 + 0]] += tangent;
+		binormals.write[index_arrayr[idx * 3 + 0]] += binormal;
+		tangents.write[index_arrayr[idx * 3 + 1]] += tangent;
+		binormals.write[index_arrayr[idx * 3 + 1]] += binormal;
+		tangents.write[index_arrayr[idx * 3 + 2]] += tangent;
+		binormals.write[index_arrayr[idx * 3 + 2]] += binormal;
 
 
 		//print_line(itos(idx)+" tangent: "+tangent);
 		//print_line(itos(idx)+" tangent: "+tangent);
 		//print_line(itos(idx)+" binormal: "+binormal);
 		//print_line(itos(idx)+" binormal: "+binormal);
@@ -800,7 +800,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
 					total += weights[i].weight;
 					total += weights[i].weight;
 				if (total)
 				if (total)
 					for (int i = 0; i < weights.size(); i++)
 					for (int i = 0; i < weights.size(); i++)
-						weights[i].weight /= total;
+						weights.write[i].weight /= total;
 
 
 				if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0
 				if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0
 					//no weights assigned
 					//no weights assigned
@@ -987,7 +987,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
 		vertex_array.resize(vertex_set.size());
 		vertex_array.resize(vertex_set.size());
 		for (Set<Collada::Vertex>::Element *F = vertex_set.front(); F; F = F->next()) {
 		for (Set<Collada::Vertex>::Element *F = vertex_set.front(); F; F = F->next()) {
 
 
-			vertex_array[F->get().idx] = F->get();
+			vertex_array.write[F->get().idx] = F->get();
 		}
 		}
 
 
 		if (has_weights) {
 		if (has_weights) {
@@ -996,9 +996,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
 			Transform local_xform = p_local_xform;
 			Transform local_xform = p_local_xform;
 			for (int i = 0; i < vertex_array.size(); i++) {
 			for (int i = 0; i < vertex_array.size(); i++) {
 
 
-				vertex_array[i].vertex = local_xform.xform(vertex_array[i].vertex);
-				vertex_array[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
-				vertex_array[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
+				vertex_array.write[i].vertex = local_xform.xform(vertex_array[i].vertex);
+				vertex_array.write[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
+				vertex_array.write[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
 				if (local_xform_mirror) {
 				if (local_xform_mirror) {
 					//i shouldn't do this? wtf?
 					//i shouldn't do this? wtf?
 					//vertex_array[i].normal*=-1.0;
 					//vertex_array[i].normal*=-1.0;
@@ -1061,13 +1061,13 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
 					//float sum=0.0;
 					//float sum=0.0;
 					for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
 					for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
 						if (l < vertex_array[k].weights.size()) {
 						if (l < vertex_array[k].weights.size()) {
-							weights[l] = vertex_array[k].weights[l].weight;
-							bones[l] = vertex_array[k].weights[l].bone_idx;
+							weights.write[l] = vertex_array[k].weights[l].weight;
+							bones.write[l] = vertex_array[k].weights[l].bone_idx;
 							//sum += vertex_array[k].weights[l].weight;
 							//sum += vertex_array[k].weights[l].weight;
 						} else {
 						} else {
 
 
-							weights[l] = 0;
-							bones[l] = 0;
+							weights.write[l] = 0;
+							bones.write[l] = 0;
 						}
 						}
 					}
 					}
 
 
@@ -1286,7 +1286,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
 
 
 						String str = joint_src->sarray[i];
 						String str = joint_src->sarray[i];
 						ERR_FAIL_COND_V(!bone_remap_map.has(str), ERR_INVALID_DATA);
 						ERR_FAIL_COND_V(!bone_remap_map.has(str), ERR_INVALID_DATA);
-						bone_remap[i] = bone_remap_map[str];
+						bone_remap.write[i] = bone_remap_map[str];
 					}
 					}
 				}
 				}
 
 
@@ -1506,7 +1506,7 @@ void ColladaImport::_fix_param_animation_tracks() {
 										const Vector<int> &rt = collada.state.referenced_tracks[track_name];
 										const Vector<int> &rt = collada.state.referenced_tracks[track_name];
 
 
 										for (int rti = 0; rti < rt.size(); rti++) {
 										for (int rti = 0; rti < rt.size(); rti++) {
-											Collada::AnimationTrack *at = &collada.state.animation_tracks[rt[rti]];
+											Collada::AnimationTrack *at = &collada.state.animation_tracks.write[rt[rti]];
 
 
 											at->target = E->key();
 											at->target = E->key();
 											at->param = "morph/" + collada.state.mesh_name_map[mesh_name];
 											at->param = "morph/" + collada.state.mesh_name_map[mesh_name];
@@ -1540,7 +1540,7 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_im
 
 
 	for (int i = 0; i < collada.state.animation_tracks.size(); i++) {
 	for (int i = 0; i < collada.state.animation_tracks.size(); i++) {
 
 
-		Collada::AnimationTrack &at = collada.state.animation_tracks[i];
+		const Collada::AnimationTrack &at = collada.state.animation_tracks[i];
 		//print_line("CHANNEL: "+at.target+" PARAM: "+at.param);
 		//print_line("CHANNEL: "+at.target+" PARAM: "+at.param);
 
 
 		String node;
 		String node;
@@ -1698,7 +1698,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
 
 
 		if (nm.anim_tracks.size() == 1) {
 		if (nm.anim_tracks.size() == 1) {
 			//use snapshot keys from anim track instead, because this was most likely exported baked
 			//use snapshot keys from anim track instead, because this was most likely exported baked
-			Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
+			const Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
 			snapshots.clear();
 			snapshots.clear();
 			for (int i = 0; i < at.keys.size(); i++)
 			for (int i = 0; i < at.keys.size(); i++)
 				snapshots.push_back(at.keys[i].time);
 				snapshots.push_back(at.keys[i].time);
@@ -1723,7 +1723,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
 
 
 				found_anim = true;
 				found_anim = true;
 
 
-				Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
+				const Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
 
 
 				int xform_idx = -1;
 				int xform_idx = -1;
 				for (int j = 0; j < cn->xform_list.size(); j++) {
 				for (int j = 0; j < cn->xform_list.size(); j++) {
@@ -1745,18 +1745,18 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
 				Vector<float> data = at.get_value_at_time(snapshots[i]);
 				Vector<float> data = at.get_value_at_time(snapshots[i]);
 				ERR_CONTINUE(data.empty());
 				ERR_CONTINUE(data.empty());
 
 
-				Collada::Node::XForm &xf = cn->xform_list[xform_idx];
+				Collada::Node::XForm &xf = cn->xform_list.write[xform_idx];
 
 
 				if (at.component == "ANGLE") {
 				if (at.component == "ANGLE") {
 					ERR_CONTINUE(data.size() != 1);
 					ERR_CONTINUE(data.size() != 1);
 					ERR_CONTINUE(xf.op != Collada::Node::XForm::OP_ROTATE);
 					ERR_CONTINUE(xf.op != Collada::Node::XForm::OP_ROTATE);
 					ERR_CONTINUE(xf.data.size() < 4);
 					ERR_CONTINUE(xf.data.size() < 4);
-					xf.data[3] = data[0];
+					xf.data.write[3] = data[0];
 				} else if (at.component == "X" || at.component == "Y" || at.component == "Z") {
 				} else if (at.component == "X" || at.component == "Y" || at.component == "Z") {
 					int cn = at.component[0] - 'X';
 					int cn = at.component[0] - 'X';
 					ERR_CONTINUE(cn >= xf.data.size());
 					ERR_CONTINUE(cn >= xf.data.size());
 					ERR_CONTINUE(data.size() > 1);
 					ERR_CONTINUE(data.size() > 1);
-					xf.data[cn] = data[0];
+					xf.data.write[cn] = data[0];
 				} else if (data.size() == xf.data.size()) {
 				} else if (data.size() == xf.data.size()) {
 
 
 					xf.data = data;
 					xf.data = data;
@@ -1862,7 +1862,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
 					continue;
 					continue;
 			}
 			}
 
 
-			Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
+			const Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
 
 
 			// take snapshots
 			// take snapshots
 			if (!collada.state.scene_map.has(at.target))
 			if (!collada.state.scene_map.has(at.target))
@@ -1965,7 +1965,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
 			if (p_flags & IMPORT_ANIMATION_DETECT_LOOP) {
 			if (p_flags & IMPORT_ANIMATION_DETECT_LOOP) {
 
 
 				if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
 				if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
-					state.animations[i]->set_loop(true);
+					state.animations.write[i]->set_loop(true);
 				}
 				}
 			}
 			}
 
 

+ 18 - 18
editor/import/editor_scene_importer_gltf.cpp

@@ -651,7 +651,7 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
 	} else {
 	} else {
 		//fill with zeros, as bufferview is not defined.
 		//fill with zeros, as bufferview is not defined.
 		for (int i = 0; i < (a.count * component_count); i++) {
 		for (int i = 0; i < (a.count * component_count); i++) {
-			dst_buffer[i] = 0;
+			dst_buffer.write[i] = 0;
 		}
 		}
 	}
 	}
 
 
@@ -794,7 +794,7 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state,
 	ret.resize(ret_size);
 	ret.resize(ret_size);
 	{
 	{
 		for (int i = 0; i < ret_size; i++) {
 		for (int i = 0; i < ret_size; i++) {
-			ret[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
+			ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
 		}
 		}
 	}
 	}
 	return ret;
 	return ret;
@@ -808,8 +808,8 @@ Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFSta
 	ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
 	ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
 	ret.resize(attribs.size() / 4);
 	ret.resize(attribs.size() / 4);
 	for (int i = 0; i < ret.size(); i++) {
 	for (int i = 0; i < ret.size(); i++) {
-		ret[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
-		ret[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
+		ret.write[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
+		ret.write[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
 	}
 	}
 	return ret;
 	return ret;
 }
 }
@@ -823,9 +823,9 @@ Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &stat
 	ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
 	ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
 	ret.resize(attribs.size() / 9);
 	ret.resize(attribs.size() / 9);
 	for (int i = 0; i < ret.size(); i++) {
 	for (int i = 0; i < ret.size(); i++) {
-		ret[i].set_axis(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
-		ret[i].set_axis(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
-		ret[i].set_axis(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
+		ret.write[i].set_axis(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
+		ret.write[i].set_axis(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
+		ret.write[i].set_axis(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
 	}
 	}
 	return ret;
 	return ret;
 }
 }
@@ -838,10 +838,10 @@ Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &
 	ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
 	ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
 	ret.resize(attribs.size() / 16);
 	ret.resize(attribs.size() / 16);
 	for (int i = 0; i < ret.size(); i++) {
 	for (int i = 0; i < ret.size(); i++) {
-		ret[i].basis.set_axis(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
-		ret[i].basis.set_axis(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
-		ret[i].basis.set_axis(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
-		ret[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
+		ret.write[i].basis.set_axis(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
+		ret.write[i].basis.set_axis(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
+		ret.write[i].basis.set_axis(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
+		ret.write[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
 	}
 	}
 	return ret;
 	return ret;
 }
 }
@@ -1085,7 +1085,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
 			ERR_FAIL_COND_V(mesh.mesh->get_blend_shape_count() != weights.size(), ERR_PARSE_ERROR);
 			ERR_FAIL_COND_V(mesh.mesh->get_blend_shape_count() != weights.size(), ERR_PARSE_ERROR);
 			mesh.blend_weights.resize(weights.size());
 			mesh.blend_weights.resize(weights.size());
 			for (int j = 0; j < weights.size(); j++) {
 			for (int j = 0; j < weights.size(); j++) {
-				mesh.blend_weights[j] = weights[j];
+				mesh.blend_weights.write[j] = weights[j];
 			}
 			}
 		}
 		}
 
 
@@ -1139,7 +1139,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
 
 
 			ERR_FAIL_INDEX_V(bvi, state.buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
 			ERR_FAIL_INDEX_V(bvi, state.buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
 
 
-			GLTFBufferView &bv = state.buffer_views[bvi];
+			const GLTFBufferView &bv = state.buffer_views[bvi];
 
 
 			int bi = bv.buffer;
 			int bi = bv.buffer;
 			ERR_FAIL_INDEX_V(bi, state.buffers.size(), ERR_PARAMETER_RANGE_ERROR);
 			ERR_FAIL_INDEX_V(bi, state.buffers.size(), ERR_PARAMETER_RANGE_ERROR);
@@ -1596,7 +1596,7 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
 				PoolVector<float> weights = _decode_accessor_as_floats(state, output, false);
 				PoolVector<float> weights = _decode_accessor_as_floats(state, output, false);
 
 
 				ERR_FAIL_INDEX_V(state.nodes[node]->mesh, state.meshes.size(), ERR_PARSE_ERROR);
 				ERR_FAIL_INDEX_V(state.nodes[node]->mesh, state.meshes.size(), ERR_PARSE_ERROR);
-				GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
+				const GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
 				ERR_FAIL_COND_V(mesh->blend_weights.size() == 0, ERR_PARSE_ERROR);
 				ERR_FAIL_COND_V(mesh->blend_weights.size() == 0, ERR_PARSE_ERROR);
 				int wc = mesh->blend_weights.size();
 				int wc = mesh->blend_weights.size();
 
 
@@ -1611,11 +1611,11 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
 					Vector<float> wdata;
 					Vector<float> wdata;
 					wdata.resize(wlen);
 					wdata.resize(wlen);
 					for (int l = 0; l < wlen; l++) {
 					for (int l = 0; l < wlen; l++) {
-						wdata[l] = r[l * wc + k];
+						wdata.write[l] = r[l * wc + k];
 					}
 					}
 
 
 					cf.values = wdata;
 					cf.values = wdata;
-					track->weight_tracks[k] = cf;
+					track->weight_tracks.write[k] = cf;
 				}
 				}
 			} else {
 			} else {
 				WARN_PRINTS("Invalid path: " + path);
 				WARN_PRINTS("Invalid path: " + path);
@@ -1657,7 +1657,7 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
 	if (n->mesh >= 0) {
 	if (n->mesh >= 0) {
 		ERR_FAIL_INDEX(n->mesh, state.meshes.size());
 		ERR_FAIL_INDEX(n->mesh, state.meshes.size());
 		MeshInstance *mi = memnew(MeshInstance);
 		MeshInstance *mi = memnew(MeshInstance);
-		GLTFMesh &mesh = state.meshes[n->mesh];
+		GLTFMesh &mesh = state.meshes.write[n->mesh];
 		mi->set_mesh(mesh.mesh);
 		mi->set_mesh(mesh.mesh);
 		if (mesh.mesh->get_name() == "") {
 		if (mesh.mesh->get_name() == "") {
 			mesh.mesh->set_name(n->name);
 			mesh.mesh->set_name(n->name);
@@ -1750,7 +1750,7 @@ void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vecto
 		s->set_bone_rest(bone_index, state.skins[skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
 		s->set_bone_rest(bone_index, state.skins[skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
 
 
 		n->godot_nodes.push_back(s);
 		n->godot_nodes.push_back(s);
-		n->joints[i].godot_bone_index = bone_index;
+		n->joints.write[i].godot_bone_index = bone_index;
 	}
 	}
 
 
 	for (int i = 0; i < n->children.size(); i++) {
 	for (int i = 0; i < n->children.size(); i++) {

+ 1 - 1
editor/import/resource_importer_csv_translation.cpp

@@ -119,7 +119,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
 		if (key != "") {
 		if (key != "") {
 
 
 			for (int i = 1; i < line.size(); i++) {
 			for (int i = 1; i < line.size(); i++) {
-				translations[i - 1]->add_message(key, line[i]);
+				translations.write[i - 1]->add_message(key, line[i]);
 			}
 			}
 		}
 		}
 
 

+ 1 - 1
editor/import/resource_importer_scene.cpp

@@ -750,7 +750,7 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
 	Vector<String> strings = p_text.split("\n");
 	Vector<String> strings = p_text.split("\n");
 	for (int i = 0; i < strings.size(); i++) {
 	for (int i = 0; i < strings.size(); i++) {
 
 
-		strings[i] = strings[i].strip_edges();
+		strings.write[i] = strings[i].strip_edges();
 	}
 	}
 
 
 	List<StringName> anim_names;
 	List<StringName> anim_names;

+ 10 - 10
editor/import/resource_importer_wav.cpp

@@ -215,19 +215,19 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 				for (int i = 0; i < frames * format_channels; i++) {
 				for (int i = 0; i < frames * format_channels; i++) {
 					// 8 bit samples are UNSIGNED
 					// 8 bit samples are UNSIGNED
 
 
-					data[i] = int8_t(file->get_8() - 128) / 128.f;
+					data.write[i] = int8_t(file->get_8() - 128) / 128.f;
 				}
 				}
 			} else if (format_bits == 32 && compression_code == 3) {
 			} else if (format_bits == 32 && compression_code == 3) {
 				for (int i = 0; i < frames * format_channels; i++) {
 				for (int i = 0; i < frames * format_channels; i++) {
 					//32 bit IEEE Float
 					//32 bit IEEE Float
 
 
-					data[i] = file->get_float();
+					data.write[i] = file->get_float();
 				}
 				}
 			} else if (format_bits == 16) {
 			} else if (format_bits == 16) {
 				for (int i = 0; i < frames * format_channels; i++) {
 				for (int i = 0; i < frames * format_channels; i++) {
 					//16 bit SIGNED
 					//16 bit SIGNED
 
 
-					data[i] = int16_t(file->get_16()) / 32768.f;
+					data.write[i] = int16_t(file->get_16()) / 32768.f;
 				}
 				}
 			} else {
 			} else {
 				for (int i = 0; i < frames * format_channels; i++) {
 				for (int i = 0; i < frames * format_channels; i++) {
@@ -241,7 +241,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 					}
 					}
 					s <<= (32 - format_bits);
 					s <<= (32 - format_bits);
 
 
-					data[i] = (int32_t(s) >> 16) / 32768.f;
+					data.write[i] = (int32_t(s) >> 16) / 32768.f;
 				}
 				}
 			}
 			}
 
 
@@ -335,7 +335,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 
 
 				float res = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);
 				float res = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);
 
 
-				new_data[i * format_channels + c] = res;
+				new_data.write[i * format_channels + c] = res;
 
 
 				// update position and always keep fractional part within ]0...1]
 				// update position and always keep fractional part within ]0...1]
 				// in order to avoid 32bit floating point precision errors
 				// in order to avoid 32bit floating point precision errors
@@ -374,7 +374,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 			float mult = 1.0 / max;
 			float mult = 1.0 / max;
 			for (int i = 0; i < data.size(); i++) {
 			for (int i = 0; i < data.size(); i++) {
 
 
-				data[i] *= mult;
+				data.write[i] *= mult;
 			}
 			}
 		}
 		}
 	}
 	}
@@ -408,7 +408,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 			Vector<float> new_data;
 			Vector<float> new_data;
 			new_data.resize((last - first + 1) * format_channels);
 			new_data.resize((last - first + 1) * format_channels);
 			for (int i = first * format_channels; i < (last + 1) * format_channels; i++) {
 			for (int i = first * format_channels; i < (last + 1) * format_channels; i++) {
-				new_data[i - first * format_channels] = data[i];
+				new_data.write[i - first * format_channels] = data[i];
 			}
 			}
 
 
 			data = new_data;
 			data = new_data;
@@ -433,7 +433,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 		Vector<float> new_data;
 		Vector<float> new_data;
 		new_data.resize(data.size() / 2);
 		new_data.resize(data.size() / 2);
 		for (int i = 0; i < frames; i++) {
 		for (int i = 0; i < frames; i++) {
-			new_data[i] = (data[i * 2 + 0] + data[i * 2 + 1]) / 2.0;
+			new_data.write[i] = (data[i * 2 + 0] + data[i * 2 + 1]) / 2.0;
 		}
 		}
 
 
 		data = new_data;
 		data = new_data;
@@ -465,8 +465,8 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 			right.resize(tframes);
 			right.resize(tframes);
 
 
 			for (int i = 0; i < tframes; i++) {
 			for (int i = 0; i < tframes; i++) {
-				left[i] = data[i * 2 + 0];
-				right[i] = data[i * 2 + 1];
+				left.write[i] = data[i * 2 + 0];
+				right.write[i] = data[i * 2 + 1];
 			}
 			}
 
 
 			PoolVector<uint8_t> bleft;
 			PoolVector<uint8_t> bleft;

+ 2 - 2
editor/plugins/abstract_polygon_2d_editor.cpp

@@ -345,7 +345,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
 
 
 						Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
 						Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
 						ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
 						ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
-						vertices[edited_point.vertex] = edited_point.pos - _get_offset(edited_point.polygon);
+						vertices.write[edited_point.vertex] = edited_point.pos - _get_offset(edited_point.polygon);
 
 
 						undo_redo->create_action(TTR("Edit Poly"));
 						undo_redo->create_action(TTR("Edit Poly"));
 						_action_set_polygon(edited_point.polygon, pre_move_edit, vertices);
 						_action_set_polygon(edited_point.polygon, pre_move_edit, vertices);
@@ -445,7 +445,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
 
 
 				Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
 				Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
 				ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
 				ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
-				vertices[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
+				vertices.write[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
 				_set_polygon(edited_point.polygon, vertices);
 				_set_polygon(edited_point.polygon, vertices);
 			}
 			}
 
 

+ 1 - 1
editor/plugins/animation_blend_space_2d_editor.cpp

@@ -414,7 +414,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
 			point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
 			point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
 			point *= s;
 			point *= s;
 			point.y = s.height - point.y;
 			point.y = s.height - point.y;
-			points[j] = point;
+			points.write[j] = point;
 		}
 		}
 
 
 		for (int j = 0; j < 3; j++) {
 		for (int j = 0; j < 3; j++) {

+ 2 - 2
editor/plugins/animation_player_editor_plugin.cpp

@@ -1333,7 +1333,7 @@ void AnimationPlayerEditor::_allocate_onion_layers() {
 		bool is_present = onion.differences_only && i == captures - 1;
 		bool is_present = onion.differences_only && i == captures - 1;
 
 
 		// Each capture is a viewport with a canvas item attached that renders a full-size rect with the contents of the main viewport
 		// Each capture is a viewport with a canvas item attached that renders a full-size rect with the contents of the main viewport
-		onion.captures[i] = VS::get_singleton()->viewport_create();
+		onion.captures.write[i] = VS::get_singleton()->viewport_create();
 		VS::get_singleton()->viewport_set_usage(onion.captures[i], VS::VIEWPORT_USAGE_2D);
 		VS::get_singleton()->viewport_set_usage(onion.captures[i], VS::VIEWPORT_USAGE_2D);
 		VS::get_singleton()->viewport_set_size(onion.captures[i], capture_size.width, capture_size.height);
 		VS::get_singleton()->viewport_set_size(onion.captures[i], capture_size.width, capture_size.height);
 		VS::get_singleton()->viewport_set_update_mode(onion.captures[i], VS::VIEWPORT_UPDATE_ALWAYS);
 		VS::get_singleton()->viewport_set_update_mode(onion.captures[i], VS::VIEWPORT_UPDATE_ALWAYS);
@@ -1473,7 +1473,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
 		float pos = cpos + step_off * anim->get_step();
 		float pos = cpos + step_off * anim->get_step();
 
 
 		bool valid = anim->has_loop() || (pos >= 0 && pos <= anim->get_length());
 		bool valid = anim->has_loop() || (pos >= 0 && pos <= anim->get_length());
-		onion.captures_valid[cidx] = valid;
+		onion.captures_valid.write[cidx] = valid;
 		if (valid) {
 		if (valid) {
 			player->seek(pos, true);
 			player->seek(pos, true);
 			get_tree()->flush_transform_notifications(); // Needed for transforms of Spatials
 			get_tree()->flush_transform_notifications(); // Needed for transforms of Spatials

+ 2 - 2
editor/plugins/animation_state_machine_editor.cpp

@@ -679,7 +679,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
 		Ref<StyleBox> sb = name == selected_node ? style_selected : style;
 		Ref<StyleBox> sb = name == selected_node ? style_selected : style;
 		int strsize = font->get_string_size(name).width;
 		int strsize = font->get_string_size(name).width;
 
 
-		NodeRect &nr = node_rects[i];
+		NodeRect &nr = node_rects.write[i];
 
 
 		Vector2 offset = nr.node.position;
 		Vector2 offset = nr.node.position;
 		int h = nr.node.size.height;
 		int h = nr.node.size.height;
@@ -771,7 +771,7 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
 	if (idx == -1)
 	if (idx == -1)
 		return;
 		return;
 
 
-	NodeRect &nr = node_rects[idx];
+	const NodeRect &nr = node_rects[idx];
 
 
 	Vector2 from;
 	Vector2 from;
 	from.x = nr.play.position.x;
 	from.x = nr.play.position.x;

+ 1 - 1
editor/plugins/asset_library_editor_plugin.cpp

@@ -197,7 +197,7 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
 
 
 			for (int i = 0; i < preview_images.size(); i++) {
 			for (int i = 0; i < preview_images.size(); i++) {
 				if (preview_images[i].id == p_index) {
 				if (preview_images[i].id == p_index) {
-					preview_images[i].image = p_image;
+					preview_images.write[i].image = p_image;
 					if (preview_images[i].button->is_pressed()) {
 					if (preview_images[i].button->is_pressed()) {
 						_preview_click(p_index);
 						_preview_click(p_index);
 					}
 					}

+ 2 - 2
editor/plugins/audio_stream_editor_plugin.cpp

@@ -81,8 +81,8 @@ void AudioStreamEditor::_draw_preview() {
 		float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
 		float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
 
 
 		int idx = i;
 		int idx = i;
-		lines[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
-		lines[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
+		lines.write[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
+		lines.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
 	}
 	}
 
 
 	Vector<Color> color;
 	Vector<Color> color;

+ 1 - 1
editor/plugins/canvas_item_editor_plugin.cpp

@@ -533,7 +533,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
 			r_items.remove(i);
 			r_items.remove(i);
 			i--;
 			i--;
 		} else {
 		} else {
-			r_items[i].item = canvas_item;
+			r_items.write[i].item = canvas_item;
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
editor/plugins/collision_polygon_editor_plugin.cpp

@@ -276,7 +276,7 @@ bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<Inpu
 							//apply
 							//apply
 
 
 							ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
 							ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
-							poly[edited_point] = edited_point_pos;
+							poly.write[edited_point] = edited_point_pos;
 							undo_redo->create_action(TTR("Edit Poly"));
 							undo_redo->create_action(TTR("Edit Poly"));
 							undo_redo->add_do_method(node, "set_polygon", poly);
 							undo_redo->add_do_method(node, "set_polygon", poly);
 							undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
 							undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);

+ 10 - 10
editor/plugins/collision_shape_2d_editor_plugin.cpp

@@ -446,8 +446,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
 			float radius = shape->get_radius();
 			float radius = shape->get_radius();
 			float height = shape->get_height() / 2;
 			float height = shape->get_height() / 2;
 
 
-			handles[0] = Point2(radius, -height);
-			handles[1] = Point2(0, -(height + radius));
+			handles.write[0] = Point2(radius, -height);
+			handles.write[1] = Point2(0, -(height + radius));
 
 
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -458,7 +458,7 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
 			Ref<CircleShape2D> shape = node->get_shape();
 			Ref<CircleShape2D> shape = node->get_shape();
 
 
 			handles.resize(1);
 			handles.resize(1);
-			handles[0] = Point2(shape->get_radius(), 0);
+			handles.write[0] = Point2(shape->get_radius(), 0);
 
 
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 
 
@@ -476,8 +476,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
 			Ref<LineShape2D> shape = node->get_shape();
 			Ref<LineShape2D> shape = node->get_shape();
 
 
 			handles.resize(2);
 			handles.resize(2);
-			handles[0] = shape->get_normal() * shape->get_d();
-			handles[1] = shape->get_normal() * (shape->get_d() + 30.0);
+			handles.write[0] = shape->get_normal() * shape->get_d();
+			handles.write[1] = shape->get_normal() * (shape->get_d() + 30.0);
 
 
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -488,7 +488,7 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
 			Ref<RayShape2D> shape = node->get_shape();
 			Ref<RayShape2D> shape = node->get_shape();
 
 
 			handles.resize(1);
 			handles.resize(1);
-			handles[0] = Point2(0, shape->get_length());
+			handles.write[0] = Point2(0, shape->get_length());
 
 
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 
 
@@ -499,8 +499,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
 
 
 			handles.resize(2);
 			handles.resize(2);
 			Vector2 ext = shape->get_extents();
 			Vector2 ext = shape->get_extents();
-			handles[0] = Point2(ext.x, 0);
-			handles[1] = Point2(0, -ext.y);
+			handles.write[0] = Point2(ext.x, 0);
+			handles.write[1] = Point2(0, -ext.y);
 
 
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -511,8 +511,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
 			Ref<SegmentShape2D> shape = node->get_shape();
 			Ref<SegmentShape2D> shape = node->get_shape();
 
 
 			handles.resize(2);
 			handles.resize(2);
-			handles[0] = shape->get_a();
-			handles[1] = shape->get_b();
+			handles.write[0] = shape->get_a();
+			handles.write[1] = shape->get_b();
 
 
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
 			p_overlay->draw_texture(h, gt.xform(handles[1]) - size);

+ 1 - 1
editor/plugins/light_occluder_2d_editor_plugin.cpp

@@ -255,7 +255,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 							//apply
 							//apply
 
 
 							ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
 							ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
-							poly[edited_point] = edited_point_pos;
+							poly.write[edited_point] = edited_point_pos;
 							undo_redo->create_action(TTR("Edit Poly"));
 							undo_redo->create_action(TTR("Edit Poly"));
 							undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
 							undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
 							undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);
 							undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);

+ 11 - 11
editor/plugins/particles_2d_editor_plugin.cpp

@@ -165,12 +165,12 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
 					if (emode == EMISSION_MODE_SOLID) {
 					if (emode == EMISSION_MODE_SOLID) {
 
 
 						if (capture_colors) {
 						if (capture_colors) {
-							valid_colors[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
-							valid_colors[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
-							valid_colors[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
-							valid_colors[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
+							valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
+							valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
+							valid_colors.write[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
+							valid_colors.write[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
 						}
 						}
-						valid_positions[vpc++] = Point2(i, j);
+						valid_positions.write[vpc++] = Point2(i, j);
 
 
 					} else {
 					} else {
 
 
@@ -189,7 +189,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
 						}
 						}
 
 
 						if (on_border) {
 						if (on_border) {
-							valid_positions[vpc] = Point2(i, j);
+							valid_positions.write[vpc] = Point2(i, j);
 
 
 							if (emode == EMISSION_MODE_BORDER_DIRECTED) {
 							if (emode == EMISSION_MODE_BORDER_DIRECTED) {
 								Vector2 normal;
 								Vector2 normal;
@@ -206,14 +206,14 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
 								}
 								}
 
 
 								normal.normalize();
 								normal.normalize();
-								valid_normals[vpc] = normal;
+								valid_normals.write[vpc] = normal;
 							}
 							}
 
 
 							if (capture_colors) {
 							if (capture_colors) {
-								valid_colors[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
-								valid_colors[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
-								valid_colors[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
-								valid_colors[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
+								valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
+								valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
+								valid_colors.write[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
+								valid_colors.write[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
 							}
 							}
 
 
 							vpc++;
 							vpc++;

+ 6 - 6
editor/plugins/script_editor_plugin.cpp

@@ -342,11 +342,11 @@ void ScriptEditor::_save_history() {
 
 
 		if (Object::cast_to<ScriptEditorBase>(n)) {
 		if (Object::cast_to<ScriptEditorBase>(n)) {
 
 
-			history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+			history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
 		}
 		}
 		if (Object::cast_to<EditorHelp>(n)) {
 		if (Object::cast_to<EditorHelp>(n)) {
 
 
-			history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+			history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
 		}
 		}
 	}
 	}
 
 
@@ -373,11 +373,11 @@ void ScriptEditor::_go_to_tab(int p_idx) {
 
 
 		if (Object::cast_to<ScriptEditorBase>(n)) {
 		if (Object::cast_to<ScriptEditorBase>(n)) {
 
 
-			history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+			history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
 		}
 		}
 		if (Object::cast_to<EditorHelp>(n)) {
 		if (Object::cast_to<EditorHelp>(n)) {
 
 
-			history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+			history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
 		}
 		}
 	}
 	}
 
 
@@ -2612,11 +2612,11 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
 
 
 	if (Object::cast_to<ScriptEditorBase>(n)) {
 	if (Object::cast_to<ScriptEditorBase>(n)) {
 
 
-		history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+		history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
 	}
 	}
 	if (Object::cast_to<EditorHelp>(n)) {
 	if (Object::cast_to<EditorHelp>(n)) {
 
 
-		history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+		history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
 	}
 	}
 
 
 	history_pos = p_new_pos;
 	history_pos = p_new_pos;

+ 3 - 3
editor/plugins/skeleton_editor_plugin.cpp

@@ -68,16 +68,16 @@ void SkeletonEditor::create_physical_skeleton() {
 
 
 		if (parent < 0) {
 		if (parent < 0) {
 
 
-			bones_infos[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
+			bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
 
 
 		} else {
 		} else {
 
 
-			bones_infos[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
+			bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
 
 
 			/// create physical bone on parent
 			/// create physical bone on parent
 			if (!bones_infos[parent].physical_bone) {
 			if (!bones_infos[parent].physical_bone) {
 
 
-				bones_infos[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
+				bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
 
 
 				ur->create_action(TTR("Create physical bones"));
 				ur->create_action(TTR("Create physical bones"));
 				ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
 				ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);

+ 9 - 9
editor/plugins/spatial_editor_plugin.cpp

@@ -5009,7 +5009,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_SELECT]->set_flat(true);
 	tool_button[TOOL_MODE_SELECT]->set_flat(true);
 	tool_button[TOOL_MODE_SELECT]->set_pressed(true);
 	tool_button[TOOL_MODE_SELECT]->set_pressed(true);
-	button_binds[0] = MENU_TOOL_SELECT;
+	button_binds.write[0] = MENU_TOOL_SELECT;
 	tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
 	tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
 
 
@@ -5017,7 +5017,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
 	hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
 	tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_MOVE]->set_flat(true);
 	tool_button[TOOL_MODE_MOVE]->set_flat(true);
-	button_binds[0] = MENU_TOOL_MOVE;
+	button_binds.write[0] = MENU_TOOL_MOVE;
 	tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
 	tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
 
 
@@ -5025,7 +5025,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
 	hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
 	tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_ROTATE]->set_flat(true);
 	tool_button[TOOL_MODE_ROTATE]->set_flat(true);
-	button_binds[0] = MENU_TOOL_ROTATE;
+	button_binds.write[0] = MENU_TOOL_ROTATE;
 	tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
 	tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
 
 
@@ -5033,7 +5033,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
 	hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
 	tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_SCALE]->set_flat(true);
 	tool_button[TOOL_MODE_SCALE]->set_flat(true);
-	button_binds[0] = MENU_TOOL_SCALE;
+	button_binds.write[0] = MENU_TOOL_SCALE;
 	tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
 	tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
 
 
@@ -5041,19 +5041,19 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
 	hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
 	tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
 	tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true);
 	tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true);
-	button_binds[0] = MENU_TOOL_LIST_SELECT;
+	button_binds.write[0] = MENU_TOOL_LIST_SELECT;
 	tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
 	tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
 
 
 	tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton);
 	tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton);
 	hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
 	hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
-	button_binds[0] = MENU_LOCK_SELECTED;
+	button_binds.write[0] = MENU_LOCK_SELECTED;
 	tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
 	tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
 
 
 	tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton);
 	tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton);
 	hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
 	hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
-	button_binds[0] = MENU_UNLOCK_SELECTED;
+	button_binds.write[0] = MENU_UNLOCK_SELECTED;
 	tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
 	tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
 
 
@@ -5064,7 +5064,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
 	hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
 	tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true);
 	tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true);
 	tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
 	tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
-	button_binds[0] = MENU_TOOL_LOCAL_COORDS;
+	button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
 	tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
 	tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
 	ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
 	ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
 	sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
 	sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
@@ -5074,7 +5074,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
 	hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
 	tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true);
 	tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true);
 	tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
 	tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
-	button_binds[0] = MENU_TOOL_USE_SNAP;
+	button_binds.write[0] = MENU_TOOL_USE_SNAP;
 	tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
 	tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
 	ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
 	ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
 	sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
 	sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();

+ 1 - 1
editor/plugins/sprite_editor_plugin.cpp

@@ -169,7 +169,7 @@ void SpriteEditor::_update_mesh_data() {
 
 
 	Size2 img_size = Vector2(image->get_width(), image->get_height());
 	Size2 img_size = Vector2(image->get_width(), image->get_height());
 	for (int j = 0; j < lines.size(); j++) {
 	for (int j = 0; j < lines.size(); j++) {
-		lines[j] = expand(lines[j], rect, epsilon);
+		lines.write[j] = expand(lines[j], rect, epsilon);
 
 
 		int index_ofs = computed_vertices.size();
 		int index_ofs = computed_vertices.size();
 
 

+ 6 - 6
editor/plugins/tile_map_editor_plugin.cpp

@@ -196,7 +196,7 @@ Vector<int> TileMapEditor::get_selected_tiles() const {
 	}
 	}
 
 
 	for (int i = items.size() - 1; i >= 0; i--) {
 	for (int i = items.size() - 1; i >= 0; i--) {
-		items[i] = palette->get_item_metadata(items[i]);
+		items.write[i] = palette->get_item_metadata(items[i]);
 	}
 	}
 	return items;
 	return items;
 }
 }
@@ -983,7 +983,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 						ids.push_back(0);
 						ids.push_back(0);
 						for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
 						for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
 
 
-							ids[0] = E->get().cell;
+							ids.write[0] = E->get().cell;
 							_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
 							_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
 						}
 						}
 						_finish_undo();
 						_finish_undo();
@@ -1006,7 +1006,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 						}
 						}
 						for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
 						for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
 
 
-							ids[0] = E->get().cell;
+							ids.write[0] = E->get().cell;
 							_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
 							_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
 						}
 						}
 						_finish_undo();
 						_finish_undo();
@@ -1228,7 +1228,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 				for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
 				for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
 
 
-					tmp_cell[0] = E->get().idx;
+					tmp_cell.write[0] = E->get().idx;
 					_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
 					_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
 				}
 				}
 			}
 			}
@@ -1265,7 +1265,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 					for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
 					for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
 
 
-						tmp_cell[0] = E->get().idx;
+						tmp_cell.write[0] = E->get().idx;
 						_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
 						_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
 					}
 					}
 				}
 				}
@@ -1750,7 +1750,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
 	bucket_cache_visited = 0;
 	bucket_cache_visited = 0;
 
 
 	invalid_cell.resize(1);
 	invalid_cell.resize(1);
-	invalid_cell[0] = TileMap::INVALID_CELL;
+	invalid_cell.write[0] = TileMap::INVALID_CELL;
 
 
 	ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE);
 	ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE);
 	ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F);
 	ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F);

+ 1 - 1
editor/plugins/visual_shader_editor_plugin.cpp

@@ -190,7 +190,7 @@ void VisualShaderEditor::_update_graph() {
 		}
 		}
 
 
 		for (int i = 0; i < plugins.size(); i++) {
 		for (int i = 0; i < plugins.size(); i++) {
-			custom_editor = plugins[i]->create_editor(vsnode);
+			custom_editor = plugins.write[i]->create_editor(vsnode);
 			if (custom_editor) {
 			if (custom_editor) {
 				break;
 				break;
 			}
 			}

+ 2 - 2
editor/project_manager.cpp

@@ -1781,8 +1781,8 @@ ProjectManager::ProjectManager() {
 	vb->add_constant_override("separation", 15 * EDSCALE);
 	vb->add_constant_override("separation", 15 * EDSCALE);
 
 
 	String cp;
 	String cp;
-	cp.push_back(0xA9);
-	cp.push_back(0);
+	cp += 0xA9;
+	cp += '0';
 	OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2018 Juan Linietsky, Ariel Manzur & Godot Contributors");
 	OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2018 Juan Linietsky, Ariel Manzur & Godot Contributors");
 
 
 	HBoxContainer *top_hb = memnew(HBoxContainer);
 	HBoxContainer *top_hb = memnew(HBoxContainer);

+ 2 - 2
editor/project_settings_editor.cpp

@@ -1462,7 +1462,7 @@ void ProjectSettingsEditor::_update_translations() {
 			t->set_editable(0, true);
 			t->set_editable(0, true);
 			t->set_tooltip(0, l);
 			t->set_tooltip(0, l);
 			t->set_checked(0, l_filter.has(l));
 			t->set_checked(0, l_filter.has(l));
-			translation_filter_treeitems[i] = t;
+			translation_filter_treeitems.write[i] = t;
 		}
 		}
 	} else {
 	} else {
 		for (int i = 0; i < s; i++) {
 		for (int i = 0; i < s; i++) {
@@ -1502,7 +1502,7 @@ void ProjectSettingsEditor::_update_translations() {
 					if (langnames.length() > 0)
 					if (langnames.length() > 0)
 						langnames += ",";
 						langnames += ",";
 					langnames += names[i];
 					langnames += names[i];
-					translation_locales_idxs_remap[l_idx] = i;
+					translation_locales_idxs_remap.write[l_idx] = i;
 					l_idx++;
 					l_idx++;
 				}
 				}
 			}
 			}

+ 1 - 1
editor/property_editor.cpp

@@ -90,7 +90,7 @@ bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) co
 	return false;
 	return false;
 }
 }
 
 
-Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) {
+Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const {
 
 
 	if (get_script_instance())
 	if (get_script_instance())
 		return get_script_instance()->call("_convert", p_resource);
 		return get_script_instance()->call("_convert", p_resource);

+ 1 - 1
editor/property_editor.h

@@ -64,7 +64,7 @@ protected:
 public:
 public:
 	virtual String converts_to() const;
 	virtual String converts_to() const;
 	virtual bool handles(const Ref<Resource> &p_resource) const;
 	virtual bool handles(const Ref<Resource> &p_resource) const;
-	virtual Ref<Resource> convert(const Ref<Resource> &p_resource);
+	virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
 };
 };
 
 
 class CustomPropertyEditor : public Popup {
 class CustomPropertyEditor : public Popup {

+ 1 - 1
editor/quick_open.cpp

@@ -195,7 +195,7 @@ Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<Strin
 	Vector<float> scores;
 	Vector<float> scores;
 	scores.resize(list.size());
 	scores.resize(list.size());
 	for (int i = 0; i < list.size(); i++)
 	for (int i = 0; i < list.size(); i++)
-		scores[i] = _path_cmp(search_text, list[i].first);
+		scores.write[i] = _path_cmp(search_text, list[i].first);
 
 
 	while (list.size() > 0) {
 	while (list.size() > 0) {
 
 

+ 6 - 6
editor/script_editor_debugger.cpp

@@ -658,7 +658,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
 		Vector<float> p;
 		Vector<float> p;
 		p.resize(arr.size());
 		p.resize(arr.size());
 		for (int i = 0; i < arr.size(); i++) {
 		for (int i = 0; i < arr.size(); i++) {
-			p[i] = arr[i];
+			p.write[i] = arr[i];
 			if (i < perf_items.size()) {
 			if (i < perf_items.size()) {
 
 
 				float v = p[i];
 				float v = p[i];
@@ -693,7 +693,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
 				perf_items[i]->set_text(1, vs);
 				perf_items[i]->set_text(1, vs);
 				perf_items[i]->set_tooltip(1, tt);
 				perf_items[i]->set_tooltip(1, tt);
 				if (p[i] > perf_max[i])
 				if (p[i] > perf_max[i])
-					perf_max[i] = p[i];
+					perf_max.write[i] = p[i];
 			}
 			}
 		}
 		}
 		perf_history.push_front(p);
 		perf_history.push_front(p);
@@ -807,7 +807,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
 				item.signature = "categ::" + name + "::" + item.name;
 				item.signature = "categ::" + name + "::" + item.name;
 				item.name = item.name.capitalize();
 				item.name = item.name.capitalize();
 				c.total_time += item.total;
 				c.total_time += item.total;
-				c.items[i / 2] = item;
+				c.items.write[i / 2] = item;
 			}
 			}
 			metric.categories.push_back(c);
 			metric.categories.push_back(c);
 		}
 		}
@@ -844,7 +844,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
 			item.calls = calls;
 			item.calls = calls;
 			item.self = self;
 			item.self = self;
 			item.total = total;
 			item.total = total;
-			funcs.items[i] = item;
+			funcs.items.write[i] = item;
 		}
 		}
 
 
 		metric.categories.push_back(funcs);
 		metric.categories.push_back(funcs);
@@ -1193,7 +1193,7 @@ void ScriptEditorDebugger::start() {
 	perf_history.clear();
 	perf_history.clear();
 	for (int i = 0; i < Performance::MONITOR_MAX; i++) {
 	for (int i = 0; i < Performance::MONITOR_MAX; i++) {
 
 
-		perf_max[i] = 0;
+		perf_max.write[i] = 0;
 	}
 	}
 
 
 	int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
 	int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
@@ -2076,7 +2076,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
 			it->set_selectable(1, false);
 			it->set_selectable(1, false);
 			it->set_text(0, name.capitalize());
 			it->set_text(0, name.capitalize());
 			perf_items.push_back(it);
 			perf_items.push_back(it);
-			perf_max[i] = 0;
+			perf_max.write[i] = 0;
 		}
 		}
 	}
 	}
 
 

+ 22 - 22
editor/spatial_editor_gizmos.cpp

@@ -229,7 +229,7 @@ void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines)
 	collision_segments.resize(from + p_lines.size());
 	collision_segments.resize(from + p_lines.size());
 	for (int i = 0; i < p_lines.size(); i++) {
 	for (int i = 0; i < p_lines.size(); i++) {
 
 
-		collision_segments[from + i] = p_lines[i];
+		collision_segments.write[from + i] = p_lines[i];
 	}
 	}
 }
 }
 
 
@@ -296,14 +296,14 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
 		int chs = handles.size();
 		int chs = handles.size();
 		handles.resize(chs + p_handles.size());
 		handles.resize(chs + p_handles.size());
 		for (int i = 0; i < p_handles.size(); i++) {
 		for (int i = 0; i < p_handles.size(); i++) {
-			handles[i + chs] = p_handles[i];
+			handles.write[i + chs] = p_handles[i];
 		}
 		}
 	} else {
 	} else {
 
 
 		int chs = secondary_handles.size();
 		int chs = secondary_handles.size();
 		secondary_handles.resize(chs + p_handles.size());
 		secondary_handles.resize(chs + p_handles.size());
 		for (int i = 0; i < p_handles.size(); i++) {
 		for (int i = 0; i < p_handles.size(); i++) {
-			secondary_handles[i + chs] = p_handles[i];
+			secondary_handles.write[i + chs] = p_handles[i];
 		}
 		}
 	}
 	}
 }
 }
@@ -597,7 +597,7 @@ void EditorSpatialGizmo::create() {
 
 
 	for (int i = 0; i < instances.size(); i++) {
 	for (int i = 0; i < instances.size(); i++) {
 
 
-		instances[i].create_instance(spatial_node);
+		instances.write[i].create_instance(spatial_node);
 	}
 	}
 
 
 	transform();
 	transform();
@@ -621,7 +621,7 @@ void EditorSpatialGizmo::free() {
 
 
 		if (instances[i].instance.is_valid())
 		if (instances[i].instance.is_valid())
 			VS::get_singleton()->free(instances[i].instance);
 			VS::get_singleton()->free(instances[i].instance);
-		instances[i].instance = RID();
+		instances.write[i].instance = RID();
 	}
 	}
 
 
 	valid = false;
 	valid = false;
@@ -1124,8 +1124,8 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() {
 			Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
 			Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
 			Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
 			Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
 
 
-			points[i * 2 + 0] = from;
-			points[i * 2 + 1] = to;
+			points.write[i * 2 + 0] = from;
+			points.write[i * 2 + 1] = to;
 		}
 		}
 
 
 		for (int i = 0; i < 4; i++) {
 		for (int i = 0; i < 4; i++) {
@@ -1134,8 +1134,8 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() {
 
 
 			Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
 			Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
 
 
-			points[200 + i * 2 + 0] = from;
-			points[200 + i * 2 + 1] = Vector3();
+			points.write[200 + i * 2 + 0] = from;
+			points.write[200 + i * 2 + 1] = Vector3();
 		}
 		}
 
 
 		add_lines(points, material);
 		add_lines(points, material);
@@ -1441,11 +1441,11 @@ void SkeletonSpatialGizmo::redraw() {
 	weights.resize(4);
 	weights.resize(4);
 
 
 	for (int i = 0; i < 4; i++) {
 	for (int i = 0; i < 4; i++) {
-		bones[i] = 0;
-		weights[i] = 0;
+		bones.write[i] = 0;
+		weights.write[i] = 0;
 	}
 	}
 
 
-	weights[0] = 1;
+	weights.write[0] = 1;
 
 
 	AABB aabb;
 	AABB aabb;
 
 
@@ -1457,7 +1457,7 @@ void SkeletonSpatialGizmo::redraw() {
 		int parent = skel->get_bone_parent(i);
 		int parent = skel->get_bone_parent(i);
 
 
 		if (parent >= 0) {
 		if (parent >= 0) {
-			grests[i] = grests[parent] * skel->get_bone_rest(i);
+			grests.write[i] = grests[parent] * skel->get_bone_rest(i);
 
 
 			Vector3 v0 = grests[parent].origin;
 			Vector3 v0 = grests[parent].origin;
 			Vector3 v1 = grests[i].origin;
 			Vector3 v1 = grests[i].origin;
@@ -1480,7 +1480,7 @@ void SkeletonSpatialGizmo::redraw() {
 			int pointidx = 0;
 			int pointidx = 0;
 			for (int j = 0; j < 3; j++) {
 			for (int j = 0; j < 3; j++) {
 
 
-				bones[0] = parent;
+				bones.write[0] = parent;
 				surface_tool->add_bones(bones);
 				surface_tool->add_bones(bones);
 				surface_tool->add_weights(weights);
 				surface_tool->add_weights(weights);
 				surface_tool->add_color(rootcolor);
 				surface_tool->add_color(rootcolor);
@@ -1508,7 +1508,7 @@ void SkeletonSpatialGizmo::redraw() {
 					Vector3 point = v0 + d * dist * 0.2;
 					Vector3 point = v0 + d * dist * 0.2;
 					point += axis * dist * 0.1;
 					point += axis * dist * 0.1;
 
 
-					bones[0] = parent;
+					bones.write[0] = parent;
 					surface_tool->add_bones(bones);
 					surface_tool->add_bones(bones);
 					surface_tool->add_weights(weights);
 					surface_tool->add_weights(weights);
 					surface_tool->add_color(bonecolor);
 					surface_tool->add_color(bonecolor);
@@ -1518,12 +1518,12 @@ void SkeletonSpatialGizmo::redraw() {
 					surface_tool->add_color(bonecolor);
 					surface_tool->add_color(bonecolor);
 					surface_tool->add_vertex(point);
 					surface_tool->add_vertex(point);
 
 
-					bones[0] = parent;
+					bones.write[0] = parent;
 					surface_tool->add_bones(bones);
 					surface_tool->add_bones(bones);
 					surface_tool->add_weights(weights);
 					surface_tool->add_weights(weights);
 					surface_tool->add_color(bonecolor);
 					surface_tool->add_color(bonecolor);
 					surface_tool->add_vertex(point);
 					surface_tool->add_vertex(point);
-					bones[0] = i;
+					bones.write[0] = i;
 					surface_tool->add_bones(bones);
 					surface_tool->add_bones(bones);
 					surface_tool->add_weights(weights);
 					surface_tool->add_weights(weights);
 					surface_tool->add_color(bonecolor);
 					surface_tool->add_color(bonecolor);
@@ -1535,7 +1535,7 @@ void SkeletonSpatialGizmo::redraw() {
 			SWAP(points[1], points[2]);
 			SWAP(points[1], points[2]);
 			for (int j = 0; j < 4; j++) {
 			for (int j = 0; j < 4; j++) {
 
 
-				bones[0] = parent;
+				bones.write[0] = parent;
 				surface_tool->add_bones(bones);
 				surface_tool->add_bones(bones);
 				surface_tool->add_weights(weights);
 				surface_tool->add_weights(weights);
 				surface_tool->add_color(bonecolor);
 				surface_tool->add_color(bonecolor);
@@ -1560,8 +1560,8 @@ void SkeletonSpatialGizmo::redraw() {
 */
 */
 		} else {
 		} else {
 
 
-			grests[i] = skel->get_bone_rest(i);
-			bones[0] = i;
+			grests.write[i] = skel->get_bone_rest(i);
+			bones.write[0] = i;
 		}
 		}
 		/*
 		/*
 		Transform  t = grests[i];
 		Transform  t = grests[i];
@@ -2542,8 +2542,8 @@ void CollisionShapeSpatialGizmo::redraw() {
 				Vector<Vector3> points;
 				Vector<Vector3> points;
 				points.resize(md.edges.size() * 2);
 				points.resize(md.edges.size() * 2);
 				for (int i = 0; i < md.edges.size(); i++) {
 				for (int i = 0; i < md.edges.size(); i++) {
-					points[i * 2 + 0] = md.vertices[md.edges[i].a];
-					points[i * 2 + 1] = md.vertices[md.edges[i].b];
+					points.write[i * 2 + 0] = md.vertices[md.edges[i].a];
+					points.write[i * 2 + 1] = md.vertices[md.edges[i].b];
 				}
 				}
 
 
 				add_lines(points, material);
 				add_lines(points, material);

部分文件因文件數量過多而無法顯示